Queue
Queue
Unit II
Queue
► Queue is an abstract data structure, 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 (FIFO) methodology, i.e., the data item stored first will be
accessed first. front end is use for deletion and rear end is used for insertion.
► A real-world example of queue can be a single-lane one-way road, where the vehicle
enters first, exits first.
Queue Representation
Representation of 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.
► This function helps to see the data at the front of the queue. The algorithm of peek()
function is as follows −
► Algorithm
► int peek()
► {
► return queue[front]
► }
isfull()
bool isfull()
if(rear==size)
return true;
else
return false
}
isempty()
► bool isempty()
► {
► if(front==0||rear==0)
► return true;
► else
► return false;
► }
Enqueue Operation
► O(1)
Dequeue Operation
► int dequeue(Q)
► {
► int item;
► if(front==0)
► print Q is empty and exit;
► else if(front==rear)
► item=Q[front];
► front=0;
► rear=0;
► else
► item=Q[front];
► front=front+1;
► }
O(1)
► Consider the following queue:
► Q: 10,9,15 front= 3, rear=5, size=6;
10
► Perform the following operations over Q
► Enqueue(Q,10),Enqueue(Q,11),Dequeue(Q),Dequeue(),Dequeue(),Dequeue(),
dequeue(Q),enqueue(Q,10)
► Enqueue(Q,10): if(5==6)F, if(3==0)F,rear=5+1=6,Q[6]=10
► Enqueue(Q,11): if(6==6)T : Q is full.
► Dequeue(Q):if(3==0)F,if(3==6)F,item=10, front=3+1=4
► Dequeue(): if(4==0)F, if(4==6)F,item=9,front=4+1=5
► Dequeue():if(5==0)F,if(5==6)F,item=15,front=5+1=6
► Dequeue(): if(6==0)F, if(6==6)T,item=10,front=0,rear=0;
► Dequeue():if(0==0)T Q is empty.
► enqueue(Q,10): if(0==6)F, if(0==0)T, front=0+1=1,rear=0+1=1, Q[1]=10
Linked List implementation of Queue
► struct Q{
► int data,
► struct Q *next;
► }*rear=NULL,*front=NULL;
► 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. It is also called ‘Ring Buffer’. To overcome the disadvantage
of simple queue.
► In a normal Queue, we can insert elements until queue becomes full. But once queue
becomes full, we can not insert the next element even if there is a space in front of
queue.
Operations on Circular Queue:
∙ This function is used to insert an element into the circular queue. In a circular queue, the new element is always inserted at Rear position.
∙ { if((rear+1)%size==front)
∙ Q is full.
∙ else if(rear==-1)
∙ front=rear=0;
∙ Q[rear]=item;
∙ else
∙ rear=(rear+1)%size;
∙ Q[rear]=item;
∙ }
deQueue()
► This function is used to delete an element from the circular queue. In a circular queue, the element is
always deleted from front position.
► Int Dequeue(Q)
► { if(front==-1)
► Q is empty.
► else if(front==rear)
► item=Q[front];
► front=rear=-1;
► else
► item=Q[front];
► front=(front+1)%size;
► return item;
► }
► Consider circular queue with F=2,R=5 item= 9,10,1,-2
9 5 4 -10 1 -2
► Perform the following sequence of operations on the queue:
► Dequeue(Q): if(2==-1)F,if(2==5)F, item=9, F=3%6=3, R=5
► Dequeue(Q): if(3==-1)F, if(3==5)F, item=10, F=4%6=4, R=5
► Enqueue(Q,9): if(0==4)F, if(5==-1)F, R=6%6=0, Q[0]=9, F=4
► Enqueue(Q,5): if(1==4)F,if(1==-1)F, R=1%6=1,Q[1]=5, F=4
► Enqueue(Q,4): if(2==4)F, if(1==-1)F, R=2%6=2,Q[2]=4
► Enqueue(Q,-10):if(3==4)F,if(2==-1)F,R=3%6=3,Q[3]=-10
► Enqueue(Q,1): if(4%6==4)T, Q is Full. F=4,R=3
LL implementation
► Struct Q{
► int data;
► struct Q*next;
► }*front=NULL,*rear=NULL; node
► void enqueue(Q, int item) 10 1024 1 2055
► {node=(struct Q)malloc(sizeof(struct Q*)); 2
► node->data=item;
► node->next=NULL; 1 N
► if(rear==NULL) 3
► front=node;
► rear=node;
► rear->next=front;
► else
► rear->next=node;
► rear=node;
► rear->next=front;
► }
► Dequeue(Q)
► {
► if(front==NULL)
► Q is empty.
► If else(front==rear)
► temp=front;
► front=rear=NULL;
► free(temp);
► else
► temp=front;
► front=front->next;
► rear->next=front;
► free(temp);
► }
DeQueue: Doubly Ended Queue
► The word deque is short form of double ended queue. In a dequeue, insertion as well as
deletion can be carried out either at the rear end or the front end.
► Implementation of Dequeue can be done through circular array or circular LL.
Operations on Deque:
►
Mainly the following four basic operations are performed on queue:
insertFront(): Adds an item at the front of Deque.
insertRear(): Adds an item at the rear of Deque.
deleteFront(): Deletes an item from front of Deque.
deleteRear(): Deletes an item from rear of Deque.
► For implementing deque, we need to keep track of two indices, front and rear. We
enqueue(push) an item at the rear or the front end of qedue and dequeue(pop) an item
from both rear and front end.
Insert Elements at Rear end
► void Insertatrear(Q,int item)
∙ {
∙ if((rear+1)%size==front)
∙ Q is full.
∙ else if(rear==-1)
∙ front=rear=0;
∙ Q[rear]=item;
∙ else
∙ rear=(rear+1)%size
∙ Q[rear]=item;
► }
Insert Elements at Front end
► void Insertatfront(Q,int item)
► { F R
► if((rear+1)%size==front)
► Q is FULL.
► else if(front==-1)
► front=front+1;
► rear=rear+1;
► Q[front]=item;
► else
► front=(front+size-1)%size;
► Q[front]=item;
► }
Delete Element From Front end
► Int deletefromfront(Q)
► {
► if(front==-1)
► then Q is empty.
► else if(front==rear)
► item=Q[front]
► front=rear=-1;
► else
► item=Q[front];
► front= (front+1)%size;
► return item;
► }
Delete Element From rear end
► Int Deletefromrear(Q)
► {
► if(rear==-1)
► Q is empty.
► else if(front==rear)
► item=Q[rear];
► front=rear=-1;
► else
► item=Q[rear];
► rear=(rear+size-1)%size;
► }
LL implementation of Dequeue
► Note: we cant use circular singly LL in Dequeue because in that LL we can not move from first node to last node directly.
Thatswhy circular doubly LL will be used.
► insertatrear(Q,int item)
► {
► node=(struct Q)malloc(sizeof(struct Q*))
► node->data=item;
► node->next=NULL;
► node->prev=NULL;
► if(rear==NULL)
► rear=front=node;
► rear->next=node;
► front->prev=node;
► else
► rear->next=node;
► node->prev=rear;
► rear=node;
► rear->next=front;
► front->prev=rear;
► }
► insertatfront(Q, int item)
► {node=(struct Q)malloc(sizeof(struct Q*))
► node->data=item;
► node->next=NULL;
► node->prev=NULL;
► if(front==NULL)
► rear=front=node;
► rear->next=node;
► front->prev=node;
► else
► front->prev=node;
► node->next=front;
► front=node;
► front->prev=rear;
► rear->next=front;
► }
► deletefromfront(Q)
► {temp=front;
► if(front==NULL)
► Q is empty.
► else if(front==rear)
► front=rear=NULL;
► free(temp);
► else
► front=front->next;
► free(temp);
► front->prev=rear;
► rear->next=front;
► }
► Deletefromrear(Q)
► {temp=rear;
► if(rear==NULL)
► Q is empty.
► else if(front==rear)
► front=rear=NULL;
► free(temp);
► else
► rear=rear->prev;
► front->prev=rear;
► rear->next=front;
► free(temp);
► }
Variation of Deque:
► Input Restricted Dequeue: In this queue insertion can be done only from rear
end while deletion can be done at both the ends.
► insertatrear(), deletefromfront(),deletefromrear().
► Output Restricted Dequeue: In this queue deletion can be done only from
front end while insertion can be done at both the ends.
► deletefromfront(), insertatrear(),insertatfront().
Priority Queue
► Priority Queue is an extension of queue with following properties.
► An element with high priority is dequeued before an element with low priority.
► If two elements have the same priority, they are served according to their order in the
queue.
► A typical priority queue supports following operations.
insert(item, priority): Inserts an item with given priority.
getHighestPriority(): Returns the highest priority item.
deleteHighestPriority(): Removes the highest priority item.