Explain Stack and its Concepts, Its Operations, Queue, Circular Queue, Priority Queue. Explain Queue and It's Operations
Data Structures, Abstract Data Types
young call girls in Green Park🔝 9953056974 🔝 escort Service
What is Stack, Its Operations, Queue, Circular Queue, Priority Queue
1. DATA STRUCTURES
Lectures: 4 hrs/week Theory: 50 Marks
Class - SECSE Online: 50 Marks
By
Mr. B. J Gorad,
BE(CSE), M.Tech (CST), GATE2011,2016, PhD(CSE)*
Assistant Professor, Computer Science and Engineering,
Sharad Institute of Technology College of Engineering,
Ichalkaranji, Maharashtra
2. Course Outcomes
At the end of Course students will
CO1 - Familiar with C programming and basic data structures.
CO2 - Understand various searching and sorting algorithms and they will able to
Choose the appropriate data structure and algorithm design method for a
specified application.
CO3 - Understand the abstract properties of various data structures such as stacks,
queues. Also they will able to choose appropriate data structure for
specified application.
CO4 - Understand the abstract properties of various data structures such as Lists.
Also they will able to choose appropriate data structure for specified application.
CO5 - Understand and apply fundamental algorithmic problems including Tree, B+
Tree, and Tree traversals.
CO6 - Understand and apply fundamental algorithmic problems including Graph,
Graph traversals and shortest paths
3. Stack and Queue
Stack
A stack is an Abstract Data Type (ADT), commonly used in most
programming languages (existing in thought or as an idea but
not having a physical or concrete existence).
It is named stack as it behaves like a real-world stack, for
example – a deck of cards or a pile of plates, etc.
4. A real-world stack allows operations at one end only.
For example, we can place or remove a card or plate
from the top of the stack only. Likewise, Stack ADT
allows all data operations at one end only.
At any given time, we can only access the top
element of a stack. This feature makes it LIFO data
structure. LIFO stands for Last-in-first-out.
Here, the element which is placed (inserted or
added) last, is accessed first. In stack terminology,
insertion operation is called PUSH operation and
removal operation is called POP operation.
Stack... Continued
5. Stack Representation
The following diagram depicts a stack and its operations −
A stack can be implemented by means of Array, Structure,
Pointer, and Linked List.
Stack can either be a fixed size one or it may have a sense of
dynamic resizing.
Here, we are going to implement stack using arrays, which
makes it a fixed size stack implementation.
6. Basic Operations of Stack
• Stack operations may involve initializing the stack,
using it and then de-initializing it. Apart from these
basic stuffs, a stack is used for the following two
primary operations −
– push() − Pushing (storing) an element on the stack.
– pop() − Removing (accessing) an element from the stack.
when data is PUSHed onto stack.
To use a stack efficiently, we need to check the status of
stack as well. For the same purpose, the following
functionality is added to stacks −
7. – peek() − get the top data element of the stack, without
removing it.
– isFull() − check if stack is full.
– isEmpty() − check if stack is empty.
At all times, we maintain a pointer to the last
PUSHed data on the stack. As this pointer always
represents the top of the stack, hence named top.
The top pointer provides top value of the stack
without actually removing it.
First we should learn about procedures to support
stack functions −
8. 1. peek()
Algorithm of peek() function −
begin procedure peek
return stack[top]
end procedure
Implementation of peek() function in C programming language −
Example-
int peek()
{
return stack[top];
}
9. 2. isFull()
Algorithm of isFull() function −
begin procedure isfull
if top equals to MAXSIZE
return true
else
return false
endif
end procedure
Implementation of isFull() function in C programming language −
Example- bool isfull()
{
if(top == MAXSIZE)
return true;
else
return false;
}
10. 2. isEmpty()
Algorithm of isEmpty() function −
begin procedure isEmpty
if top top less than 1
return true
else
return false
endif
end procedure
11. Implementation of isempty() function in C programming
language is slightly different.
We initialize top at -1, as the index in array starts from 0. So
we check if the top is below zero or -1 to determine if the
stack is empty.
Here's the code −
Example-
bool isEmpty()
{
if(top == -1)
return true;
else
return false;
}
12. Push Operation
• The process of putting a new data element onto stack is
known as a Push Operation. Push operation involves a series
of steps −
– Step 1 − Checks if the stack is full.
– Step 2 − If the stack is full, produces an error and exit.
– Step 3 − If the stack is not full, increments top to point next empty
space.
– Step 4 − Adds data element to the stack location, where top is
pointing.
– Step 5 − Returns success.
If the linked list is used to
implement the stack, then in
step 3, we need to allocate space
dynamically.
13. Algorithm for PUSH Operation
• A simple algorithm for Push operation can be
derived as follows −
begin procedure push: stack, data
if stack is full
return null
endif
top ← top + 1
stack[top] ← data
end procedure
14. Implementation of this algorithm in C, is very easy.
See the following code − Example
void push(int data)
{
if(!isFull())
{
top = top + 1;
stack[top] = data;
}
else
{
printf("Could not insert data, Stack is full.n");
}
}
15. Pop Operation
• Accessing the content while removing it from the stack, is known
as a Pop Operation. In an array implementation of pop()
operation, the data element is not actually removed, instead top
is decremented to a lower position in the stack to point to the
next value. But in linked-list implementation, pop() actually
removes data element and deallocates memory space.
A Pop operation may involve the following steps −
– Step 1 − Checks if the stack is empty.
– Step 2 − If the stack is empty, produces an error and exit.
– Step 3 − If the stack is not empty, accesses the data element at which top
is pointing.
– Step 4 − Decreases the value of top by 1.
– Step 5 − Returns success.
16. • Algorithm for Pop Operation
• A simple algorithm for Pop operation can be derived
as follows −
begin procedure pop: stack
if stack is empty
return null
endif
data ← stack[top]
top ← top - 1
return data
end procedure
17. Implementation of this algorithm in C, is as follows −
• Example
int pop(int data)
{
if(!isempty())
{
data = stack[top];
top = top - 1;
return data;
}
else
{
printf("Could not retrieve data, Stack is empty.n");
}
}
18. Implementation of Stack C Program
#include <stdio.h>
int MAXSIZE = 8;
int stack[8];
int top = -1;
int isempty()
{
if(top == -1)
return 1;
else
return 0;
}
int isfull()
{
if(top == MAXSIZE)
return 1;
else
return 0;
}
int peek() {
return stack[top];
}
int pop() {
int data;
if(!isempty()) {
data = stack[top];
top = top - 1;
return data;
}
Else { printf("Could not retrieve data, Stack is empty.n"); }
}
int push(int data)
{
if(!isfull())
{
top = top + 1;
stack[top] = data;
}
else
{
printf("Could not insert data, Stack is full.n");
} }
19. int main() {
// push items on to the stack
push(3);
push(5);
push(9);
push(1);
push(12);
push(15);
printf("Element at top of the stack: %dn" ,peek());
printf("Elements: n"); // print stack data
while(!isempty()) {
int data = pop();
printf("%dn",data);
}
printf("Stack full: %sn" , isfull()?"true":"false");
printf("Stack empty: %sn" , isempty()?"true":"false");
return 0;
}
20. Queue
Queue
Queue is an abstract data structure, somewhat similar to
Stacks. Unlike stacks, a queue is open at both its ends. One end
is always used to insert data (enqueue) and the other is used to
remove data (dequeue). Queue follows First-In-First-Out
methodology, i.e., the data item stored first will be accessed
first.
21. A real-world example of queue can be a single-lane
one-way road, where the vehicle enters first, exits
first. More real-world examples can be seen as
queues at the ticket windows and bus-stops.
• Queue Representation
• As we now understand that in queue, we access both
ends for different reasons. The following diagram
given below tries to explain queue representation as
data structure −
queue... Continued
22. • As in stacks, a queue can also be implemented using Arrays,
Linked-lists, Pointers and Structures.
• For the sake of simplicity, we shall implement queues using one-
dimensional array.
• Basic Operations
• Queue operations may involve initializing or defining the queue,
utilizing it, and then completely erasing it from the memory. Here
we shall try to understand the basic operations associated with
queues −
– enqueue() − add (store) an item to the queue.
– dequeue() − remove (access) an item from the queue.
• Few more functions are required to make the above-mentioned
queue operation efficient. These are −
– peek() − Gets the element at the front of the queue without removing it.
– isfull() − Checks if the queue is full.
– isempty() − Checks if the queue is empty.
23. • In queue, we always dequeue (or access) data, pointed by
front pointer and while enqueing (or storing) data in the
queue we take help of rear pointer.
• Let's first learn about supportive functions of a queue −
• peek()
• This function helps to see the data at the front of the queue.
The algorithm of peek() function is as follows −
• Algorithm
begin procedure peek
return queue[front]
end procedure
• Example
int peek()
{
return queue[front];
}
24. • isfull()
• As we are using single dimension array to implement queue,
we just check for the rear pointer to reach at MAXSIZE to
determine that the queue is full. In case we maintain the
queue in a circular linked-list, the algorithm will differ.
Algorithm of isfull() function −
begin procedure isfull
if rear equals to MAXSIZE-1
return true
else
return false
endif
end procedure
Example
bool isfull()
{
if(rear == MAXSIZE - 1)
return true;
else
return false;
}
25. • isempty()
• Algorithm of isempty() function −
• Algorithm
begin procedure isempty
if front is less than MIN OR front is greater than rear
return true
else
return false
endif
end procedure
If the value of front is less than MIN or 0, it tells that the queue
is not yet initialized, hence empty. Example
bool isempty()
{
if(front < 0 || front > rear)
return true;
else return false;
26. • Enqueue Operation
• Queues maintain two data pointers, front and rear.
Therefore, its operations are comparatively difficult
to implement than that of stacks.
• The following steps should be taken to enqueue
(insert) data into a queue −
– Step 1 − Check if the queue is full.
– Step 2 − If the queue is full, produce overflow error and
exit.
– Step 3 − If the queue is not full, increment rear pointer to
point the next empty space.
– Step 4 − Add data element to the queue location, where
the rear is pointing.
– Step 5 − return success.
27. • Sometimes, we also check to see if a queue is initialized or
not, to handle any unforeseen situations.
• Algorithm for enqueue operation
procedure enqueue(data)
if queue is full
return overflow
endif
rear ← rear + 1
queue[rear] ← data
return true
end procedure
Example
int enqueue(int data)
{
if(isfull())
{
return 0;
}
rear = rear + 1;
queue[rear] = data;
return 1;
}
28. • Dequeue Operation
• Accessing data from the queue is a process of two
tasks − access the data where front is pointing and
remove the data after access. The following steps are
taken to perform dequeue operation −
– Step 1 − Check if the queue is empty.
– Step 2 − If the queue is empty, produce underflow error
and exit.
– Step 3 − If the queue is not empty, access the data where
front is pointing.
– Step 4 − Increment front pointer to point to the next
available data element.
– Step 5 − Return success.
29. • Algorithm for dequeue operation
procedure dequeue
if queue is empty
return underflow
end if
data = queue[front]
front ← front + 1
return true
end procedure
31. Circular Queue
• Circular Queue
In a normal Queue Data Structure, we can insert elements
until queue becomes full. But once if queue becomes full, we
can not insert the next element until all the elements are
deleted from the queue. For example consider the queue
below...
After inserting all the elements into the queue.
32. Now consider the following situation after deleting
three elements from the queue...
• This situation also says that Queue is Full and we can
not insert the new element because, 'rear' is still at
last position.
• In above situation, even though we have empty
positions in the queue we can not make use of them
to insert new element.
• This is the major problem in normal queue data
structure. To overcome this problem we use circular
queue data structure.
33. What is Circular Queue?
• A Circular Queue can be defined as follows...
• Circular Queue is a linear data structure in which the
operations are performed based on FIFO (First In
First Out) principle and the last position is connected
back to the first position to make a circle.
• Graphical representation of a circular queue is as
follows...
34. Implementation of Circular Queue
• To implement a circular queue data structure using
array, we first perform the following steps before we
implement actual operations.
– Step 1: Include all the header files which are used in the
program and define a constant 'SIZE' with specific value.
– Step 2: Declare all user defined functions used in circular
queue implementation.
– Step 3: Create a one dimensional array with above defined
SIZE (int cQueue[SIZE])
– Step 4: Define two integer variables 'front' and 'rear' and
initialize both with '-1'. (int front = -1, rear = -1)
– Step 5: Implement main method by displaying menu of
operations list and make suitable function calls to perform
operation selected by the user on circular queue.
35. enQueue(value) - Inserting value into the Circular Queue
In a circular queue, enQueue() is a function which is used to
insert an element into the circular queue.
In a circular queue, the new element is always inserted at rear
position. The enQueue() function takes one integer value as
parameter and inserts that value into the circular queue. We
can use the following steps to insert an element into the
circular queue...
– Step 1: Check whether queue is FULL. ((rear == SIZE-1 && front == 0) || (front
== rear+1))
– Step 2: If it is FULL, then display "Queue is FULL!!! Insertion is not possible!!!"
and terminate the function.
– Step 3: If it is NOT FULL, then check rear == SIZE - 1 && front != 0 if it is TRUE,
then set rear = -1.
– Step 4: Increment rear value by one (rear++), set queue[rear] = value and
check 'front == -1' if it is TRUE, then set front = 0.
36. deQueue() - Deleting a value from the Circular Queue
• In a circular queue, deQueue() is a function used to
delete an element from the circular queue.
• In a circular queue, the element is always deleted
from front position. The deQueue() function doesn't
take any value as parameter. We can use the
following steps to delete an element from the
circular queue...
– Step 1: Check whether queue is EMPTY. (front == -1 && rear == -1)
– Step 2: If it is EMPTY, then display "Queue is EMPTY!!! Deletion is not
possible!!!" and terminate the function.
– Step 3: If it is NOT EMPTY, then display queue[front] as deleted
element and increment the front value by one (front ++). Then check
whether front == SIZE, if it is TRUE, then set front = 0.
Then check whether both front - 1 and rear are equal (front -1 ==
rear), if it TRUE, then set both front and rear to '-1' (front = rear = -1).
37. display() - Displays the elements of a Circular Queue
• We can use the following steps to display the
elements of a circular queue...
– Step 1: Check whether queue is EMPTY. (front == -1)
– Step 2: If it is EMPTY, then display "Queue is EMPTY!!!" and terminate
the function.
– Step 3: If it is NOT EMPTY, then define an integer variable 'i' and set 'i
= front'.
– Step 4: Check whether 'front <= rear', if it is TRUE, then display
'queue[i]' value and increment 'i' value by one (i++). Repeat the same
until 'i <= rear' becomes FALSE.
– Step 5: If 'front <= rear' is FALSE, then display 'queue[i]' value and
increment 'i' value by one (i++). Repeat the same until'i <= SIZE - 1'
becomes FALSE.
– Step 6: Set i to 0.
– Step 7: Again display 'cQueue[i]' value and increment i value by one
(i++). Repeat the same until 'i <= rear' becomes FALSE.
39. #include<stdio.h>
#include<conio.h>
#define SIZE 5
void enQueue(int);
void deQueue();
void display();
int cQueue[SIZE], front = -1, rear = -1;
void main()
{
int choice, value;
clrscr();
while(1)
{
printf("n****** MENU ******n");
printf("1. Insertn2. Deleten3.
Displayn4. Exitn");
printf("Enter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("nEnter the value to be
insert: ");
scanf("%d",&value);
enQueue(value);
break;
case 2: deQueue();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("nPlease select the correct
choice!!!n");
}
}
}
void enQueue(int value)
{
if((front == 0 && rear == SIZE - 1) || (front ==
rear+1))
printf("nCircular Queue is Full!
Insertion not possible!!!n");
Else
{
if(rear == SIZE-1 && front != 0) rear = -1;
cQueue[++rear] = value;
printf("nInsertion Success!!!n");
if(front == -1) front = 0;
}
}
40. void deQueue()
{
if(front == -1 && rear == -1)
printf("nCircular Queue is Empty!
Deletion is not possible!!!n");
Else
{
printf("nDeleted element : %dn",
cQueue[front++]);
if(front == SIZE)
front = 0;
if(front-1 == rear)
front = rear = -1;
}
}
void display()
{
if(front == -1)
printf("nCircular Queue is
Empty!!!n");
Else
{
int i = front;
printf("nCircular Queue Elements are :
n");
if(front <= rear)
{
while(i <= rear)
printf("%dt",
cQueue[i++]);
}
Else
{
while(i <= SIZE - 1)
printf("%dt", cQueue[i++]);
i = 0;
while(i <= rear)
printf("%dt", cQueue[i++]);
} } }
41.
42.
43. • In normal queue data structure, insertion is
performed at the end of the queue and deletion is
performed based on the FIFO principle. This queue
implementation may not be suitable for all situations.
Consider a networking application where server has
to respond for requests from multiple clients using
queue data structure.
• Assume four requests arrived to the queue in the
order of R1 requires 20 units of time, R2 requires 2
units of time, R3 requires 10 units of time and R4
requires 5 units of time. Queue is as follows...
44. • Now, check waiting time for each request to be complete.
– R1 : 20 units of time
– R2 : 22 units of time (R2 must wait till R1 complete - 20 units and R2
itself requeres 2 units. Total 22 units)
– R3 : 32 units of time (R3 must wait till R2 complete - 22 units and R3
itself requeres 10 units. Total 32 units)
– R4 : 37 units of time (R4 must wait till R3 complete - 35 units and R4
itself requeres 5 units. Total 37 units)
• Here, average waiting time for all requests (R1, R2, R3 and
R4) is (20+22+32+37)/4 ≈ 27 units of time.
• That means, if we use a normal queue data structure to serve
these requests the average waiting time for each request is 27
units of time.
45. • Now, consider another way of serving these requests. If we
serve according to their required amount of time. That
means, first we serve R2 which has minimum time required
(2) then serve R4 which has second minimum time required
(5) then serve R3 which has third minimum time required (10)
and finnaly R1 which has maximum time required (20).
• Now, check waiting time for each request to be complete.
– R2 : 2 units of time
– R4 : 7 units of time (R4 must wait till R2 complete 2 units and R4 itself
requeres 5 units. Total 7 units)
– R3 : 17 units of time (R3 must wait till R4 complete 7 units and R3 itself
requeres 10 units. Total 17 units)
– R1 : 37 units of time (R1 must wait till R3 complete 17 units and R1 itself
requeres 20 units. Total 37 units)
Here, average waiting time for all requests (R1, R2, R3 and R4) is (2+7+17+37)/4
≈ 15 units of time.
From above two situations, it is very clear that, by using second method server
can complete all four requests with very less time compared to the first
method. This is what exactly done by the priority queue.
46. • Priority queue is a variant of queue data structure in which
insertion is performed in the order of arrival and deletion is
performed based on the priority.
• There are two types of priority queues they are as follows...
– Max Priority Queue
– Min Priority Queue
1. Max Priority Queue
• In max priority queue, elements are inserted in the order in
which they arrive the queue and always maximum value is
removed first from the queue. For example assume that we
insert in order 8, 3, 2, 5 and they are removed in the order 8,
5, 3, 2.The following are the operations performed in a Max
priority queue...
– isEmpty() - Check whether queue is Empty.
– insert() - Inserts a new value into the queue.
– findMax() - Find maximum value in the queue.
– remove() - Delete maximum value from the queue.
47. 2. Min Priority Queue Representations
• Min Priority Queue is similar to max priority queue
except removing maximum element first, we remove
minimum element first in min priority queue.
The following operations are performed in Min
Priority Queue...
– isEmpty() - Check whether queue is Empty.
– insert() - Inserts a new value into the queue.
– findMin() - Find minimum value in the queue.
– remove() - Delete minimum value from the queue.
– Min priority queue is also has same representations as Max priority
queue with minimum value removal.