Stack and Queues
Stack and Queues
Chapter Six
Stacks and Queues
Stacks
Introduction
Implementation:
Stacks can be implemented both as an array (contiguous list) and as
a linked list. We want a set of operations that will work with either
type of implementation: i.e. the method of implementation is hidden
and can be changed without affecting the programs that use them.
The basic Operations
Push()
{ Pop()
if there is room { {
put an item on the top of the stack if stack is not empty {
else return the value of the top item
give an error message remove the top item from the stack
} }
} else {
give an error message
}
}
CreateStack()
{
remove existing items from the stack
initialize the stack to empty
}
Array Implementation of Stacks
The PUSH Operation
• Here, addition of an element is known as the PUSH operation. So, if
an array is given to you, which is supposed to act as a STACK, you
know that it has to be a STATIC Stack; meaning, data will
overflow if you cross the upper limit of the array. So, keep this in
mind.
Algorithm:
• Step-1: Increment the Stack TOP by 1. Check whether it is always
less than the Upper Limit of the stack. If it is less than the Upper
Limit go to step-2 else report -"Stack Overflow“
• Step-2: Put the new element at the position pointed by the TOP
Cont.
Implementation:
• Note:- In array
int stack[UPPERLIMIT];
int top= -1; /*stack is empty*/ implementation, we have taken
..
TOP = -1 to signify the empty
main()
{ stack, as this simplifies the
..
implementation.
push(item);
..
}
push(int item)
{
top = top + 1;
if(top < UPPERLIMIT)
stack[top] = item; /*step-1 & 2*/
else
cout<<"Stack Overflow"; }
Array Implementation of Stacks
The POP Operation
• POP is the synonym for delete when it comes to Stack. So, if you're
taking an array as the stack, remember that you'll return an error
message, "Stack underflow", if an attempt is made to Pop an item
from an empty Stack.
Algorithm:
• Step-1: If the Stack is empty then give the alert "Stack underflow"
and quit; or else go to step-2
Step-2: a) Hold the value for the element pointed by the TOP
b) Put a NULL value instead
c) Decrement the TOP by 1
Implementation:
static int stack[UPPPERLIMIT];
int top=-1;
main() • Note: - Step-2:(b) signifies that
{
.. the respective element has
poped_val = pop(); been deleted.
..
}
int pop()
{
int del_val = 0;
if(top == -1)
cout<<"Stack underflow"; /*step-1*/
else
{
del_val = stack[top]; /*step-2*/
stack[top] = NULL;
top = top -1;
}
return(del_val); }
Exercise
1. Write the C++ full
void display()
implementation of static {
stack (using array). if (top==-1)
cout<<"\nstack is empity!! \n";
2. Compile and run your else{
int i;
code.
cout<<"\n Stack elements are: \n";
for(i=top; i>= 0; i--)
3. Use the following
cout<<stack[i];
function to display the }
}
stack elements.
• Since a dynamic list is used for the stack, the Stack is also
dynamic, means it has no prior upper limit set. So, we don't have to
check for the Overflow condition at all!
Contd.
• Every time we POP, the TOP most element will be deleted and
"target" will be made as the TOP most element.
Contd.
In step[1] we got the "target" pointing to the last but one node.
In step[2] we freed the TOP most element.
In step[3] we made the "target" node as our TOP most element.
Supposing you have only one element left in the Stack, then we won't
make use of "target" rather we'll take help of our "bottom" pointer.
Contd.
Algorithm:
else{
2. Compile and run your code.
display(bottom->next);
3. Use the following recursive cout<< bottom->item<<endl;
stack. }
Stack LL FIM.cpp
Application of Stacks
• Operands are the values on which the operators can perform the
task. Here operand can be a direct value or variable or address of
memory location. Based on the operator position, expressions are
divided into THREE types.
Contd.
• In infix expression, operator is used in between operands. The
general structure of an Infix expression is as follows...
Operand1 Operator Operand2 => (A+B)
• In postfix expression, operator is used after operands. We can say
that “Operator follows the Operands". The general structure of
Postfix expression is as follows...
Operand1 Operand2 Operator => AB+
• In prefix expression, operator is used before operands. We can
say that “Operands follows the Operator". The general structure of
prefix expression is as follows...
Operator Operand1 Operand2 => +AB
2:/*
1:+-
Function Calls
• Reading Assignment!
Queues
Introduction
• Example
1. Using Array
• The enQueue() function takes one value as parameter and inserts that value
into the queue. An integer variable (QUEUESIZE) that tells the total number
of data in the queue is used.
• Step 3: If it is NOT FULL, then increment rear value by one (rear++) and
set queue[rear] = value.
enQueue(value) – Implementation
const int SIZE=100;
int FRONT =-1, REAR =-1;
int QUEUESIZE = 0;
Int Num[SIZE];
void enQueue(int x)
{
if(Rear<SIZE-1)
{
REAR++;
Num[REAR]=x;
QUEUESIZE++;
if(FRONT = = -1)
FRONT++;
}
else
cout<<"Queue Overflow";
}
Contd.
deQueue(value) – Implementation
int deQueue( )
{
int x;
if(QUEUESIZE>0)
{
x=Num[FRONT];
FRONT++;
QUEUESIZE--;
}
else
cout<<"Queue Underflow";
return(x);
}
Contd.
• Step 3: If it is NOT EMTY, then define an integer variable 'i' and set
'i = front'.
• Step 4: Display 'queue[i]' value and increment 'i' value by one (i++).
Repeat the same until 'i' value is equal to rear (i <= rear)
Contd.
display() – Implementation
void display()
{
if(QUEUESIZE==0)
cout<<“\nQueue is Empty";
else
{
cout<<“\n Queue elements are ";
for(i = front; i<= rear ; i++)
cout<<“\t”<< Num[i];
}
}
EX
Combine the above simple array implementations into a single
C++ program and Run it.
Queue SAFIM2.cpp
Linked List implementation of enqueue and
dequeue operations
• Queue using array is not suitable when we don't know the size of
data which we are going to use.
• A queue which is implemented using linked list can work for unlimited
number of values. That means, queue using linked list can work for
variable size of data (No need to fix the size at beginning of the
implementation).
• Example
Contd.
• We can use the following steps to insert a new node into the queue...
• Step 1: Create a newNode with given value and set 'newNode → next'
to NULL.
enQueue(value) – Implementation
• We can use the following steps to delete a node from the queue...
• Step 3: If it is Not Empty then, define a Node pointer 'temp' and set it
to 'front'.
deQueue(value) – Implementation
void deQueue()
{
if(front == NULL)
cout<<"\nQueue is Empty!!!\n";
else{
struct Node *temp = front;
front = front -> next;
cout<<"\nDeleted element: %d\n", temp->data;
delete temp;
}
}
Contd.
• Step 4: Display 'temp → data --->' and move it to the next node.
Repeat the same until 'temp' reaches to 'rear' (temp → next !=NULL
or temp !=NULL).
Contd.
display() – Implementation
void display()
{
if(front == NULL)
cout<<"\nQueue is Empty!!!\n";
else{
struct Node *temp = front;
while(temp != NULL){
cout<<temp->data<<"--->";
temp = temp -> next;
}
cout<<"NULL";
}}
EX
Combine the above Linked List implementations into a single C++
program and Run it.
Queue LLFIM.cpp
Deque (pronounced as Deck)
• Deque is a Double Ended Queue
• Insertion and deletion can occur at either end
• Deque has the following basic operations
EnqueueFront – inserts data at the front of the list
DequeueFront – deletes data at the front of the list
EnqueueRear – inserts data at the end of the list
DequeueRear – deletes data at the end of the list
• Implementation is similar to that of queue.
• Deque is best implemented using doubly linked list
Priority Queue
• Priority Queue is a queue where each data has an associated key that is
provided at the time of insertion.
Algorithm:
create empty females and males queue
while (PriorityQueue is not empty)
{
Data=DequeuePriorityQueue(); // delete data at the front
if(gender of Data is Female)
EnqueueFemale(Data);
else
EnqueueMale(Data);
}
EX.