Lecture 4 Stack and Queues
Lecture 4 Stack and Queues
Lecture 4 Stack and Queues
Stack is an abstract data type with a bounded (predefined) capacity. It is a simple data structure
that allows adding and removing elements in a particular order. Every time an element is added,
it goes on the top of the stack and the only element that can be removed is the element that is at
the top of the stack, just like a pile of objects.
Applications of Stack
The simplest application of a stack is to reverse a word. You push a given word to stack - letter
by letter - and then pop letters from the stack.
There are other uses also like:
1. Parsing
2. Expression Conversion(Infix to Postfix, Postfix to Prefix etc)
Implementation of Stack Data Structure
Stack can be easily implemented using an Array or a Linked List. Arrays are quick, but are
limited in size and Linked List requires overhead to allocate, link, unlink, and deallocate, but is
not limited in size. Here we will implement Stack using array.
Below we have a simple C++ program implementing stack data structure while following the
object oriented programming concepts.
/* Below program is written in C++ language */
# include<iostream>
// main function
int main() {
Stack s1;
s1.push(10);
s1.push(100);
/*
preform whatever operation you want on the stack
*/
}
1. Like stack, queue is also an ordered list of elements of similar data types.
2. Queue is a FIFO( First in First Out ) structure.
3. Once a new element is inserted into the Queue, all the elements inserted before the new
element in the queue must be removed, to remove the new element.
4. peek( ) function is oftenly used to return the value of first element without dequeuing it.
Applications of Queue
Queue, as the name suggests is used whenever we need to manage any group of objects in an
order in which the first one coming in, also gets out first while the others wait for their turn, like
in the following scenarios:
1. Serving requests on a single shared resource, like a printer, CPU task scheduling etc.
2. In real life scenario, Call Center phone systems uses Queues to hold people calling them
in an order, until a service representative is free.
3. Handling of interrupts in real-time systems. The interrupts are handled in the same order
as they arrive i.e First come first served.
#include<iostream>
using namespace std;
#define SIZE 10
class Queue
{
int a[SIZE];
int rear; //same as tail
int front; //same as head
public:
Queue()
{
rear = front = -1;
}
Enqueue: O(1)
Dequeue: O(1)
Size: O(1)
When we dequeue any element to remove it from the queue, we are actually moving the front of
the queue forward, thereby reducing the overall size of the queue. And we cannot insert new
elements, because the rear pointer is still at the end of the queue.
The only way is to reset the linear queue, for a fresh start.
Circular Queue is also a linear data structure, which follows the principle of FIFO(First In First
Out), but instead of ending the queue at the last position, it again starts from the first position
after the last, hence making the queue behave like a circular data structure.
1. In case of a circular queue, head pointer will always point to the front of the queue,
and tail pointer will always point to the end of the queue.
2. Initially, the head and the tail pointers will be pointing to the same location, this would
mean that the queue is empty.
3. New data is always added to the location pointed by the tail pointer, and once the data is
added, tail pointer is incremented to point to the next available location.
4. In a circular queue, data is not actually removed from the queue. Only the head pointer is
incremented by one position when dequeue is executed. As the queue data is only the
data between head and tail, hence the data left outside is not a part of the queue anymore,
hence removed.
5. The head and the tail pointer will get reinitialised to 0 every time they reach the end of
the queue.
6. Also, the head and the tail pointers can cross each other. In other words, head pointer can
be greater than the tail. Sounds odd? This will happen when we dequeue the queue a
couple of times and the tail pointer gets reinitialised upon reaching the end of the queue.
#include<iostream>
#define SIZE 10
class CircularQueue
{
int a[SIZE];
int rear; //same as tail
int front; //same as head
public:
CircularQueue()
{
rear = front = -1;
}
if(isEmpty())
{
cout << "Queue is empty" << endl;
}
else
{
y = a[front];
if(front == rear)
{
// only one element in queue, reset queue after removal
front = -1;
rear = -1;
}
else
{
front = (front+1) % SIZE;
}
return(y);
}
}
cq.display();
return 0;
}