stack and queue
stack and queue
4
Stack and Queue
There are certain situations in computer science that one wants to
restrict insertions and deletions so that they can take place only at the
beginning or the end of the list, not in the middle. Two of such data
structures that are useful are:
• Stack.
• Queue.
Linear lists and arrays allow one to insert and delete elements at any
place in the list i.e., at the beginning, at the end or in the middle.
4.1. STACK:
A stack is a list of elements in which an element may be inserted or deleted only at one
end, called the top of the stack. Stacks are sometimes known as LIFO (last in, first out)
lists.
As the items can be added or removed only from the top i.e. the last item to be added
to a stack is the first item to be removed.
“Push” is the term used to insert an element into a stack. “Pop” is the term used to
delete an element from the stack.
All insertions and deletions take place at the same end, so the last element added to
the stack will be the first element removed from the stack. When a stack is created, the
stack base remains fixed while the stack top changes as elements are added and
removed. The most accessible element is the top and the least accessible element is
the bottom of the stack.
Let us consider a stack with 6 elements capacity. This is called as the size of the stack.
The number of elements to be added should not exceed the maximum size of the stack.
If we attempt to add new element beyond the maximum size, we will encounter a stack
overflow condition. Similarly, you cannot remove elements beyond the base of the
stack. If such is the case, we will reach a stack underflow condition.
When an element is added to a stack, the operation is performed by push(). Figure 4.1
shows the creation of a stack and addition of elements using push().
3 3 3 3
TOP
2 2 2 33 2
TOP
22 22
1 TOP 1 1 1
11 11 11
TOP 0 0 0 0
Empty Insert Insert Insert
Stack 11 22 33
When an element is taken off from the stack, the operation is performed by pop().
Figure 4.2 shows a stack initially with three elements and shows the deletion of
elements using pop().
4 4 4 4
TOP 3 3 3 3
33 2 2 2 2
TOP
22 22
1 1 TOP 1 1
11 11 11 TOP
0 0 0 0
Initial POP POP POP
Stack
Empty
Stack
Figure 4.2. Pop operations on stack
# include <stdio.h>
# include <conio.h>
# include <stdlib.h>
# define MAX 6
int stack[MAX];
int top = 0;
int menu()
{
int ch;
clrscr();
printf("\n … Stack operations using ARRAY... ");
printf("\n -----------**********-------------\n");
printf("\n 1. Push ");
printf("\n 2. Pop ");
printf("\n 3. Display");
printf("\n 4. Quit ");
printf("\n Enter your choice: ");
scanf("%d", &ch);
return ch;
}
void display()
{
int i;
if(top == 0)
{
printf("\n\nStack empty..");
void pop()
{
if(top == 0)
{
printf("\n\nStack Underflow..");
return;
}
else
printf("\n\npopped element is: %d ", stack[--top]);
}
void push()
{
int data;
if(top == MAX)
{
printf("\n\nStack Overflow..");
return;
}
else
{
printf("\n\nEnter data: ");
scanf("%d", &data);
stack[top] = data;
top = top + 1;
printf("\n\nData Pushed into the stack");
}
}
void main()
{
int ch;
do
{
ch = menu();
switch(ch)
{
case 1:
push();
break;
case 2:
pop();
break;
case 3:
display();
break;
case 4:
exit(0);
}
getch();
} while(1);
}
We can represent a stack as a linked list. In a stack push and pop operations are
performed at one end called top. We can perform similar operations at one end of list
using top pointer. The linked stack looks as shown in figure 4.3.
top
400
data next
40 X
400
30 400
300
20 300
200
start
100 10 200
100
# include <stdio.h>
# include <conio.h>
# include <stdlib.h>
struct stack
{
int data;
struct stack *next;
};
void push();
void pop();
void display();
typedef struct stack node;
node *start=NULL;
node *top = NULL;
node* getnode()
{
node *temp;
temp=(node *) malloc( sizeof(node)) ;
printf("\n Enter data ");
scanf("%d", &temp -> data);
temp -> next = NULL;
return temp;
}
void push(node *newnode)
{
node *temp;
if( newnode == NULL )
{
printf("\n Stack Overflow..");
return;
}
void main()
{
char ch;
node *newnode;
do
{
ch = menu();
switch(ch)
{
case '1' :
newnode = getnode();
push(newnode);
break;
case '2' :
pop();
break;
case '3' :
display();
break;
case '4':
return;
}
getch();
} while( ch != '4' );
}
An algebraic expression can be represented using three different notations. They are
infix, postfix and prefix notations:
Example: (A + B) * (C - D)
Prefix: It is the form of an arithmetic notation in which we fix (place) the arithmetic
operator before (pre) its two operands. The prefix notation is called as
Example: * + A B – C D
Example: A B + C D - *
1. The operands maintain the same order as in the equivalent infix expression.
Exponentiation ($ or ↑ or ^) Highest 3
*, / Next highest 2
+, - Lowest 1
Let us convert the expressions from one type to another. These can be done as follows:
1. Infix to postfix
2. Infix to prefix
3. Postfix to infix
4. Postfix to prefix
5. Prefix to infix
6. Prefix to postfix
Example 1:
Example 2:
a a
+ a +
b ab +
c abc +*
+ abc*+ +
( abc*+ +(
d abc*+d +(
* abc*+d +(*
e abc*+de +(*
+ abc*+de* +(+
f abc*+de*f +(+
) abc*+de*f+ +
* abc*+de*f+ +*
g abc*+de*f+g +*
End of The input is now empty. Pop the output symbols
abc*+de*f+g*+
string from the stack until it is empty.
Example 3:
Example 4:
# include <string.h>
char postfix[50];
char infix[50];
char opstack[50]; /* operator stack */
int i, j, top = 0;
pop()
{
while(opstack[--top] != '(' ) /* pop until '(' comes */
{
postfix[j] = opstack[top];
j++;
}
}
void main()
{
char ch;
clrscr();
printf("\n Enter Infix Expression : ");
gets(infix);
while( (ch=infix[i++]) != ‘\0’)
{
switch(ch)
{
case ' ' : break;
case '(' :
case '+' :
case '-' :
case '*' :
case '/' :
case '^' :
case '%' :
push(ch); /* check priority and push */
break;
case ')' :
pop();
break;
default :
postfix[j] = ch;
j++;
}
}
while(top >= 0)
{
postfix[j] = opstack[--top];
j++;
The precedence rules for converting an expression from infix to prefix are identical. The
only change from postfix conversion is that traverse the expression from right to left
and the operator is placed before the operands rather than after them. The prefix form
of a complex expression is not the mirror image of the postfix form.
Example 1:
PREFIX
SYMBOL STACK REMARKS
STRING
C C
- C -
B BC -
+ BC -+
A ABC -+
End of -+ABC The input is now empty. Pop the output symbols from the
string stack until it is empty.
Example 2:
PREFIX
SYMBOL STACK REMARKS
STRING
) )
D D )
- D )-
C CD )-
( -CD
* -CD *
) -CD *)
B B-CD *)
+ B-CD *)+
A AB-CD *)+
( +AB–CD *
End of *+AB–CD The input is now empty. Pop the output symbols from the
string stack until it is empty.
) )
H H )
+ H )+
G GH )+
( +GH
/ +GH /
F F+GH /
/ F+GH //
E EF+GH //
+ //EF+GH +
D D//EF+GH +
- D//EF+GH +-
C CD//EF+GH +-
* CD//EF+GH +-*
B BCD//EF+GH +-*
↑ BCD//EF+GH +-*↑
A ABCD//EF+GH +-*↑
End of The input is now empty. Pop the output
+-*↑ABCD//EF+GH
string symbols from the stack until it is empty.
# include <conio.h>
# include <string.h>
char prefix[50];
char infix[50];
char opstack[50]; /* operator stack */
int j, top = 0;
void pop()
{
while(opstack[--top] != ')') /* pop until ')' comes; */
insert_beg(opstack[top]);
}
void main()
{
char ch;
int l, i = 0;
clrscr();
printf("\n Enter Infix Expression : ");
3. If the scanned symbol is an operator, pop two symbols from the stack
and create it as a string by placing the operator in between the operands
and push it onto the stack.
Example:
A A Push A
B A B Push B
C A B C Push C
D A (B*C) D Push D
E A (B*C) D E Push E
F A (B*C) D E F Push F
End of
The input is now empty. The string formed is infix.
string
# include <stdio.h>
# include <conio.h>
# include <string.h>
# define MAX 100
3. If the scanned symbol is an operator, pop two symbols from the stack
and create it as a string by placing the operator in front of the operands
and push it onto the stack.
Example:
A A Push A
B A B Push B
C A B C Push C
D A *BC D Push D
E A *BC D E Push E
F A *BC D E F Push F
H A - *BC*/D^EFG H Push H
+ +A*-*BC*/D^EFGH
End of
The input is now empty. The string formed is prefix.
string
# include <conio.h>
# include <string.h>
main()
{
char s[MAX], str1[MAX], str2[MAX], str[MAX];
char s1[2], temp[2];
int i = 0;
clrscr();
printf("Enter the postfix expression; ");
gets (s);
while(s[i]!='\0')
{
/*skip whitespace, if any */
if (s[i] == ' ')
i++;
if(s[i] == '^' || s[i] == '*' || s[i] == '-' || s[i]== '+' || s[i] == '/')
{
pop (str1);
pop (str2);
temp[0] = s[i];
temp[1] = '\0';
strcpy (str, temp);
strcat(str, str2);
strcat(str, str1);
push(str);
}
else
{
temp[0] = s[i];
temp[1] = '\0';
strcpy (s1, temp);
push (s1);
}
i++;
}
printf("\n The prefix expression is: %s", stack[0]);
}
void pop(char*a1)
{
if(top == -1)
{
printf("\nStack is empty");
return ;
}
else
{
strcpy (a1, stack[top]);
top--;
}
}
Example:
H H Push H
G H G Push G
F H G F Push F
E H G F E Push E
Pop two operands and place the operator
^ H G (E^F) in between the operands and push the
string.
D H G (E^F) D Push D
Pop two operands and place the operator
/ H G (D/(E^F)) in between the operands and push the
string.
Pop two operands and place the operator
* H ((D/(E^F))*G) in between the operands and push the
string.
C H ((D/(E^F))*G) C Push C
B H ((D/(E^F))*G) C B Push B
Pop two operands and place the operator
* H ((D/(E^F))*G) (B*C) in front the operands and push the
string.
Pop two operands and place the operator
- H ((B*C)-((D/(E^F))*G))
in front the operands and push the
# include <string.h>
# define MAX 100
void main()
{
char s[MAX], str1[MAX], str2[MAX], str[MAX];
char s1[2],temp[2];
int i=0;
clrscr( ) ;
printf("\Enter the prefix expression; ");
gets(s);
strrev(s);
while (s[i]!='\0')
{
/*skip whitespace, if any*/
if(s[i] == ' ' )
i++;
if (s[i] == '^' || s[i] == '*'|| s[i] == '-' || s[i] == '+' || s[i] == '/')
{
pop(str1);
pop(str2);
temp[0] ='(';
temp[1] ='\0';
strcpy(str, temp);
strcat(str, str1);
temp[0] = s[i];
temp[1] = '\0';
strcat(str,temp);
strcat(str, str2);
temp[0] =')';
temp[1] ='\0';
strcat(str,temp);
push(str);
}
else
{
temp[0]=s[i];
temp[1]='\0';
strcpy(s1, temp);
push(s1);
3. If the scanned symbol is an operator, pop two symbols from the stack
and create it as a string by placing the operator after the operands and
push it onto the stack.
Example:
H H Push H
G H G Push G
F H G F Push F
E H G F E Push E
D H G EF^ D Push D
C H DEF^/G* C Push C
B H DEF^/G* C B Push B
A BC*DEF^/G*-H* A Push A
# include <stdio.h>
# include <conio.h>
# include <string.h>
void main()
{
char s[MAX], str1[MAX], str2[MAX], str[MAX];
char s1[2], temp[2];
int i = 0;
clrscr();
printf("Enter the prefix expression; ");
gets (s);
strrev(s);
while(s[i]!='\0')
{
if (s[i] == ' ') /*skip whitespace, if any */
i++;
if(s[i] == '^' || s[i] == '*' || s[i] == '-' || s[i]== '+' || s[i] == '/')
{
pop (str1);
pop (str2);
temp[0] = s[i];
temp[1] = '\0';
strcat(str1,str2);
strcat (str1, temp);
strcpy(str, str1);
push(str);
}
The postfix expression is evaluated easily by the use of a stack. When a number is
seen, it is pushed onto the stack; when an operator is seen, the operator is applied to
the two numbers that are popped from the stack and the result is pushed onto the
stack. When an expression is given in postfix notation, there is no need to know any
precedence rules; this is our obvious advantage.
Example 1:
OPERAND
SYMBOL OPERAND 2 VALUE STACK REMARKS
1
6 6
5 6, 5
2 6, 5, 2
The first four symbols are placed on
3 6, 5, 2, 3
the stack.
Next a ‘+’ is read, so 3 and 2 are
+ 2 3 5 6, 5, 5 popped from the stack and their
sum 5, is pushed
Example 2:
6 6
2 6, 2
3 6, 2, 3
+ 2 3 5 6, 5
- 6 5 1 1
3 6 5 1 1, 3
8 6 5 1 1, 3, 8
2 6 5 1 1, 3, 8, 2
/ 8 2 4 1, 3, 4
+ 3 4 7 1, 7
* 1 7 7 7
2 1 7 7 7, 2
↑ 7 2 49 49
3 7 2 49 49, 3
+ 49 3 52 52
# include <conio.h>
# include <math.h>
# define MAX 20
4. In recursion, all intermediate arguments and return values are stored on the
processor’s stack.
5. During a function call the return address and arguments are pushed onto a
stack and on return they are popped off.
A queue is another special kind of list, where items are inserted at one end called the
rear and deleted at the other end called the front. Another name for a queue is a
“FIFO” or “First-in-first-out” list.
The operations for a queue are analogues to those for a stack, the difference is that the
insertions go at the end of the list, rather than the beginning. We shall use the
following operations on queues:
Let us consider a queue, which can hold maximum of five elements. Initially the queue
is empty.
0 1 2 3 4
Q u e u e E mp t y
F RO NT = RE A R = 0
F R
0 1 2 3 4
RE A R = RE A R + 1 = 1
11
F RO NT = 0
F R
0 1 2 3 4
RE A R = RE A R + 1 = 2
11 22
F RO NT = 0
F R
Again insert another element 33 to the queue. The status of the queue is:
0 1 2 3 4
RE A R = RE A R + 1 = 3
11 22 33
F RO NT = 0
F R
0 1 2 3 4
RE A R = 3
22 33
F RO NT = F R O NT + 1 = 1
F R
Again, delete an element. The element to be deleted is always pointed to by the FRONT
pointer. So, 22 is deleted. The queue status is as follows:
0 1 2 3 4
RE A R = 3
33
F RO NT = F R O NT + 1 = 2
F R
Now, insert new elements 44 and 55 into the queue. The queue status is:
0 1 2 3 4
RE A R = 5
33 44 55
F RO NT = 2
F R
Next insert another element, say 66 to the queue. We cannot insert 66 to the queue as
the rear crossed the maximum size of the queue (i.e., 5). There will be queue full
signal. The queue status is as follows:
0 1 2 3 4
RE A R = 5
33 44 55
F RO NT = 2
F R
Now it is not possible to insert an element 66 even though there are two vacant
positions in the linear queue. To over come this problem the elements of the queue are
to be shifted towards the beginning of the queue so that it creates vacant position at
the rear end. Then the FRONT and REAR are to be adjusted properly. The element 66
can be inserted at the rear end. After this operation, the queue status is as follows:
0 1 2 3 4
RE A R = 4
33 44 55 66
F RO NT = 0
F R
This difficulty can overcome if we treat queue position with index 0 as a position that
comes after position with index 4 i.e., we treat the queue as a circular queue.
In order to create a queue we require a one dimensional array Q(1:n) and two
variables front and rear. The conventions we shall adopt for these two variables are
that front is always 1 less than the actual front of the queue and rear always points to
the last element in the queue. Thus, front = rear if and only if there are no elements in
the queue. The initial condition then is front = rear = 0. The various queue operations
to perform creation, deletion and display the elements in a queue are as follows:
# include <conio.h>
# define MAX 6
int Q[MAX];
int front, rear;
void insertQ()
{
int data;
if(rear == MAX)
{
printf("\n Linear Queue is full");
return;
}
else
{
printf("\n Enter data: ");
scanf("%d", &data);
Q[rear] = data;
rear++;
printf("\n Data Inserted in the Queue ");
}
}
void deleteQ()
{
if(rear == front)
{
printf("\n\n Queue is Empty..");
return;
}
else
{
printf("\n Deleted element from Queue is %d", Q[front]);
front++;
}
}
void displayQ()
{
int i;
if(front == rear)
{
printf("\n\n\t Queue is Empty");
return;
}
else
{
printf("\n Elements in Queue are: ");
for(i = front; i < rear; i++)
We can represent a queue as a linked list. In a queue data is deleted from the front end
and inserted at the rear end. We can perform similar operations on the two ends of a
list. We use two pointers front and rear for our linked queue implementation.
front rear
100 400
# include <stdlib.h>
# include <conio.h>
struct queue
{
int data;
struct queue *next;
};
typedef struct queue node;
node *front = NULL;
node *rear = NULL;
node* getnode()
{
node *temp;
temp = (node *) malloc(sizeof(node)) ;
printf("\n Enter data ");
scanf("%d", &temp -> data);
temp -> next = NULL;
return temp;
}
void insertQ()
{
node *newnode;
newnode = getnode();
if(newnode == NULL)
{
printf("\n Queue Full");
return;
}
if(front == NULL)
{
front = newnode;
rear = newnode;
}
else
{
rear -> next = newnode;
rear = newnode;
}
printf("\n\n\t Data Inserted into the Queue..");
}
void deleteQ()
{
node *temp;
if(front == NULL)
{
printf("\n\n\t Empty Queue..");
return;
}
temp = front;
front = front -> next;
printf("\n\n\t Deleted element from queue is %d ", temp -> data);
free(temp);
}
char menu()
{
char ch;
clrscr();
printf("\n \t..Queue operations using pointers.. ");
printf("\n\t -----------**********-------------\n");
printf("\n 1. Insert ");
printf("\n 2. Delete ");
printf("\n 3. Display");
printf("\n 4. Quit ");
printf("\n Enter your choice: ");
ch = getche();
return ch;
}
void main()
{
char ch;
do
{
ch = menu();
switch(ch)
{
case '1' :
insertQ();
break;
case '2' :
deleteQ();
break;
case '3' :
displayQ();
break;
case '4':
return;
}
getch();
} while(ch != '4');
}
2. When multiple users send print jobs to a printer, each printing job is kept in
the printing queue. Then the printer prints those jobs according to first in
first out (FIFO) basis.
3. Breadth first search uses a queue data structure to find an element from a
graph.
There are two problems associated with linear queue. They are:
0 1 2 3 4
RE A R = 5
33 44 55
F RO NT = 2
F R
Next insert another element, say 66 to the queue. We cannot insert 66 to the queue as
the rear crossed the maximum size of the queue (i.e., 5). There will be queue full
signal. The queue status is as follows:
0 1 2 3 4
RE A R = 5
33 44 55
F RO NT = 2
F R
This difficulty can be overcome if we treat queue position with index zero as a position
that comes after position with index four then we treat the queue as a circular queue.
In circular queue if we reach the end for inserting elements to it, it is possible to insert
new elements if the slots at the beginning of the circular queue are empty.
Let us consider a circular queue, which can hold maximum (MAX) of six elements.
Initially the queue is empty.
F R
5 0
1 Queue E mp t y
4 MAX = 6
F RO NT = RE A R = 0
C O U NT = 0
3 2
C irc u l ar Q u e u e
Now, insert 11 to the circular queue. Then circular queue status will be:
5 0
R
11
1 F RO NT = 0
4 RE A R = ( RE A R + 1) % 6 = 1
C O U NT = 1
3 2
C irc u l ar Q u e u e
Insert new elements 22, 33, 44 and 55 into the circular queue. The circular queue
status is:
F
R
0
5
11
55 22 1 FRONT = 0
4
REAR = (REAR + 1) % 6 = 5
COUNT = 5
44 33
3 2
Circular Queue
0
5
F
22 1 F RO NT = (F R O NT + 1) % 6 = 1
4 55
RE A R = 5
C O U NT = C O U NT - 1 = 4
44 33
3 2
C irc u l ar Q u e u e
Again, delete an element. The element to be deleted is always pointed to by the FRONT
pointer. So, 22 is deleted. The circular queue status is as follows:
0
5
1 F RO NT = (F R O NT + 1) % 6 = 2
4 55
RE A R = 5
C O U NT = C O U NT - 1 = 3
44 33
F
3 2
C irc u l ar Q u e u e
Again, insert another element 66 to the circular queue. The status of the circular queue
is:
R
0
5
66
55 1
4 F RO NT = 2
RE A R = ( RE A R + 1) % 6 = 0
C O U NT = C O U NT + 1 = 4
44 33
3 2 F
C irc u l ar Q u e u e
0
5
66 77
55 88 1
4 F RO NT = 2, RE A R = 2
RE A R = RE A R % 6 = 2
C O U NT = 6
44 33
R
3 2
F
C irc u l ar Q u e u e
Now, if we insert an element to the circular queue, as COUNT = MAX we cannot add
the element to circular queue. So, the circular queue is full.
# include <stdio.h>
# include <conio.h>
# define MAX 6
int CQ[MAX];
int front = 0;
int rear = 0;
int count = 0;
void insertCQ()
{
int data;
if(count == MAX)
{
printf("\n Circular Queue is Full");
}
else
{
printf("\n Enter data: ");
scanf("%d", &data);
CQ[rear] = data;
rear = (rear + 1) % MAX;
count ++;
printf("\n Data Inserted in the Circular Queue ");
}
}
void deleteCQ()
{
if(count == 0)
{
printf("\n\nCircular Queue is Empty..");
}
else
{
printf("\n Deleted element from Circular Queue is %d ", CQ[front]);
front = (front + 1) % MAX;
count --;
}
}
int menu()
{
int ch;
clrscr();
printf("\n \t Circular Queue Operations using ARRAY..");
printf("\n -----------**********-------------\n");
printf("\n 1. Insert ");
printf("\n 2. Delete ");
printf("\n 3. Display");
printf("\n 4. Quit ");
printf("\n Enter Your Choice: ");
scanf("%d", &ch);
return ch;
}
void main()
{
int ch;
do
{
ch = menu();
switch(ch)
{
case 1:
insertCQ();
break;
case 2:
deleteCQ();
break;
case 3:
displayCQ();
break;
case 4:
return;
default:
printf("\n Invalid Choice ");
}
getch();
} while(1);
}
In the preceding section we saw that a queue in which we insert items at one end and
from which we remove items at the other end. In this section we examine an extension
of the queue, which provides a means to insert and remove items at both ends of the
queue. This data structure is a deque. The word deque is an acronym derived from
double-ended queue. Figure 4.5 shows the representation of a deque.
Deletion Insertion
36 16 56 62 19
Insertion Deletion
front rear
A deque provides four operations. Figure 4.6 shows the basic operations on a deque.
enqueue_front(33) enqueue_rear(44)
11 22 33 11 22 33 11 22 44
dequeue_front(33)
55 11 22 enqueue_front(55) 11 22 dequeue_rear(44) 11 22 44
An Input restricted deque is a deque, which allows insertions at one end but allows
deletions at both ends of the list.
An output restricted deque is a deque, which allows deletions at one end but allows
insertions at both ends of the list.
A priority queue is a collection of elements such that each element has been assigned a
priority and such that the order in which elements are deleted and processed comes
from the following rules:
2. two elements with same priority are processed according to the order in
which they were added to the queue.
A prototype of a priority queue is time sharing system: programs of high priority are
processed first, and programs with the same priority form a standard queue. An
efficient implementation for the Priority Queue is to use heap, which in turn can be
used for sorting purpose called heap sort.
Exercises
1. What is a linear data structure? Give two examples of linear data structures.
2. Is it possible to have two designs for the same data structure that provide the
same functionality but are implemented differently?
3. What is the difference between the logical representation of a data structure and
the physical representation?
+
(
bottom *
Now, suppose that you read and process the 11th symbol of the input. Draw the
stack for the case where the 11th symbol is:
A. A number:
B. A left parenthesis:
C. A right parenthesis:
D. A minus sign:
E. A division sign:
11. Write an algorithm to construct a fully parenthesized infix expression from its
postfix equivalent. Write a “C” function for your algorithm.
12. How can one convert a postfix expression to its prefix equivalent and vice-versa?
13. A double-ended queue (deque) is a linear list where additions and deletions can
be performed at either end. Represent a deque using an array to store the
elements of the list and write the “C” functions for additions and deletions.
14. In a circular queue represented by an array, how can one specify the number of
elements in the queue in terms of “front”, “rear” and MAX-QUEUE-SIZE? Write a
“C” function to delete the K-th element from the “front” of a circular queue.
15. Can a queue be represented by a circular linked list with only one pointer pointing
to the tail of the queue? Write “C” functions for the “add” and “delete” operations
on such a queue
16. Write a “C” function to test whether a string of opening and closing parenthesis is
well formed or not.
17. Represent N queues in a single one-dimensional array. Write functions for “add”
and “delete” operations on the ith queue
18. Represent a stack and queue in a single one-dimensional array. Write functions
for “push”, “pop” operations on the stack and “add”, “delete” functions on the
queue.
5. A queue is a data structure in which all insertions and deletions are made [ A ]
respectively at:
A. rear and front C. front and rear
B. front and front D. rear and rear
A. 4 C. 1
B. 8 D. none of the above
14. If the characters 'D', 'C', 'B', 'A' are placed in a queue (in that order), and [ D ]
then removed one at a time, in what order will they be removed?
A. ABCD C. DCAB
B. ABDC D. DCBA
16. Consider the implementation of the queue using a circular array. What [ B ]
goes wrong if we try to keep all the items at the front of a partially-filled
array (so that data[0] is always the front).
A. The constructor would require linear time.
B. The get_front function would require linear time.
C. The insert function would require linear time.
D. The is_empty function would require linear time.
17. In the linked list implementation of the queue class, where does the push [ A ]
member function place the new entry on the linked list?
A. At the head
B. At the tail
C. After all other entries that are greater than the new entry.
D. After all other entries that are smaller than the new entry.
18. In the circular array version of the queue class (with a fixed-sized array), [ ]
which operations require linear time for their worst-case behavior?
A. front C. empty
B. push D. None of these.
19. In the linked-list version of the queue class, which operations require [ ]
linear time for their worst-case behavior?
A. front C. empty
B. push D. None of these operations.
20. To implement the queue with a linked list, keeping track of a front [ B ]
pointer and a rear pointer. Which of these pointers will change during an
insertion into a NONEMPTY queue?
A. Neither changes C. Only rear_ptr changes.
B. Only front_ptr changes. D. Both change.
21. To implement the queue with a linked list, keeping track of a front [ D ]
pointer and a rear pointer. Which of these pointers will change during an
insertion into an EMPTY queue?
A. Neither changes C. Only rear_ptr changes.
B. Only front_ptr changes. D. Both change.
23. Entries in a stack are "ordered". What is the meaning of this statement? [ D ]
A. A collection of stacks can be sorted.
B. Stack entries may be compared with the '<' operation.
C. The entries must be stored in a linked list.
D. There is a first entry, a second entry, and so on.
25. The operation for removing an entry from a stack is traditionally called: [ C ]
A. delete C. pop
B. peek D. remove
26. Which of the following stack operations could result in stack underflow? [ A ]
A. is_empty C. push
B. pop D. Two or more of the above answers
34 Which among the following data structure may give overflow error, even [ A ]
though the current number of elements in it, is less than its size:
A. Simple Queue C. Stack
B. Circular Queue D. None of the above
35. Which among the following types of expressions does not require [ C ]
precedence rules for evaluation:
A. Fully parenthesized infix expression
B. Prefix expression
C. both A and B
D. none of the above