CS23231 Data Structures Unit II
CS23231 Data Structures Unit II
Unit- II
Lecture Notes
(Regulations -2023)
UNIT-II LINEAR DATA STRUCTURES – STACKS, QUEUES 9
Stack – Operations, Array and Linked list implementation, Applications –
Evaluation of Arithmetic Expressions, Queues-Operations, Array and Linked
list Implementation.
CHAPTER - 12 - STACK ADT
12.1 INTRODUCTION
A stack is a list with the restriction that insertions and deletions can be performed in only
one position, namely, the end of the list, called the top. It follows Last-In-First-Out (LIFO)
principle.
Top 50
40
30
20
10
Fig. 12.2 Stack model: only the top element is accessible
12.3 PUSH
• The process of inserting a new element to the top of the stack is called push operation.
• For every push operation the top is incremented by 1.
Top
Top 20
10 10
Top Empty Stack After After
inserting an inserting an
element 10 element 20
The process of deleting an element from the top of stack is called pop operation.
After every pop operation the top pointer is decremented by 1.
Top 30
Top
20 20 Top
10 10 10
12.5.1 Overflow
Top 50
40
30
20
10
Fig. 12.5 Full Stack (Size = 5)
12.5.2 Underflow
• Array
• Linked list
REVIEW QUESTIONS
13.1 INTRODUCTION
In this implementation each stack is associated with a top pointer, which is -1 for an empty
stack.
13.1.1 Push
To push an element X onto the stack, top pointer is incremented by 1 and then set:
Stack [top] = X.
13.1.2 Pop
To pop an element from the stack, the Stack [top] value is returned and the top pointer is
decremented by 1.
IsFull()
Step 1 : Start.
Step 2 : If top = MAX - 1 goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.
int IsFull()
{
if(top == MAX - 1)
return 1; else
return 0;
}
IsEmpty()
Step 1 : Start.
Step 2 : If top = -1 goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.
13.3.2 Routine to Check whether a Stack is Empty
int IsEmpty()
{
if(top == -1)
return 1;
else
return 0;
}
13.4 PUSH
Push(ele)
Step 1 : Start.
Step 2 : If IsFull() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Stack Overflow…!” and goto Step 6.
Step 4 : Set Top = Top + 1.
Step 5 : Set Stack[Top] = ele.
Step 6 : Stop.
13.5 POP
Pop()
Step 1 : Start.
Step 2 : If IsEmpty() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Stack Underflow…!” and goto Step 6.
Step 4 : Display Stack[Top].
Step 5 : Set Top = Top – 1.
Step 6 : Stop.
void Pop()
{
if(IsEmpty())
printf("Stack Underflow...!\n");
else
{
printf("%d\n", Stack[top]);
top = top - 1;
}
}
13.6 PEEK
Top()
Step 1 : Start.
Step 2 : If IsEmpty() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Stack Underflow…!” and goto Step 5.
Step 4 : Display Stack[Top].
Step 5 : Stop.
void Top()
{
if(IsEmpty())
printf("Stack Underflow...!\n");
else
printf("%d\n", Stack[top]);
}
13.7 DISPLAY
Display()
Step 1 : Start.
Step 2 : If IsEmpty() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Stack Underflow…!” and goto Step 8.
Step 4 : Set i = top.
Step 5 : Repeat Steps 6 to 7 while i >= 0.
Step 6 : Display Stack[i].
Step 7 : Set i = i – 1.
Step 8 : Stop.
void Display()
{
int i;
if(IsEmpty())
printf("Stack Underflow...!\n");
else
{
for(i = top; i >= 0; i--)
printf("%d\t", Stack[i]);
printf("\n");
}
}
13.8 PROGRAM
#include <stdio.h>
#define MAX 5
int Stack[MAX], top = -1;
int IsFull(); int
IsEmpty(); void Push(int
ele); void Pop(); void
Top(); void Display();
int main()
{
int ch, e;
do
{
printf("1.PUSH 2.POP 3.TOP 4.DISPLAY 5.EXIT");
printf("\nEnter your choice : "); scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the element : ");
scanf("%d", &e);
Push(e);
break;
case 2:
Pop(); break;
case 3:
Top();
break;
case 4:
Display();
break;
}
} while(ch <= 4);
return 0;
} int IsFull()
{
if(top == MAX - 1)
return 1;
else
return 0;
}
int IsEmpty()
{
if(top == -1)
return 1;
else return 0;
}
void Push(int ele)
{
if(IsFull()) printf("Stack
Overflow...!\n");
else
{
top = top + 1;
Stack[top] = ele;
}
} void Pop()
{
if(IsEmpty())
printf("Stack Underflow...!\n");
else
{
printf("%d\n", Stack[top]);
top = top - 1;
}
}
void Top()
{
if(IsEmpty()) printf("Stack
Underflow...!\n"); else
printf("%d\n", Stack[top]);
} void Display()
{
int i;
if(IsEmpty())
printf("Stack Underflow...!\n");
else
{
for(i = top; i >= 0; i--)
printf("%d\t", Stack[i]);
printf("\n");
}
}
Output
REVIEW QUESTIONS
14.1 INTRODUCTION
In this implementation:
struct node
{
int Element;
struct node *Next;
}*List = NULL;
IsEmpty()
Step 1 : Start.
Step 2 : If List = NULL goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop. Step
4 : Return 0 and Stop.
Step 5 : Stop.
int IsEmpty()
{
if(List == NULL)
return 1;
else
return 0;
}
14.4 PUSH
The push is implemented as an insertion into the front of a linked list, where the front
serves as the top of the stack.
Example
The general idea is shown in Figure. The dashed line represents the old pointer.
Push(10)
NewNode
List
Push(20)
NewNode
List
Push(30)
NewNode
List
Push(e)
Step 1 : Start.
Step 2 : Set NewNode = addressof(Stack).
Step 3 : Set NewNodeElement = e.
Step 4 : If IsEmpty() = True, then goto Step 5 else goto Step 6.
Step 5 : Set NewNodeNext = NULL and goto Step 7.
Step 6 : Set NewNodeNext = List.
Step 7 : Set List = NewNode.
Step 8 : Stop.
void Push(int e)
{
Stack *NewNode = malloc(sizeof(Stack));
NewNode->Element = e;
if(IsEmpty()) NewNode->Next =
NULL; else
NewNode->Next = List;
List = NewNode;
}
14.5 POP
Example
List
Fig. Initial Stack
Pop()
TempNode
List
Pop()
Step 1 : Start.
Step 2 : If IsEmpty() = True, then goto Step 3 else goto Step 4.
Step 3 : Display “Stack is Underflow…!” and goto Step 8.
Step 4 : Set TempNode = List.
Step 5 : Set List = ListNext.
Step 6 : Display the TempNodeElement.
Step 7 : Delete TempNode.
Step 8 : Stop.
void Pop()
{
if(IsEmpty())
printf("Stack is Underflow...!\n");
else
{
Stack *TempNode;
TempNode = List;
List = List->Next;
printf("%d\n", TempNode->Element);
free(TempNode);
}
}
14.6 TOP
Top is performed by examining the element in the first position of the list.
Example
List
Fig. Initial Stack
Top()
List
Top(List)
Step 1 : Start.
Step 2 : If IsEmpty() = True, then goto Step 3 else goto Step 4.
Step 3 : Display “Stack is Underflow…!” and goto Step 5.
Step 4 : Display the List Element.
Step 5 : Stop.
void Top()
{
if(IsEmpty())
printf("Stack is Underflow...!\n"); else
printf("%d\n", List->Element);
}
14.7 DISPLAY
Example
List
Display()
Step 1 : Start.
Step 2 : If IsEmpty() = True goto Step 3 else goto Step 4.
Step 3 : Display “Stack is Underflow…!” and goto Step 8.
Step 4 : Set Position = List.
Step 5 : Repeat the Steps 6-7 until Position != NULL.
Step 6 : Display PositionElement.
Step 7 : Set Position = PositionNext.
Step 8 : Stop.
void Display()
{
if(IsEmpty())
printf("Stack is Underflow...!\n");
else
{
Stack *Position;
Position = List; while(Position !
= NULL)
{
printf("%d\t", Position->Element);
Position = Position->Next;
}
printf("\n");
}
}
14.8 PROGRAM
#include <stdio.h>
#include <stdlib.h>
struct node
{
int Element;
struct node *Next;
}*List = NULL;
void Push(int e)
{
Stack *NewNode = malloc(sizeof(Stack));
NewNode->Element = e;
if(IsEmpty()) NewNode->Next =
NULL; else
NewNode->Next = List;
List = NewNode;
}
void Pop()
{
if(IsEmpty())
printf("Stack is Underflow...!\n");
else
{
Stack *TempNode; TempNode =
List; List = List->Next; printf("%d\
n", TempNode->Element); free(TempNode);
}
} void Top()
{
if(IsEmpty())
printf("Stack is Underflow...!\n");
else
printf("%d\n", List->Element);
}
void Display()
{
if(IsEmpty())
printf("Stack is Underflow...!\n");
else
{
Stack *Position;
Position = List;
while(Position != NULL)
{
printf("%d\t", Position->Element);
Position = Position->Next;
}
printf("\n");
}
}
Output
REVIEW QUESTIONS
• Balancing symbols
• Infix to postfix conversion
• Evaluating postfix expression
• Function calls
• Towers of Hanoi
• 8 queens problem
• Page-visited history in a Web browser (Back Buttons)
• Undo sequence in a text editor
• Matching Tags in HTML and XML
REVIEW QUESTIONS
1. State the applications of stack data structure. (or) List few applications of stack. (or) Mention
the Applications of stack. (or) Write any four applications of stack. (or) List the applications
of stack. (or) Give the applications of stack.
CHAPTER - 16 - BALANCING SYMBOLS
16.1 INTRODUCTION
Compilers check your programs for syntax errors, but frequently a lack of one symbol
(such as a missing brace or comment starter) will cause the compiler to spill out a hundred lines
of diagnostics without identifying the real error.
A useful tool in this situation is a program that checks whether everything is balanced.
Thus, every right brace, bracket, and parenthesis must correspond to their left counterparts. The
sequence [()] is legal, but [(]) is wrong. Obviously, it is not worthwhile writing a huge program
for this, but it turns out that it is easy to check these things. For simplicity, we will just check for
balancing of parentheses, brackets, and braces and ignore any other character that appears.
16.2 EXAMPLES
16.2.1 (a+b)
(
( ( (
(a+b)
16.2.2 ((a+b)
(
( ( a +b)
( (( ( (
( ( ( (
16.2.3 (a+b))
(
( ( (
(a+b)
16.2.4 (a+b]
(
( ( (
(a+b]
16.3 PROGRAM
#include <stdio.h>
#include <string.h>
Output
REVIEW QUESTIONS
17.1 INTRODUCTION
There are 3 different ways of representing the algebraic expression. They are:
• Infix notation
• Postfix notation
• Prefix notation
In infix notation, the arithmetic operator appears between the two operands to which it is
being applied.
For example:
A/B+C
In postfix notation, the arithmetic operator appears directly after the two operands to
which it applies. It is also called as reverse polish notation.
For example:
((A/B) + C) AB/C+
In prefix notation, the arithmetic operator is placed before the two operands to which it
applies. It is also called as polish notation.
For example:
((A/B) + C) +/ABC
REVIEW QUESTIONS
18.1 INTRODUCTION
To evaluate an arithmetic expression, first convert the given infix expression to postfix
expression and then evaluate the postfix expression using stack.
Not only can a stack be used to evaluate a postfix expression, but we can also use a stack
to convert an expression in standard form (otherwise known as infix) into postfix.
18.3 EXAMPLE-I
a+b*c+(d*e+f)*g
First, the symbol a is read, so it is passed through to the output. Then '+' is read and pushed
onto the stack. Next b is read and passed through to the output. The state of affairs at this juncture
is as follows:
Next a '*' is read. The top entry on the operator stack has lower precedence than '*', so
nothing is output and '*' is put on the stack. Next, c is read and output. Thus far, we have
The next symbol is a '+'. Checking the stack, we find that we will pop a '*' and place it on
the output, pop the other '+', which is not of lower but equal priority, on the stack, and then push
the '+'.
The next symbol read is an '(', which, being of highest precedence, is placed on the stack.
Then d is read and output.
We continue by reading a '*'. Since open parentheses do not get removed except when a
closed parenthesis is being processed, there is no output. Next, e is read and output.
The next symbol read is a '+'. We pop and output '*' and then push '+'. Then we read and
output.
Now we read a ')', so the stack is emptied back to the '('. We output a '+'.
We read a '*' next; it is pushed onto the stack. Then g is read and output.
The input is now empty, so we pop and output symbols from the stack until it is empty.
18.4 EXAMPLE-II
a * b + (c – d / e)
a
Stack Output
* a
Stack Output
* ab
Stack Output
+ ab*
Stack Output
(
+ ab*
Stack Output
(
+ ab*c
Stack Output
-
(
+ ab*c
Stack Output
-
(
+ ab*cd
Stack Output
/
-
(
+ ab*cd
Stack Output
/
-
(
+ ab*cde
Stack Output
ab*cde/-+
Stack Output
18.5 EXAMPLE-III
#include <stdio.h>
#include <string.h>
#define MAX 20
int Stack[MAX], top = -1; char
expr[MAX], post[MAX];
void Push(char sym); char
Pop(); char Top();
int Priority(char sym);
int main()
{
int i;
printf("Enter the infix expression : "); gets(expr);
for(i = 0; i < strlen(expr); i++)
{
if(expr[i] >= 'a' && expr[i] <= 'z')
printf("%c", expr[i]); else if(expr[i] == '(')
Push(expr[i]);
else if(expr[i] == ')')
{
while(Top() != '(')
printf("%c", Pop());
Pop();
}
else
{
while(Priority(expr[i])<=Priority(Top()) && top!=-1)
printf("%c", Pop());
Push(expr[i]);
}
}
Output
REVIEW QUESTIONS
19.1 INTRODUCTION
The easiest way to do this is to use a stack. The algorithm uses a stack and is as follows:
19.2 EXAMPLE-I
ab*cde/-+
2
85 8 4
a b * cde/
54 5 20 5 5
4 20 20 20 20
1
20 21
-+
19.3 EXAMPLE-II
Consider the postfix expression 4 5 6 * +. As you scan the expression from left to right,
you first encounter the operands 4 and 5. Placing each on the stack ensures that they are available
if an operator comes next.
In this case, the next symbol is another operand. So, as before, push it and check the next
symbol. Now we see an operator, *. This means that the two most recent operands need to be used
in a multiplication operation. By popping the stack twice, we can get the proper operands and
then perform the multiplication (in this case getting the result 30).
We can now handle this result by placing it back on the stack so that it can be used as an
operand for the later operators in the expression. When the final operator is processed, there will
be only one value left on the stack. Pop and return it as the result of the expression. Fig. 9.1 shows
the stack contents as this entire example expression is being processed.
19.4 EXAMPLE-III
Fig. 19.2 shows a slightly more complex example, 7 8 + 3 2 + /. There are two things to
note in this example. First, the stack size grows, shrinks, and then grows again as the
subexpressions are evaluated. Second, the division operation needs to be handled carefully. Recall
that the operands in the postfix expression are in their original order since postfix changes only
the placement of operators. When the operands for the division are popped from the stack, they
are reversed. Since division is not a commutative operator, in other words 15/515/5 is not the
same as 5/155/15, we must be sure that the order of the operands is not switched.
#include <stdio.h>
#include <string.h>
#define MAX 20
int Stack[MAX], top = -1; char
expr[MAX];
else
{
printf("Enter the value of %c : ", expr[i]);
scanf("%d", &e);
Push(e);
}
}
printf("The result is %d", Pop());
return 0;
}
void Push(int ele)
{
top = top + 1; Stack[top] = ele;
} int Pop()
{
int e;
e = Stack[top];
top = top - 1;
return e;
}
Output
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 20
struct node
{
int Element; struct
node *Next;
}*List = NULL;
case '/':
c = a / b;
Push(c);
break;
}
}
else
{
printf("Enter the value of %c : ", expr[i]);
scanf("%d", &e);
Push(e);
}
}
printf("The result is %d", Pop());
return 0;
}
void Push(int e)
{
Stack *NewNode = malloc(sizeof(Stack));
NewNode->Element = e; if(List
== NULL) NewNode->Next =
NULL; else
NewNode->Next = List;
List = NewNode;
} int Pop()
{
int e;
Stack *TempNode;
TempNode = List;
List = List->Next;
e = TempNode->Element;
free(TempNode);
return e;
}
Output
REVIEW QUESTIONS
20.1 INTRODUCTION
A queue is list with the restrictions that insertion is done at one end (rear), whereas
deletion is performed at the other end (front). It follows First-In-First-Out (FIFO) principle.
• Enqueue - which inserts an element at the end of the list (called rear).
• Dequeue - which deletes (and returns) the element at the start of the list (known as
front).
-1 0 1 2 3 4
F R
20.3 ENQUEUE
• The process of inserting a new element on to the rear of the queue is called enqueue
operation.
• For every enqueue operation the rear pointer is incremented by 1.
10 20 30
0 1 2 3 4
F
R
Fig. 20.4 Enqueue Operations
10.4 DEQUEUE
• The process of deleting an element from the front of queue is called dequeue operation.
• After every dequeue operation the front pointer is incremented by 1.
20 30
0 1 2 3 4
F R
20.5.1 Overflow
10 20 30 40 50
0 1 2 3 4
F R
20.5.2 Underflow
-1 0 1 2 3 4
F R
• Array
• Linked list
REVIEW QUESTIONS
21.1 INTRODUCTION
In this implementation each queue is associated with two pointers namely front and rear,
which is -1 for an empty queue.
21.1.1 Enqueue
To insert an element X onto the queue, the rear pointer is incremented by 1 and then set:
Queue[rear] = X.
21.1.2 Dequeue
To delete an element from the queue, the Queue[front] value is returned and the front
pointer is incremented by 1.
IsFull()
Step 1 : Start.
Step 2 : If rear = MAX - 1 goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.
int IsFull()
{
if(rear == MAX - 1)
return 1; else
return 0;
}
IsEmpty()
Step 1 : Start.
Step 2 : If front = -1 goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.
21.3.2 Routine to whether a Queue is Empty
int IsEmpty()
{
if(front == -1)
return 1;
else
return 0;
}
21.4 ENQUEUE
Enqueue(ele)
ele : int
Step 1 : Start.
Step 2 : If IsFull() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Overflow…!” and goto Step 8.
Step 4 : Set rear = rear + 1.
Step 5 : Set Queue[rear] = ele.
Step 6 : If front = -1 goto Step 7 else goto Step 8.
Step 7 : Set front = 0.
Step 8 : Stop.
21.5 DEQUEUE
Step 1 : Start.
Step 2 : If IsEmpty() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Underflow…!” and goto Step 8.
Step 4 : Display Queue[front].
Step 5 : If front = rear goto Step 6 else goto Step 7.
Step 6 : Set front = rear = -1 and goto Step 8.
Step 7 : Set front = front + 1.
Step 8 : Stop.
void Dequeue()
{
if(IsEmpty())
printf("Queue is Underflow...!\n");
else
{
printf("%d\n", Queue[front]);
if(front == rear)
front = rear = -1;
else
front = front + 1;
}
}
21.6 DISPLAY
Display()
Step 1 : Start.
Step 2 : If IsEmpty() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Underflow…!” and goto Step 8.
Step 4 : Set i = front.
Step 5 : Repeat Steps 6 to 7 while i <= rear.
Step 6 : Display Queue[i].
Step 7 : Set i = i + 1.
Step 8 : Stop.
void Display()
{
int i;
if(IsEmpty())
printf("Queue is Underflow...!\n");
else
{
for(i = front; i <= rear; i++)
printf("%d\t", Queue[i]);
printf("\n");
}
}
21.7 PROGRAM
#include <stdio.h>
#define MAX 5
int IsEmpty()
{
if(front == -1)
return 1;
else return 0;
}
void Enqueue(int ele)
{
if(IsFull()) printf("Queue is
Overflow...!\n");
else
{
rear = rear + 1;
Queue[rear] = ele; if(front ==
-1) front = 0;
}
} void Dequeue()
{
if(IsEmpty()) printf("Queue is
Underflow...!\n");
else
{
printf("%d\n", Queue[front]);
if(front == rear) front = rear =
-1;
else
front = front + 1;
}
} void Display()
{
int i;
if(IsEmpty())
printf("Queue is Underflow...!\n");
else
{
for(i = front; i <= rear; i++)
printf("%d\t", Queue[i]);
printf("\n");
}
}
Output
22.1. INTRODUCTION
In this implementation:
struct node
{
int Element;
struct node *Next;
}*Front = NULL, *Rear = NULL;
IsEmpty(List) Step
1 : Start.
Step 2 : If List = NULL goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop. Step
4 : Return 0 and Stop.
Step 5 : Stop.
22.4 ENQUEUE
Example
Front
Rear
Enqueue(20)
NewNode
Front Rear
Enqueue(30)
NewNode
Front Rear
Enqueue(e)
e : int
Step 1 : Start.
Step 2 : Set NewNode = addressof(Queue).
Step 3 : Set NewNodeElement = e.
Step 4 : Set NewNodeNext = NULL.
Step 5 : If Rear = NULL, then goto Step 6 else goto Step 7.
Step 6 : Set Front = Rear = NewNode and goto Step 9.
Step 7 : Set RearNext = NewNode.
Step 8 : Set Rear = NewNode.
Step 9 : Stop.
void Enqueue(int e)
{
Queue *NewNode = malloc(sizeof(Queue));
NewNode->Element = e;
NewNode->Next = NULL; if(Rear ==
NULL) Front = Rear =
NewNode; else
{
Rear->Next = NewNode;
Rear = NewNode;
}
}
22.5 DEQUEUE
Example
Front Rear
Fig. Initial Queue
Dequeue()
TempNode
Front Rear
Dequque()
Step 1 : Start.
Step 2 : If IsEmpty(Front) = True, then goto Step 3 else goto Step 4.
Step 3 : Display “Queue is Underflow…!” and goto Step 10.
Step 4 : Set TempNode = Front.
Step 5 : If Front = Rear goto Step 6 else goto Step 7.
Step 6 : Set Front = Rear = NULL and goto Step 8.
Step 7 : Set Front = FrontNext.
Step 8 : Display TempNodeElement.
Step 9 : Delete TempNode.
Step 10: Stop.
void Dequeue()
{
if(IsEmpty(Front))
printf("Queue is Underflow...!\n");
else
{
Queue *TempNode;
TempNode = Front;
if(Front == Rear)
Front = Rear = NULL;
else
Front = Front->Next;
printf("%d\n", TempNode->Element);
free(TempNode);
}
}
22.6. DISPLAY
Example
Front Rear
Display(List)
Step 1 : Start.
Step 2 : If IsEmpty(Front) = TRUE goto Step 3 else goto Step 4.
Step 3 : Display “Queue is Underflow…!” and goto Step 8.
Step 4 : Set Position = Front.
Step 5 : Repeat the Steps 6-7 until Position != NULL.
Step 6 : Display PositionElement.
Step 7 : Set Position = PositionNext.
Step 8 : Stop.
void Display()
{
if(IsEmpty(Front))
printf("Queue is Underflow...!\n");
else
{
Queue *Position;
Position = Front;
while(Position != NULL)
{
printf("%d\t", Position->Element);
Position = Position->Next;
}
printf("\n");
}
}
22.7 PROGRAM
#include <stdio.h>
#include <stdlib.h>
struct node
{
int Element; struct
node *Next;
}*Front = NULL, *Rear = NULL; typedef struct
node Queue; int IsEmpty(Queue *List); void
Enqueue(int e); void Dequeue(); void Display();
int main()
{
int ch, e;
do
{
printf("1.ENQUEUE 2.DEQUEUE 3.DISPLAY 4.EXIT");
printf("\nEnter your choice : "); scanf("%d", &ch);
switch(ch)
{
case 1:
printf("Enter the element : ");
scanf("%d", &e); Enqueue(e);
break; case 2:
Dequeue(); break; case 3:
Display(); break;
}
} while(ch <= 3);
return 0;
}
int IsEmpty(Queue *List)
{ if(List == NULL)
return 1;
else
return 0;
} void Enqueue(int e)
{
Queue *NewNode = malloc(sizeof(Queue));
NewNode->Element = e;
NewNode->Next = NULL; if(Rear ==
NULL) Front = Rear =
NewNode; else
{
Rear->Next = NewNode;
Rear = NewNode;
}
}
void Dequeue()
{ if(IsEmpty(Front)) printf("Queue is
Underflow...!\n");
else
{
Queue *TempNode;
TempNode = Front; if(Front == Rear)
Front = Rear = NULL;
else
Front = Front->Next;
printf("%d\n", TempNode->Element);
free(TempNode);
}
} void Display()
{
if(IsEmpty(Front))
printf("Queue is Underflow...!\n");
else
{
Queue *Position;
Position = Front;
while(Position != NULL)
{
printf("%d\t", Position->Element);
Position = Position->Next;
}
printf("\n");
}
}
Output
23.1 INTRODUCTION
A circular queue is a queue whose start and end locations are logically connected with
each other. That means, the start location comes after the end location. If we continue to add
elements in a circular queue till its end location, then after the end location has been filled, the
next element will be added at the beginning of the queue.
As we can see in Fig. 23.2, the start location of the queue comes after its end location. Thus, if
the queue is filled till its capacity, i.e., the end location, then the start location will be checked for
space, and if it is empty, the new element will be added there.
Figure shows the different states of a circular queue during insert and delete operations.
23.1.1 Advantages
Circular queues remove one of the main disadvantages of array implemented queues in
which a lot of memory space is wasted due to inefficient utilization.
IsFull()
Step 1 : Start.
Step 2 : If front = (rear + 1) % MAX goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.
int IsFull() {
if(front == (rear + 1) % MAX)
return 1; else
return 0;
}
IsEmpty()
Step 1 : Start.
Step 2 : If front = -1 goto Step 3 else goto Step 4.
Step 3 : Return 1 and Stop.
Step 4 : Return 0.
Step 5 : Stop.
int IsEmpty()
{
if(front == -1)
return 1;
else
return 0;
}
23.4 ENQUEUE
23.4.1 Algorithm to Enqueue an Element on to the Queue
Enqueue(ele)
ele : int
Step 1 : Start.
Step 2 : If IsFull() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Overflow…!” and goto Step 8.
Step 4 : Set rear = (rear + 1) % MAX.
Step 5 : Set CQueue[rear] = ele.
Step 6 : If front = -1 goto Step 7 else goto Step 8.
Step 7 : Set front = 0.
Step 8 : Stop.
23.5 DEQUEUE
Dequeue()
Step 1 : Start.
Step 2 : If IsEmpty() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Underflow…!” and goto Step 8.
Step 4 : Display CQueue[front].
Step 5 : If front = rear goto Step 6 else goto Step 7.
Step 6 : Set front = rear = -1 and goto Step 8.
Step 7 : Set front = (front + 1) % MAX.
Step 8 : Stop.
23.6 DISPLAY
Display()
Step 1 : Start.
Step 2 : If IsEmpty() = True goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Underflow…!” and goto Step 9.
Step 4 : Set i = front.
Step 5 : Repeat Steps 6 to 7 while i != rear.
Step 6 : Display CQueue[i].
Step 7 : Set i = (i + 1) % MAX.
Step 8 : Display CQueue[i].
Step 9 : Stop.
void Display()
{
int i;
if(IsEmpty())
printf("Queue is Underflow...!\n");
else
{
for(i = front; i != rear; i = (i + 1) % MAX)
printf("%d\t", CQueue[i]);
printf("%d\n", CQueue[i]);
}
}
23.7 PROGRAM
#include <stdio.h>
#define MAX 5
int IsEmpty()
{
if(front == -1)
return 1;
else return 0;
}
void Enqueue(int ele)
{
if(IsFull())
printf("Queue is Overflow...!\n");
else
{
rear = (rear + 1) % MAX;
CQueue[rear] = ele; if(front == -1)
front = 0;
}
}
void Dequeue()
{
if(IsEmpty())
printf("Queue is Underflow...!\n");
else
{
printf("%d\n", CQueue[front]);
if(front == rear) front = rear = -
1;
else
front = (front + 1) % MAX;
}
} void Display()
{
int i;
if(IsEmpty())
printf("Queue is Underflow...!\n");
else
{
for(i = front; i != rear; i = (i + 1) % MAX)
printf("%d\t", CQueue[i]);
printf("%d\n", CQueue[i]);
}
}
Output
REVIEW QUESTIONS
24.1 INTRODUCTION
A double-ended queue is a special type of queue that allows insertion and deletion of
elements at both ends, i.e., front and rear. In simple words, a double-ended queue can be referred
as a linear list of elements in which insertion and deletion of elements takes place at its two ends
but not in the middle. This is the reason why it is termed as double-ended queue or deque.
24.2 TYPES
Based on the type of restrictions imposed on insertion and deletion of elements, a double-
ended queue is categorized into two types:
1. Input-restricted deque
2. Output-restricted deque
It allows deletion from both the ends but restricts the insertion at only one end.
It allows insertion at both the ends but restricts the deletion at only one end.
24.3 OPERATIONS
As shown in Fig., insertion and deletion of elements is possible at both front and rear ends
of the queue. As a result, the following four operations are possible for a double-ended queue:
EnqueueFront(ele)
ele : int
Step 1 : Start.
Step 2 : If front = 0 goto Step 3 else goto Step 4.
Step 3 : Display message “Cannot Insert at Front…!” and goto Step 11.
Step 4 : If front = –1 goto Step 5 else goto Step 9.
Step 5 : Set front = front + 1.
Step 6 : Set DQueue[front] = ele.
Step 7 : If rear = -1 goto Step 8 else goto Step 11.
Step 8 : Set rear = 0 and goto Step 11.
Step 9 : Set front = front – 1.
Step 10: Set DQueue[front] = ele.
Step 11: Stop.
}
}
Step 1 : Start.
Step 2 : If front = -1 goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Underflow…!” and goto Step 8.
Step 4 : Display DQueue[front].
Step 5 : If front = rear goto Step 6 else goto Step 7.
Step 6 : Set front = rear = -1 and goto Step 8.
Step 7 : Set front = front + 1.
Step 8 : Stop.
void DequeueFront()
{
if(front == -1)
printf("Queue is Underflow...!\n");
else
{
printf("%d\n", DQueue[front]);
if(front == rear) front =
rear = -1;
else
front = front + 1;
}
}
EnqueueRear(ele)
ele : int
Step 1 : Start.
Step 2 : If rear = MAX – 1 goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Overflow…!” and goto Step 8.
Step 4 : Set rear = rear + 1.
Step 5 : Set DQueue[rear] = ele.
Step 6 : If front = -1 goto Step 7 else goto Step 8.
Step 7 : Set front = 0.
Step 8 : Stop.
DequeueRear()
Step 1 : Start.
Step 2 : If rear = -1 goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Underflow…!” and goto Step 8.
Step 4 : Display DQueue[front].
Step 5 : If front = rear goto Step 6 else goto Step 7.
Step 6 : Set front = rear = -1 and goto Step 8.
Step 7 : Set rear = rear - 1.
Step 8 : Stop.
void DequeueRear()
{
if(rear == -1)
printf("Queue is Underflow...!\n"); else
{
printf("%d\n", DQueue[rear]);
if(front == rear) front
= rear = -1;
else
rear = rear - 1;
}
}
Step 1 : Start.
Step 2 : If front = -1 goto Step 3 else goto Step 4.
Step 3 : Display message “Queue is Underflow…!” and goto Step 8.
Step 4 : Set i = front.
Step 5 : Repeat Steps 6 to 7 while i <= rear.
Step 6 : Display DQueue[i].
Step 7 : Set i = i + 1.
Step 8 : Stop.
void Display()
{
int i;
if(front == -1)
printf("Queue is Underflow...!\n");
else
{
for(i = front; i <= rear; i++) printf("%d\
t", DQueue[i]); printf("\n");
}
}
24.9 PROGRAM
#include <stdio.h>
#define MAX 5
void DequeueRear()
{
if(rear == -1)
printf("Queue is Underflow...!\n");
else
{
printf("%d\n", DQueue[rear]);
if(front == rear)
front = rear = -1;
else
rear = rear - 1;
}
} void Display()
{
int i;
if(front == -1)
printf("Queue is Underflow...!\n");
else
{
for(i = front; i <= rear; i++)
printf("%d\t", DQueue[i]);
printf("\n");
}
}
Output
1. Define double ended queue (deque). (or) How do you define double ended queue? (or) What
is double ended queue?
2. What are the types of deque?
3. What is an input-restricted deque?
4. What is an output-restricted deque?
5. What are the operations of deque?
6. Explain the significance of double-ended queue.
7. List the differences between stack and queue data structures.