0% found this document useful (0 votes)
6 views59 pages

Stacks Data Structure

The document provides a comprehensive overview of the stack data structure, emphasizing its LIFO (Last In First Out) principle and common operations such as push, pop, isEmpty, and peek. It discusses fixed and dynamic size stacks, their implementations using arrays and linked lists, and various applications in computer science, including expression evaluation and memory management. Additionally, it includes algorithms for stack operations and their time complexities.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views59 pages

Stacks Data Structure

The document provides a comprehensive overview of the stack data structure, emphasizing its LIFO (Last In First Out) principle and common operations such as push, pop, isEmpty, and peek. It discusses fixed and dynamic size stacks, their implementations using arrays and linked lists, and various applications in computer science, including expression evaluation and memory management. Additionally, it includes algorithms for stack operations and their time complexities.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 59

C NITHISHA – SOCTS0369

Stacks Data Structure

“A stack is a linear data structure in which the insertion of a new


element and removal of an existing element takes place at the same
end represented as the top of the stack”.
To implement the stack, it is required to maintain the pointer to the top
of the stack, which is the last element to be inserted because we can
access the elements only on the top of the stack.
LIFO( Last In First Out ):
This strategy states that the element that is inserted last will come out
first. You can take a pile of plates kept on top of each other as a real-life
example. The plate which we put last is on the top and since we remove
the plate that is at the top, we can say that the plate that was put last
comes out first.

The following are some common operations implemented on the


stack:

o push(): When we insert an element in a stack then the operation is


known as a push. If the stack is full then the overflow condition
occurs.
o pop(): When we delete an element from the stack, the operation is
known as a pop. If the stack is empty means that no element exists
in the stack, this state is known as an underflow state.
o isEmpty(): It determines whether the stack is empty or not.
o isFull(): It determines whether the stack is full or not.'
C NITHISHA – SOCTS0369

o peek(): It returns the element at the given position.


o count(): It returns the total number of elements available in a
stack.
o change(): It changes the element at the given position.
o display(): It prints all the elements available in the stack.

Understanding stack practically:


There are many real-life examples of a stack. Consider the simple
example of plates stacked over one another in a canteen. The plate which
is at the top is the first one to be removed, i.e. the plate which has been
placed at the bottommost position remains in the stack for the longest
period of time. So, it can be simply seen to follow the LIFO/FILO order.
Complexity Analysis: Time Complexity
Operations Complexity
push() O(1)
pop() O(1)
isEmpty() O(1)
size() O(1)
Types of Stacks:
Fixed Size Stack:
As the name suggests, a fixed size stack has a fixed size and cannot
grow or shrink dynamically. If the stack is full and an attempt is made to
add an element to it, an overflow error occurs. If the stack is empty and
an attempt is made to remove an element from it, an underflow error
occurs.
C NITHISHA – SOCTS0369

Dynamic Size Stack:


A dynamic size stack can grow or shrink dynamically. When the stack is
full, it automatically increases its size to accommodate the new element,
and when the stack is empty, it decreases its size. This type of stack is
implemented using a linked list, as it allows for easy resizing of the
stack.
In addition to these two main types, there are several other variations of
Stacks, including:
Infix to Postfix Stack: This type of stack is used to convert infix
expressions to postfix expressions.
Expression Evaluation Stack: This type of stack is used to evaluate
postfix expressions.
Recursion Stack: This type of stack is used to keep track of function
calls in a computer program and to return control to the correct function
when a function returns.
Memory Management Stack: This type of stack is used to store the
values of the program counter and the values of the registers in a
computer program, allowing the program to return to the previous state
when a function returns.
Balanced Parenthesis Stack: This type of stack is used to check the
balance of parentheses in an expression.
Undo-Redo Stack: This type of stack is used in computer programs to
allow users to undo and redo actions.
C NITHISHA – SOCTS0369

Working of Stack
Stack works on the LIFO pattern. As we can observe in the below figure
there are five memory blocks in the stack; therefore, the size of the stack
is 5.

Suppose we want to store the elements in a stack and let's assume that
stack is empty. We have taken the stack of size 5 as shown below in
which we are pushing the elements one by one until the stack becomes
full.

Since our stack is full as the size of the stack is 5. In the above cases, we
can observe that it goes from the top to the bottom when we were
entering the new element in the stack. The stack gets filled up from the
bottom to the top.
When we perform the delete operation on the stack, there is only one
way for entry and exit as the other end is closed. It follows the LIFO
pattern, which means that the value entered first will be removed last. In
the above case, the value 5 is entered first, so it will be removed only
after the deletion of all the other elements.
C NITHISHA – SOCTS0369

PUSH operation
The steps involved in the PUSH operation is given below:

o Before inserting an element in a stack, we check whether the stack


is full.
o If we try to insert the element in a stack, and the stack is full, then
the overflow condition occurs.
o When we initialize a stack, we set the value of top as -1 to check
that the stack is empty.
o When the new element is pushed in a stack, first, the value of the
top gets incremented, i.e., top=top+1, and the element will be
placed at the new position of the top.
o The elements will be inserted until we reach the max size of the
stack.
C NITHISHA – SOCTS0369

Push:
Adds an item to the stack. If the stack is full, then it is said to be an
Overflow condition.
Algorithm for push:
begin
if stack is full
return
endif
else
increment top
stack[top] assign value
end else
end procedure

POP operation
The steps involved in the POP operation is given below:

o Before deleting the element from the stack, we check whether the
stack is empty.
o If we try to delete the element from the empty stack, then
the underflow condition occurs.
o If the stack is not empty, we first access the element which is
pointed by the top
C NITHISHA – SOCTS0369

o Once the pop operation is performed, the top is decremented by 1,


i.e., top=top-1.

Pop:
Removes an item from the stack. The items are popped in the reversed
order in which they are pushed. If the stack is empty, then it is said to be
an Underflow condition.
Algorithm for pop:
begin
if stack is empty
return
endif
C NITHISHA – SOCTS0369

else
store value of stack[top]
decrement top
return value
end else
end procedure

Top:
Returns the top element of the stack.
Algorithm for Top:
begin
return stack[top]
end procedure

isEmpty:
Returns true if the stack is empty, else false.
Algorithm for isEmpty:
begin
if top < 1
return true
C NITHISHA – SOCTS0369

else
return false
end procedure

Applications of the stack:


 Infix to Postfix /Prefix conversion
 Redo-undo features at many places like editors, photoshop.
 Forward and backward features in web browsers
 Used in many algorithms like Tower of Hanoi, tree traversals,
stock span problems, and histogram problems.
 Backtracking is used to solve problems like the Knight-Tour
problem, N-Queen problem, maze problems, and game-like chess
or checkers in all these problems we dive into someway if that way
is inefficient, we come back to the previous state and go into some
another path. To get back from a current state we need to store the
previous state in a stack.
 In Graph Algorithms like Topological Sorting and Strongly
Connected Components
 In Memory management, any modern computer uses a stack as the
primary management for a running purpose. Each program that is
running in a computer system has its own memory allocations.
 Stack also helps in implementing function call in computers. The
last called function is always completed first.
C NITHISHA – SOCTS0369

Implementation of Stack:
The basic operations that can be performed on a stack include push, pop,
and peek. There are two ways to implement a stack –
 Using array
 Using linked list

In an array-based implementation, the push operation is implemented


by incrementing the index of the top element and storing the new
element at that index. The pop operation is implemented by
decrementing the index of the top element and returning the value stored
at that index.
Advantages of array implementation:
 Easy to implement.
 Memory is saved as pointers are not involved.
Disadvantages of array implementation:
 It is not dynamic i.e., it doesn’t grow and shrink depending on
needs at runtime. [But in case of dynamic sized arrays like vector
in C++, list in Python, ArrayList in Java, stacks can grow and
shrink with array implementation as well].
 The total size of the stack must be defined beforehand.

In a linked list-based implementation, the push operation is


implemented by creating a new node with the new element and setting
the next pointer of the current top node to the new node. The pop
C NITHISHA – SOCTS0369

operation is implemented by setting the next pointer of the current top


node to the next node and returning the value of the current top node.
Advantages of Linked List implementation:
 The linked list implementation of a stack can grow and shrink
according to the needs at runtime.
 It is used in many virtual machines like JVM.
Disadvantages of Linked List implementation:
 Random accessing is not possible in stack.
 Requires extra memory due to the involvement of pointers.

Array implementation of Stack


In array implementation, the stack is formed by using the array. All the
operations regarding the stack are performed using arrays. Lets see how
each operation can be implemented on the stack using array data
structure.

Adding an element onto the stack (push operation)

Adding an element into the top of the stack is referred to as push


operation. Push operation involves following two steps.

1. Increment the variable Top so that it can now refere to the next
memory location.
2. Add element at the position of incremented top. This is referred to
as adding new element at the top of the stack.
C NITHISHA – SOCTS0369

Stack is overflown when we try to insert an element into a completely


filled stack therefore, our main function must always avoid stack
overflow condition.

Algorithm:

1. begin
2. if top = n then stack full
3. top = top + 1
4. stack (top) : = item;
5. end

Time Complexity : o(1)

Implementation of push algorithm in C language

1. void push (int val,int n) //n is size of the stack


2. {
3. if (top == n )
4. printf("\n Overflow");
5. else
6. {
7. top = top +1;
8. stack[top] = val;
9. }
10. }
C NITHISHA – SOCTS0369

Deletion of an element from a stack (Pop operation)

Deletion of an element from the top of the stack is called pop operation.
The value of the variable top will be incremented by 1 whenever an item
is deleted from the stack. The top most element of the stack is stored in
an another variable and then the top is decremented by 1. the operation
returns the deleted value that was stored in another variable as the result.

The underflow condition occurs when we try to delete an element from


an already empty stack.

Algorithm :

1. begin
2. if top = 0 then stack empty;
3. item := stack(top);
4. top = top - 1;
5. end;

Time Complexity : o(1)

Implementation of POP algorithm using C language

1. int pop ()
2. {
3. if(top == -1)
4. {
5. printf("Underflow");
6. return 0;
7. }
C NITHISHA – SOCTS0369

8. else
9. {
10. return stack[top - - ];
11. }
12. }

Visiting each element of the stack (Peek operation)

Peek operation involves returning the element which is present at the top
of the stack without deleting it. Underflow condition can occur if we try
to return the top element in an already empty stack.

Algorithm :

PEEK (STACK, TOP)

1. Begin
2. if top = -1 then stack empty
3. item = stack[top]
4. return item
5. End

Time complexity: o(n)

Implementation of Peek algorithm in C language

1. int peek()
2. {
3. if (top == -1)
C NITHISHA – SOCTS0369

4. {
5. printf("Underflow");
6. return 0;
7. }
8. else
9. {
10. return stack [top];
11. }
12. }

Linked list implementation of stack


Instead of using array, we can also use linked list to implement stack.
Linked list allocates the memory dynamically. However, time
complexity in both the scenario is same for all the operations i.e. push,
pop and peek.

In linked list implementation of stack, the nodes are maintained non-


contiguously in the memory. Each node contains a pointer to its
immediate successor node in the stack. Stack is said to be overflown if
the space left in the memory heap is not enough to create a node.
C NITHISHA – SOCTS0369

The top most node in the stack always contains null in its address field.
Lets discuss the way in which, each operation is performed in linked list
implementation of stack.

Adding a node to the stack (Push operation)

Adding a node to the stack is referred to as push operation. Pushing an


element to a stack in linked list implementation is different from that of
an array implementation. In order to push an element onto the stack, the
following steps are involved.

1. Create a node first and allocate memory to it.


2. If the list is empty then the item is to be pushed as the start node of
the list. This includes assigning value to the data part of the node
and assign null to the address part of the node.
3. If there are some nodes in the list already, then we have to add the
new element in the beginning of the list (to not violate the property
of the stack). For this purpose, assign the address of the starting
element to the address field of the new node and make the new
node, the starting node of the list.
C NITHISHA – SOCTS0369

Time Complexity : o(1)

C implementation :

1. void push ()
2. {
3. int val;
4. struct node *ptr =(struct node*)malloc(sizeof(struct node))
;
C NITHISHA – SOCTS0369

5. if(ptr == NULL)
6. {
7. printf("not able to push the element");
8. }
9. else
10. {
11. printf("Enter the value");
12. scanf("%d",&val);
13. if(head==NULL)
14. {
15. ptr->val = val;
16. ptr -> next = NULL;
17. head=ptr;
18. }
19. else
20. {
21. ptr->val = val;
22. ptr->next = head;
23. head=ptr;
24.
25. }
26. printf("Item pushed");
27.
28. }
29. }
C NITHISHA – SOCTS0369

Deleting a node from the stack (POP operation)

Deleting a node from the top of stack is referred to


as pop operation. Deleting a node from the linked list
implementation of stack is different from that in the array
implementation. In order to pop an element from the stack, we
need to follow the following steps :

(i) Check for the underflow condition: The underflow


condition occurs when we try to pop from an already
empty stack. The stack will be empty if the head pointer
of the list points to null.

(ii) Adjust the head pointer accordingly: In stack, the


elements are popped only from one end, therefore, the
value stored in the head pointer must be deleted and the
node must be freed. The next node of the head node
now becomes the head node.

Time Complexity : o(n)

C implementation

1.void pop()
2.{
3. int item;
4. struct node *ptr;
5. if (head == NULL)
6. {
C NITHISHA – SOCTS0369

7. printf("Underflow");
8. }
9. else
10. {
11. item = head->val;
12. ptr = head;
13. head = head->next;
14. free(ptr);
15. printf("Item popped");
16.
17. }
18. }

Display the nodes (Traversing)

Displaying all the nodes of a stack needs traversing all the nodes of
the linked list organized in the form of stack. For this purpose, we
need to follow the following steps.

 Copy the head pointer into a temporary pointer.


 Move the temporary pointer through all the nodes of the list
and print the value field attached to every node.

Time Complexity : o(n)

C Implementation

1.void display()
2.{
C NITHISHA – SOCTS0369

3. int i;
4. struct node *ptr;
5. ptr=head;
6. if(ptr == NULL)
7. {
8. printf("Stack is empty\n");
9. }
10. else
11. {
12. printf("Printing Stack elements \n");
13. while(ptr!=NULL)
14. {
15. printf("%d\n",ptr->val);
16. ptr = ptr->next;
17. }
18. }
19. }
C NITHISHA – SOCTS0369

Queue Data Structure

“A queue can be defined as an ordered list which enables insert


operations to be performed at one end called REAR and delete
operations to be performed at another end called FRONT”.

2. Queue is referred to be as First In First Out list.

3. For example, people waiting in line for a rail ticket form a queue.

Applications of Queue

Due to the fact that queue performs actions on first in first out basis
which is quite fair for the ordering of actions. There are various
applications of queues discussed as below.

1. Queues are widely used as waiting lists for a single shared resource
like printer, disk, CPU.
C NITHISHA – SOCTS0369

2. Queues are used in asynchronous transfer of data (where data is


not being transferred at the same rate between two processes) for
eg. pipes, file IO, sockets.
3. Queues are used as buffers in most of the applications like MP3
media player, CD player, etc.
4. Queue are used to maintain the play list in media players in order
to add and remove the songs from the play-list.
5. Queues are used in operating systems for handling interrupts.

Complexity
C NITHISHA – SOCTS0369

Array representation of Queue


We can easily represent queue by using linear arrays. There are two
variables i.e. front and rear, that are implemented in the case of every
queue. Front and rear variables point to the position from where
insertions and deletions are performed in a queue. Initially, the value of
front and queue is -1 which represents an empty queue. Array
representation of a queue containing 5 elements along with the
respective values of front and rear, is shown in the following figure.

The above figure shows the queue of characters forming the English
word "HELLO". Since, No deletion is performed in the queue till now,
therefore the value of front remains -1 . However, the value of rear
increases by one every time an insertion is performed in the queue. After
inserting an element into the queue shown in the above figure, the queue
will look something like following. The value of rear will become 5
while the value of front remains same.
C NITHISHA – SOCTS0369

After deleting an element, the value of front will increase from -1 to 0.


however, the queue will look something like following.

Algorithm to insert any element in a queue

Check if the queue is already full by comparing rear to max - 1. if so,


then return an overflow error.
C NITHISHA – SOCTS0369

If the item is to be inserted as the first element in the list, in that case set
the value of front and rear to 0 and insert the element at the rear end.

Otherwise keep increasing the value of rear and insert each element one
by one having rear as the index.

Algorithm

Step 1: IF REAR = MAX - 1


Write OVERFLOW
Go to step
[END OF IF]
Step 2: IF FRONT = -1 and REAR = -1
SET FRONT = REAR = 0
ELSE
SET REAR = REAR + 1
[END OF IF]
Step 3: Set QUEUE[REAR] = NUM
Step 4: EXIT

C Function

1. void insert (int queue[], int max, int front, int rear, int item)
2. {
3. if (rear + 1 == max)
C NITHISHA – SOCTS0369

4. {
5. printf("overflow");
6. }
7. else
8. {
9. if(front == -1 && rear == -1)
10. {
11. front = 0;
12. rear = 0;
13. }
14. else
15. {
16. rear = rear + 1;
17. }
18. queue[rear]=item;
19. }
20. }

Algorithm to delete an element from the queue

If, the value of front is -1 or value of front is greater than rear , write an
underflow message and exit.

Otherwise, keep increasing the value of front and return the item stored
at the front end of the queue at each time.

Algorithm

Step 1: IF FRONT = -1 or FRONT > REAR

Write UNDERFLOW

ELSE
C NITHISHA – SOCTS0369

SET VAL = QUEUE[FRONT]


SET FRONT = FRONT + 1
[END OF IF]
Step 2: EXIT

C Function

1. int delete (int queue[], int max, int front, int rear)
2. {
3. int y;
4. if (front == -1 || front > rear)
5.
6. {
7. printf("underflow");
8. }
9. else
10. {
11. y = queue[front];
12. if(front == rear)
13. {
14. front = rear = -1;
15. else
16. front = front + 1;
17.
18. }
19. return y;
20. }
21. }
C NITHISHA – SOCTS0369

Drawback of array implementation

Although, the technique of creating a queue is easy, but there are some
drawbacks of using this technique to implement a queue.

o Memory wastage : The space of the array, which is used to store


queue elements, can never be reused to store the elements of that
queue because the elements can only be inserted at front end and
the value of front might be so high so that, all the space before that,
can never be filled.

The above figure shows how the memory space is wasted in the array
representation of queue. In the above figure, a queue of size 10 having 3
elements, is shown. The value of the front variable is 5, therefore, we
can not reinsert the values in the place of already deleted element before
the position of front. That much space of the array is wasted and can not
be used in the future (for this queue).

o Deciding the array size

On of the most common problem with array implementation is the size


of the array which requires to be declared in advance. Due to the fact
that, the queue can be extended at runtime depending upon the problem,
the extension in the array size is a time taking process and almost
impossible to be performed at runtime since a lot of reallocations take
place. Due to this reason, we can declare the array large enough so that
C NITHISHA – SOCTS0369

we can store queue elements as enough as possible but the main problem
with this declaration is that, most of the array slots (nearly half) can
never be reused. It will again lead to memory wastage.

Linked List implementation of Queue


Due to the drawbacks discussed in the previous section of this tutorial,
the array implementation can not be used for the large scale applications
where the queues are implemented. One of the alternative of array
implementation is linked list implementation of queue. The storage
requirement of linked representation of a queue with n elements is o(n)
while the time requirement for operations is o(1).

In a linked queue, each node of the queue consists of two parts i.e. data
part and the link part. Each element of the queue points to its immediate
next element in the memory.

In the linked queue, there are two pointers maintained in the memory i.e.
front pointer and rear pointer. The front pointer contains the address of
the starting element of the queue while the rear pointer contains the
address of the last element of the queue.

Insertion and deletions are performed at rear and front end respectively.
If front and rear both are NULL, it indicates that the queue is empty.
C NITHISHA – SOCTS0369

Operation on Linked Queue

There are two basic operations which can be implemented on the linked
queues. The operations are Insertion and Deletion.

Insert operation

The insert operation append the queue by adding an element to the end
of the queue. The new element will be the last element of the queue.

Firstly, allocate the memory for the new node ptr by using the following
statement.

Ptr = (struct node *) malloc (sizeof(struct node));

There can be the two scenario of inserting this new node ptr into the
linked queue.

In the first scenario, we insert element into an empty queue. In this case,
the condition front = NULL becomes true. Now, the new element will
be added as the only element of the queue and the next pointer of front
and rear pointer both, will point to NULL.

1. ptr -> data = item;


2. if(front == NULL)
3. {
4. front = ptr;
5. rear = ptr;
6. front -> next = NULL;
7. rear -> next = NULL;
8. }

In the second case, the queue contains more than one element. The
condition front = NULL becomes false. In this scenario, we need to
update the end pointer rear so that the next pointer of rear will point to
the new node ptr. Since, this is a linked queue, hence we also need to
C NITHISHA – SOCTS0369

make the rear pointer point to the newly added node ptr. We also need
to make the next pointer of rear point to NULL.

1. rear -> next = ptr;


2. rear = ptr;
3. rear->next = NULL;

In this way, the element is inserted into the queue. The algorithm and the
C implementation is given as follows.

Algorithm

o Step 1: Allocate the space for the new node PTR


o Step 2: SET PTR -> DATA = VAL
o Step3: IF FRONT = NULL
o SET FRONT = REAR = PTR
o SET FRONT -> NEXT = REAR -> NEXT = NULL
o ELSE
o SET REAR -> NEXT = PTR
o SET REAR = PTR
o SET REAR -> NEXT = NULL
o [END OF IF]
o Step 4: END

C Function

1. void insert(struct node *ptr, int item; )


2. {
3.
4.
C NITHISHA – SOCTS0369

5. ptr = (struct node *) malloc (sizeof(struct node));


6. if(ptr == NULL)
7. {
8. printf("\nOVERFLOW\n");
9. return;
10. }
11. else
12. {
13. ptr -> data = item;
14. if(front == NULL)
15. {
16. front = ptr;
17. rear = ptr;
18. front -> next = NULL;
19. rear -> next = NULL;
20. }
21. else
22. {
23. rear -> next = ptr;
24. rear = ptr;
25. rear->next = NULL;
26. }
27. }
28. }

Deletion

Deletion operation removes the element that is first inserted among all
the queue elements. Firstly, we need to check either the list is empty or
not. The condition front == NULL becomes true if the list is empty, in
this case , we simply write underflow on the console and make exit.
C NITHISHA – SOCTS0369

Otherwise, we will delete the element that is pointed by the pointer


front. For this purpose, copy the node pointed by the front pointer into
the pointer ptr. Now, shift the front pointer, point to its next node and
free the node pointed by the node ptr. This is done by using the
following statements.

1. ptr = front;
2. front = front -> next;
3. free(ptr);

The algorithm and C function is given as follows.

Algorithm
o Step 1: IF FRONT = NULL
o Write " Underflow "
o Go to Step 5
o [END OF IF]
o Step 2: SET PTR = FRONT
o Step 3: SET FRONT = FRONT -> NEXT
o Step 4: FREE PTR
o Step 5: END

C Function

1. void delete (struct node *ptr)


2. {
3. if(front == NULL)
4. {
5. printf("\nUNDERFLOW\n");
6. return;
7. }
C NITHISHA – SOCTS0369

8. else
9. {
10. ptr = front;
11. front = front -> next;
12. free(ptr);
13. }
14. }
C NITHISHA – SOCTS0369

Circular Queue
Why was the concept of the circular queue introduced?

There was one limitation in the array implementation of Queue. If the


rear reaches to the end position of the Queue then there might be
possibility that some vacant spaces are left in the beginning which
cannot be utilized. So, to overcome such limitations, the concept of the
circular queue was introduced.

As we can see in the above image, the rear is at the last position of the
Queue and front is pointing somewhere rather than the 0 th position. In
the above array, there are only two elements and other three positions
are empty. The rear is at the last position of the Queue; if we try to insert
the element then it will show that there are no empty spaces in the
Queue. There is one solution to avoid such wastage of memory space by
shifting both the elements at the left and adjust the front and rear end
accordingly. It is not a practically good approach because shifting all the
C NITHISHA – SOCTS0369

elements will consume lots of time. The efficient approach to avoid the
wastage of the memory is to use the circular queue data structure.

What is a Circular Queue?

A circular queue is similar to a linear queue as it is also based on the


FIFO (First In First Out) principle except that the last position is
connected to the first position in a circular queue that forms a circle. It is
also known as a Ring Buffer.

Operations on Circular Queue

The following are the operations that can be performed on a circular


queue:

o Front: It is used to get the front element from the Queue.


o Rear: It is used to get the rear element from the Queue.
o enQueue(value): This function is used to insert the new value in
the Queue. The new element is always inserted from the rear end.
o deQueue(): This function deletes an element from the Queue. The
deletion in a Queue always takes place from the front end.

Applications of Circular Queue

The circular Queue can be used in the following scenarios:

o Memory management: The circular queue provides memory


management. As we have already seen that in linear queue, the
memory is not managed very efficiently. But in case of a circular
queue, the memory is managed efficiently by placing the elements
in a location which is unused.
o CPU Scheduling: The operating system also uses the circular
queue to insert the processes and then execute them.
C NITHISHA – SOCTS0369

o Traffic system: In a computer-control traffic system, traffic light


is one of the best examples of the circular queue. Each light of
traffic light gets ON one by one after every jinterval of time. Like
red light gets ON for one minute then yellow light for one minute
and then green light. After green light, the red light gets ON.

Enqueue operation

The steps of enqueue operation are given below:

o First, we will check whether the Queue is full or not.


o Initially the front and rear are set to -1. When we insert the first
element in a Queue, front and rear both are set to 0.
o When we insert a new element, the rear gets incremented,
i.e., rear=rear+1.

Scenarios for inserting an element

There are two scenarios in which queue is not full:

o If rear != max - 1, then rear will be incremented


to mod(maxsize) and the new value will be inserted at the rear end
of the queue.
o If front != 0 and rear = max - 1, it means that queue is not full,
then set the value of rear to 0 and insert the new element there.

There are two cases in which the element cannot be inserted:

o When front ==0 && rear = max-1, which means that front is at
the first position of the Queue and rear is at the last position of the
Queue.
o front== rear + 1;
C NITHISHA – SOCTS0369

Algorithm to insert an element in a circular queue

Step 1: IF (REAR+1)%MAX = FRONT


Write " OVERFLOW "
Goto step 4
[End OF IF]
Step 2: IF FRONT = -1 and REAR = -1
SET FRONT = REAR = 0
ELSE IF REAR = MAX - 1 and FRONT ! = 0
SET REAR = 0
ELSE
SET REAR = (REAR + 1) % MAX
[END OF IF]
Step 3: SET QUEUE[REAR] = VAL
Step 4: EXIT

Dequeue Operation

The steps of dequeue operation are given below:

o First, we check whether the Queue is empty or not. If the queue is


empty, we cannot perform the dequeue operation.
C NITHISHA – SOCTS0369

o When the element is deleted, the value of front gets decremented


by 1.
o If there is only one element left which is to be deleted, then the
front and rear are reset to -1.

Algorithm to delete an element from the circular queue

Step 1: IF FRONT = -1
Write " UNDERFLOW "
Goto Step 4
[END of IF]
Step 2: SET VAL = QUEUE[FRONT]
Step 3: IF FRONT = REAR
SET FRONT = REAR = -1
ELSE
IF FRONT = MAX -1
SET FRONT = 0
ELSE
SET FRONT = FRONT + 1
[END of IF]
[END OF IF]
Step 4: EXIT
C NITHISHA – SOCTS0369

Let's understand the enqueue and dequeue operation through the


diagrammatic representation:
C NITHISHA – SOCTS0369
C NITHISHA – SOCTS0369

Implementation of circular queue using linked list

As we know that linked list is a linear data structure that stores two
parts, i.e., data part and the address part where address part contains the
address of the next node. Here, linked list is used to implement the
circular queue; therefore, the linked list follows the properties of the
Queue. When we are implementing the circular queue using linked list
then both the enqueue and dequeue operations take O(1) time.
C NITHISHA – SOCTS0369

Deque (or double-ended queue)


What is a queue?

A queue is a data structure in which whatever comes first will go out


first, and it follows the FIFO (First-In-First-Out) policy. Insertion in the
queue is done from one end known as the rear end or the tail, whereas
the deletion is done from another end known as the front end or
the head of the queue.

The real-world example of a queue is the ticket queue outside a cinema


hall, where the person who enters first in the queue gets the ticket first,
and the person enters last in the queue gets the ticket at last.

What is a Deque (or double-ended queue)?

The deque stands for Double Ended Queue. Deque is a linear data
structure where the insertion and deletion operations are performed from
both ends. We can say that deque is a generalized version of the queue.

Though the insertion and deletion in a deque can be performed on both


ends, it does not follow the FIFO rule. The representation of a deque is
given as follows -

Types of deque

There are two types of deque -

o Input restricted queue


o Output restricted queue
C NITHISHA – SOCTS0369

Input restricted Queue

In input restricted queue, insertion operation can be performed at only


one end, while deletion can be performed from both ends.

Output restricted Queue

In output restricted queue, deletion operation can be performed at only


one end, while insertion can be performed from both ends.

Operations performed on deque

There are the following operations that can be applied on a deque -

o Insertion at front
o Insertion at rear
o Deletion at front
o Deletion at rear
C NITHISHA – SOCTS0369

We can also perform peek operations in the deque along with the
operations listed above. Through peek operation, we can get the deque's
front and rear elements of the deque. So, in addition to the above
operations, following operations are also supported in deque -

o Get the front item from the deque


o Get the rear item from the deque
o Check whether the deque is full or not
o Checks whether the deque is empty or not

Now, let's understand the operation performed on deque using an


example.

Insertion at the front end

In this operation, the element is inserted from the front end of the queue.
Before implementing the operation, we first have to check whether the
queue is full or not. If the queue is not full, then the element can be
inserted from the front end by using the below conditions -

o If the queue is empty, both rear and front are initialized with 0.
Now, both will point to the first element.
o Otherwise, check the position of the front if the front is less than 1
(front < 1), then reinitialize it by front = n - 1, i.e., the last index of
the array.
C NITHISHA – SOCTS0369

Insertion at the rear end

In this operation, the element is inserted from the rear end of the queue.
Before implementing the operation, we first have to check again whether
the queue is full or not. If the queue is not full, then the element can be
inserted from the rear end by using the below conditions –

o If the queue is empty, both rear and front are initialized with 0.
Now, both will point to the first element.
o Otherwise, increment the rear by 1. If the rear is at last index (or
size - 1), then instead of increasing it by 1, we have to make it
equal to 0.
C NITHISHA – SOCTS0369

Deletion at the front end

In this operation, the element is deleted from the front end of the queue.
Before implementing the operation, we first have to check whether the
queue is empty or not.

If the queue is empty, i.e., front = -1, it is the underflow condition, and
we cannot perform the deletion. If the queue is not full, then the element
can be inserted from the front end by using the below conditions -

If the deque has only one element, set rear = -1 and front = -1.

Else if front is at end (that means front = size - 1), set front = 0.

Else increment the front by 1, (i.e., front = front + 1).


C NITHISHA – SOCTS0369

Deletion at the rear end

In this operation, the element is deleted from the rear end of the queue.
Before implementing the operation, we first have to check whether the
queue is empty or not.

If the queue is empty, i.e., front = -1, it is the underflow condition, and
we cannot perform the deletion.

If the deque has only one element, set rear = -1 and front = -1.

If rear = 0 (rear is at front), then set rear = n - 1.

Else, decrement the rear by 1 (or, rear = rear -1).


C NITHISHA – SOCTS0369

Check empty

This operation is performed to check whether the deque is empty or not.


If front = -1, it means that the deque is empty.

Check full

This operation is performed to check whether the deque is full or not. If


front = rear + 1, or front = 0 and rear = n - 1 it means that the deque is
full.

The time complexity of all of the above operations of the deque is O(1),
i.e., constant.

Applications of deque
o Deque can be used as both stack and queue, as it supports both
operations.
o Deque can be used as a palindrome checker means that if we read
the string from both ends, the string would be the same.
C NITHISHA – SOCTS0369

Priority Queue
What is a priority queue?

A priority queue is an abstract data type that behaves similarly to the


normal queue except that each element has some priority, i.e., the
element with the highest priority would come first in a priority queue.
The priority of the elements in a priority queue will determine the order
in which elements are removed from the priority queue.

The priority queue supports only comparable elements, which means


that the elements are either arranged in an ascending or descending
order.

For example, suppose we have some values like 1, 3, 4, 8, 14, 22


inserted in a priority queue with an ordering imposed on the values is
from least to the greatest. Therefore, the 1 number would be having the
highest priority while 22 will be having the lowest priority.

Characteristics of a Priority queue

A priority queue is an extension of a queue that contains the following


characteristics:

o Every element in a priority queue has some priority associated with


it.
o An element with the higher priority will be deleted before the
deletion of the lesser priority.
o If two elements in a priority queue have the same priority, they
will be arranged using the FIFO principle.

Let's understand the priority queue through an example.

We have a priority queue that contains the following values:

1, 3, 4, 8, 14, 22
C NITHISHA – SOCTS0369

All the values are arranged in ascending order. Now, we will observe
how the priority queue will look after performing the following
operations:

o poll(): This function will remove the highest priority element from
the priority queue. In the above priority queue, the '1' element has
the highest priority, so it will be removed from the priority queue.
o add(2): This function will insert '2' element in a priority queue. As
2 is the smallest element among all the numbers so it will obtain
the highest priority.
o poll(): It will remove '2' element from the priority queue as it has
the highest priority queue.
o add(5): It will insert 5 element after 4 as 5 is larger than 4 and
lesser than 8, so it will obtain the third highest priority in a priority
queue.

Types of Priority Queue


There are two types of priority queue:

o Ascending order priority queue: In ascending order priority


queue, a lower priority number is given as a higher priority in a
priority. For example, we take the numbers from 1 to 5 arranged in
an ascending order like 1,2,3,4,5; therefore, the smallest number,
C NITHISHA – SOCTS0369

i.e., 1 is given as the highest priority in a priority queue.

o Descending order priority queue: In descending order priority


queue, a higher priority number is given as a higher priority in a
priority. For example, we take the numbers from 1 to 5 arranged in
descending order like 5, 4, 3, 2, 1; therefore, the largest number,
i.e., 5 is given as the highest priority in a priority queue.
C NITHISHA – SOCTS0369

Representation of priority queue

Now, we will see how to represent the priority queue through a one-way
list.

We will create the priority queue by using the list given below in
which INFO list contains the data elements, PRN list contains the
priority numbers of each data element available in the INFO list, and
LINK basically contains the address of the next node.

Let's create the priority queue step by step.

In the case of priority queue, lower priority number is considered


the higher priority, i.e., lower priority number = higher priority.

Step 1: In the list, lower priority number is 1, whose data value is 333,
so it will be inserted in the list as shown in the below diagram:

Step 2: After inserting 333, priority number 2 is having a higher


priority, and data values associated with this priority are 222 and 111.
C NITHISHA – SOCTS0369

So, this data will be inserted based on the FIFO principle; therefore 222
will be added first and then 111.

Step 3: After inserting the elements of priority 2, the next higher priority
number is 4 and data elements associated with 4 priority numbers are
444, 555, 777. In this case, elements would be inserted based on the
FIFO principle; therefore, 444 will be added first, then 555, and then
777.

Step 4: After inserting the elements of priority 4, the next higher priority
number is 5, and the value associated with priority 5 is 666, so it will be
inserted at the end of the queue.

Implementation of Priority Queue

The priority queue can be implemented in four ways that include arrays,
linked list, heap data structure and binary search tree. The heap data
structure is the most efficient way of implementing the priority queue, so
we will implement the priority queue using a heap data structure in this
topic. Now, first we understand the reason why heap is the most efficient
way among all the other data structures.

Analysis of complexities using different implementations

Implementation add Remove peek

Linked list O(1) O(n) O(n)

Binary heap O(logn) O(logn) O(1)


C NITHISHA – SOCTS0369

Binary search tree O(logn) O(logn) O(1)

What is Heap?

A heap is a tree-based data structure that forms a complete binary tree,


and satisfies the heap property. If A is a parent node of B, then A is
ordered with respect to the node B for all nodes A and B in a heap. It
means that the value of the parent node could be more than or equal to
the value of the child node, or the value of the parent node could be less
than or equal to the value of the child node. Therefore, we can say that
there are two types of heaps:

o Max heap: The max heap is a heap in which the value of the
parent node is greater than the value of the child nodes.
C NITHISHA – SOCTS0369

o Min heap: The min heap is a heap in which the value of the parent
node is less than the value of the child nodes.

Both the heaps are the binary heap, as each has exactly two child nodes.

Priority Queue Operations

The common operations that we can perform on a priority queue are


insertion, deletion and peek. Let's see how we can maintain the heap
data structure.

o Inserting the element in a priority queue (max heap)

If we insert an element in a priority queue, it will move to the empty slot


by looking from top to bottom and left to right.

If the element is not in a correct place then it is compared with the parent
node; if it is found out of order, elements are swapped. This process
continues until the element is placed in a correct position.
C NITHISHA – SOCTS0369

o Removing the minimum element from the priority queue

As we know that in a max heap, the maximum element is the root node.
When we remove the root node, it creates an empty slot. The last
inserted element will be added in this empty slot. Then, this element is
compared with the child nodes, i.e., left-child and right child, and swap
C NITHISHA – SOCTS0369

with the smaller of the two. It keeps moving down the tree until the heap
property is restored.

Applications of Priority queue

The following are the applications of the priority queue:

o It is used in the Dijkstra's shortest path algorithm.


o It is used in prim's algorithm
o It is used in data compression techniques like Huffman code.
o It is used in heap sort.
o It is also used in operating system like priority scheduling, load
balancing and interrupt handling.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy