You are on page 1of 12

Chapter 4 Stack and Queue

4.1. Stack
Stack is a data structure provides temporary storage in such a way that the element stored last will be
retried first (Last In First Out or LIFO method). Items can be inserted (“pushed”) and deleted
(“popped”). But only the most recently inserted elements can be operated on. This element is called
“top” of the stack. It can be implemented using.
 Array
 Linked list representation
Stack is useful for temporary storage, especially for dealing with nested structure or processes,
expressions with tin expressions, functions calling other functions, directors within directors.

Operation of stack support:


Push(s, k): Push an item k in to stack s
Pop: deleting the top element, returning its value
Peek(s): returning the value of the top elements
IsEmpty(s): return true if and only the stack is empty
Create(s): Make an empty stack (remove existing items from the stack initialize the stack to empty)
IsFull (): return true if and only if the stack is full.

Array implementation of Sack


It use only and integer index called stack pointer which makes the current top of the stack and
incremented a when new elements pushed into the stack and decremented when popped.
Algorithm:
1. Inclement the stack top by 1
2. Check stack top is less than upper limit of the stack
3. If so put the new element at the position pointed by the top otherwise report stack overflow
Implementation
Data-type stack [maxSize];
Int top=-1;
Void main (int stack [], int*p, int value)
{
If (*top<maxSize)
{
*top=*top+1;
Stack [[*top] =value;
}
Else
{
cout<<”The stack is full cannot push a value\n”;
Exit (0);
}
}
or
stack[maxSize];
int Top=-1;
void push(int data)
{
Top=Top+1;
If (Top < maxSize)
Stack (top)=data
Else

1 Data Structure and Algorithm Analysis ----- Stack and Queue


cout<<”Stack Overflow”;
}
Void main ()
{

Push (data);

}

Pop Operation
Pop operation is a way to remove values from the stack and return its value.
Algorithm:
1. Determine if any value is on the stack
2. If the stack is empty return “stack under flow”
3. Else go to the next step
4. Assign the value at the stack to variable which referenced by the stack pointer () top
Then
Assign null value for the stack slot pointed by the top and determine the stack pointer (top)
3. Return the value bold by the variable
Implementation
Data-type pop (data-type-stack [])
{
Int var=0;
If (top==-1)
cout<<”stack underflow\n”;
Else
{
Var=stack [top];
Stack [top] =NULL;
Top--;
}
Return var;
}
Peek Operation
The peek operation return the top element in the sack without modifying stacks contents.
Implementation exercise:
Laboratory: Write a complete code about array implementation of stack.

Linked List implementation of stack


Linked list implementation uses a single linked list with elements added and removed at one end head
or tail of the list.
Bottom
Head
Name: X Name: X Name: X Top
ID: 1 ID: 1 ID: 1 New
Dept: Cs Dept: Cs Dept: Cs
Pop Operation:
The push operation takes a head or tail pointer to an existing list as the first parameter and a data
value to be pushed as the second parameter and create a new node by using the data value and adds it
to top of the existing list.
Algorithm for push operation to push at the tail of the list
2 Data Structure and Algorithm Analysis ----- Stack and Queue
1. If the stack is empty
Create the new element and make your “stack” and “top” pointers point to it and quit
2. Else
a. Create the new node and make the top most element of the stack to point to it
b. Make the new node your top most element by making the “top” pointer points to it
Implementation
Void push (node *tail, data-type data)
{
If (tail==NULL)
{
Newnode= new node;
Newnode->data=data;
Newnode->next=Null;
Tail=newnode;
}
Else
{
Newnode=new node;
Newnode->data=data;
Newnode->next=Null;
Tail->next=newnode;
Tail=newnode;
}
Implementation for push operation when inserted at the head left as exercise for you.

To implementation pop operation we need a list pointer “target” which will be pointing to the node
before the top node. Each time we pop, the top most nodes will be deleted and “target” will be made as
the top most nodes.
Algorithm for pop operation at the tail:
1. If the stack is empty then, give an alert”stack underflow” and exit the program
2. else if only one node if left free that node and make the “ stack” top and bottom pointers
point to NULL and quit.
3. Else make “target” pointer to just a node before the top, free top most nodes, the target as
your top most elements.
Implementation:
Data-type pop (node *tail, data-type pop-val)
{
Pop-val=0
Node *target=head;
If (head==NULL)
{
cout<<”stack underflow”;
Exit ();
}
Else
{
If (tail==head)
{
Pop-val=tail->data;
Delete tail;
Head=NULL;
Tail=head;
3 Data Structure and Algorithm Analysis ----- Stack and Queue
}
Else
{
While (target->next! =tail)
Target=target->next;
Pop-val=tail->data;
Delete tail;
Tail=target;
Target->next=NULL;
}
}
Return pop-val;
}
Implementation for Pop operation when pop from the head left as exercise for you.
Laboratory: Write a complete code for linked list implementation of stack

Application of stack
In computer science stacks are useful for temporary storage, especially for dealing with nested
structures pr processes for example:
1. To pass parameters between functions (function calling other functions)
2. Expressions with in expression (expression evaluation)
3. Directories with in directories.

Function calling other functions


Each time a function call occurs whether it is recursive function or not the return address in the calling
function is saved. This information is saved so that computer will know where to resume execution in
the calling function after he execution of the function has been completed. This information is called
activation record or stack frame. When a function is called arguments (including the return address)
have to be passed to the called function if stored in affixed memory area then the function cannot be
repeatedly called because first return address would be overwritten by the second return address
before the first used.

Void G () Void H() Void F() Void main()


{ { { {
Int i=30; int i=40; int i=20; int i=30;
} } G (); F ();
H (); ….
} }
Void main()

F()

G() H()
Main function call F and F call G and H that must be first completed before F then F before Main
function. Hence, G and H contain calling function address (return address) of f.
Expression with in expression
Expressions can be evaluated by machine by placing all operations before or after their operands this
method is called polish notation. An arithmetic notation is said to postfix (suffix)notation also called as
reverse polish notation (RNP) if each operator is placed after its operands
E.g. ABC-* is A*(B-C)

4 Data Structure and Algorithm Analysis ----- Stack and Queue


ABC-*D/ is A*(B-C)/D
When the operators exist between two operands, then the expression is called infix notation.
E.g. A+B+C
When the operator comes before their Operands, then the expression is called prefix notation. E.g. -
*ABC
The postfix expression is easier to process by machine than infix because to get evaluated it is first
converted postfix form. Algorithm to process infix is complex and inefficient. Polish notations do not
require any precedence rules parentheses for unique definition and use simple algorithm.
Algorithm to Convert Infix notation to postfix notation (RNP)
While (not end of infix expression){
Get next infix item
If (item is value)
Append item to postfix output
Else if (item==’ (‘) push item on to stack
Else if (item==’)’) {
Pop to x
While (! =’(‘)
Else {
While (precedence (stack top)>=precedence (item))
Pop stack to x and append x to postfix output
Push item on to stack
}}
While (stack not empty)
Pop stack to x and append x to postfix output
 “(“Only popped if matching”)” is found
 All unary operator
 /*
 +-
Example: To change the infix notation to postfix notation A+B*C+ (D*E+F)*G
Solution:
equivalently can be computed using table as follow:
Stack
Token 0 1 2 3 TOP Output
A -1 A
+ + 0 A
B + 0 AB
* + * 1 AB
C + * 1 ABC
+ + 0 ABC*
D + 0 ABC*+
( + ( 1 ABC*+D
* + ( * 2 ABC*+D
E + ( * 2 ABC*+D
+ + ( + 2 ABC*+DE
F + ( + 2 ABC*+D*
) + 0 ABC*+DE*F+
* + 1 ABC*+DE*F+
G + 1 ABC*+DE*F+G
ABC*+DE*F+G*+

5 Data Structure and Algorithm Analysis ----- Stack and Queue


Algorithm to Evaluate expression in postfix expression
Initialize stack to empty
While (not end of postfix expression)
{
Get next postfix item
If (item is value)
Push it onto the stack
Else
If (item is binary operator)
{
Pop the stack to x;
Pop the stack to y;
Push the results onto the stacks;
}
Else
if (item is unary operator){
Pop the stack to x;
Perform operator(x);
Push the results onto the stack;
}
}

The single value in the stack I the desired result


Binary operators: +, -, *, /, etc
Unary operators: unary minus, square root, sign, cos, exp, etc
Example:
So for 6523+8*+3+*
Solution: The first item is the value (6) so it is pushed onto the stack
The first item is the value (5) so it is pushed onto the stack
The first item is the value (2) so it is pushed onto the stack
The first item is the value (3) so it is pushed onto the stack
TOS =>
3
2
5
6
The remaining item are now +8*+3+*
so next a’+’ is read (a binary operator), so 3 and 2 are popped from the stack and their sum ‘5’ is
pushed onto the stack
TOS =>
5
5
6

Next 8 are pushed and the next item is the operator *:


TOS =>
8
5 40
5 5
6 (8, 5 popped, 40 pushed) 6

6 Data Structure and Algorithm Analysis ----- Stack and Queue


Next the operator + followed by 3:
TOS =>
3
45 45
6 6
(40,5 popped, 45 pushed, 3 pushed)
Next operator are +, so 3 and 45 are popped and 4+3=48 is pushed
TOS =>

48
6
Next is operator *, so 48 and 6 are popped, and 6*48 =288 is pushed

288
Now there are no more items and there is a single value on the stack, representing the final answer
288.
Queues
A queue is a data structure that stores a set of elements in particular order and permits addition of
elements from end and removal of elements from front. Elements are removed in the same order in
which they are stored (FIFO). E.g. job scheduling

Operations in Queue
 enqueue - inserting data at the rear of the queue
 dequeue – removing data at the front of the queue
Dequeue Enqueue
Example:
Front Rear

Operation Content of queue


Enqueue(B) B
Enqueue(C) B, C
Dequeue() C
Enqueue(G) C, G
Enqueue (F) C, G, F
Dequeue() G, F
Enqueue(A) G, F, A
Dequeue() F, A
Queue can be implemented using:
 Array
 Linked list
Array implementation
It keeps number of items in the queue and index of the first element and last element
Enqueue Operation:
Size increased and rear changed

7 Data Structure and Algorithm Analysis ----- Stack and Queue


Dequeue Operation:
Size decreased and front change
Algorithm
Initialize FRONT =-1, REAR =-1, Int QUEUESIZE=0;
 To Enqueue data to the queue
o check if there is space in the queue
IF (REAR<MAX_SIZE-1 )
- Increment REAR
- Store the data in Num [REAR]
- Increment QUEUESIZE
If (FRONT = = -1)
- Increment FRONT
Else
Report error message (Queue Overflow)
 To dequeue data from the queue
o check if there is data in the queue
IF (QUEUESIZE > 0 )
- Copy the data in Num[FRONT]
- Increment FRONT
- Decrement QUEUESIZE
Else
- Report Error Message (Queue Underflow)
Implementation:
Const int MAX_SIZE=100;
Int FRONT =-1, REAR =-1;
Int QUEUESIZE = 0;

Void enqueue (int x)


{
If (Rear<MAX_SIZE-1)
{
REAR++;
Num [REAR]=x;
QUEUESIZE++;
If (FRONT = = -1)
FRONT++;
}
Else
Cout<<"Queue Overflow";
}
Int dequeue ()
{
Int x;
If (QUEUESIZE>0)
{
x=Num [FRONT];
FRONT++;
QUEUESIZE--;

}
Else
Cout<<"Queue Underflow";
Return(x);
}

8 Data Structure and Algorithm Analysis ----- Stack and Queue


Limitation: Insert function (enqueue) gives a queue full signal even if a considerable portion is free
Circular Queue
In this implementation freed spaces are reused to store data. The circular queue is full either the first
element is in the first cell and last element is in the last cell or if the first element is right after the last.
12 11
13 10
9
MAX_SIZE - 1 8
0 7
1 6
2 5
3 4
Algorithm:
Initialize int FRONT =-1, REAR =-1, int QUEUESIZE=0;
 To Enqueue data to the queue
o check if there is space in the queue
IF (QUEUESIZE<MAX_SIZE)
- Increment REAR
IF (REAR = = MAX_SIZE)
REAR = 0
- Store the data in Num [REAR]
- Increment QUEUESIZE
IF (FRONT = = -1)
- Increment FRONT
Else
- Queue Overflow
 To dequeue data from the queue
o check if there is data in the queue
IF (QUEUESIZE > 0 )
- Copy the data in Num[FRONT]
- Increment FRONT
IF (FRONT = = MAX_SIZE )
FRONT = 0
- Decrement QUEUESIZE
else
- Queue Underflow

Implementation:
Const int MAX_SIZE=100;
Int FRONT =-1, REAR =-1;
Int QUEUESIZE = 0;

void enqueue(int x)
{
if (QUEUESIZE<MAX_SIZE)
{
REAR++;
if (REAR = = MAX_SIZE)
REAR=0;

9 Data Structure and Algorithm Analysis ----- Stack and Queue


Num [REAR] =x;
QUEUESIZE++;
if (FRONT = = -1)
FRONT++;
}
Else
Cout<<"Queue Overflow";
}
int dequeue ()
{
int x;
if (QUEUESIZE>0)
{
x=Num [FRONT];
FRONT++;
if(FRONT = = MAX_SIZE)
FRONT = 0;
QUEUESIZE--;

}
else
cout<<"Queue Underflow";
return (x);
}

Linked list implementation:


 Enqueue- is inserting a node at the end of a linked list
 Dequeue- is deleting the first node in the list

In linked list data is stored in a node of a linked list. a more natural queue implementation is a double
linked list in which both enqueue and dequeue can be executed in a constant time 0(1). In single list
implementation dequeue requires 0(n) operations primarily to scan the head and stop at the next to
the last node. Initially the list is empty so both front and rear pointers are NULL. The enqueue function
creates a new node, puts the new node data value in it, appends it to an existing list, and makes the
rear pointer point to it. a dequeue function checks whether the queue is empty, and if not, retrieves the
data value of the node pointed to by the front, advances the front and frees the storage of the node
whose data value has been retrieved.

Struct node {
Int data;
Node prev, next;
}
Front=NULL;
Rear=NULL:
Void enqueue (int x)
{
Node *Temp=new Node;
Temp->data=x;
If (! rear)
Head=Temp;
Rear=Temp;
Temp->Next=NULL;
Temp->Prev=NULL;
}
Else

10 Data Structure and Algorithm Analysis ----- Stack and Queue


{
Rear->next=temp;
Temp->prev=rear;
Temp->next=NULL;
Rear=Temp;
}
}
Int dequeue ()
{
If (front==NULL)
{
cout<<”Queue Underflow”;
Return;
}
Int retval =front->data;
Node *temp=front;
If (front->next=NULL)
{
Rear=NULL;
Front=NULL;
}
Else
{
Front=front->next;
Front->prev=NULL;
}
Delete temp;
Return retval;
}
Priority Queue
 Is a queue where each data has an associated key that is provided at the time of insertion
 Dequeue operation deletes data having highest priority in the list
 One of the previously used dequeue or Enqueue operations has to be modified
Example: Consider the following queue of persons where females have higher priority than males
(gender is the key to give priority).
Abebe Alemu Aster Belay Kedir Meron Yonas
Male Male Female Male Male Female Male
Dequeue () - deletes Aster
Abebe Alemu Belay Kedir Meron Yonas
Male Male Male Male Female Male

Dequeue () - deletes Meron Abebe Alemu Belay Kedir Yonas


Male Male Male Male Male
Now the queue has data having equal priority and dequeue operation deletes the front element like in
the case of ordinary queues.
Dequeue ()- deletes Abebe Alemu Belay Kedir Yonas
Male Male Male Male
Dequeue ()- deletes Alemu

Belay Kedir Yonas


Male Male Male
Thus, in the above example the implementation of the dequeue operation need to be modified.

11 Data Structure and Algorithm Analysis ----- Stack and Queue


Next chapter 5 Tree

12 Data Structure and Algorithm Analysis ----- Stack and Queue

You might also like