Queue •Queue: –Like any other data structure (apart from Array and Linked List), •Queue also can be implemented, –Either as an Array or, –As a Linked List. –So it does not have any physical identity/existence of its own, however, •It has its own logical identity/existence because, –It handles the data in its own unique way. Queue Examples Waiting register in a cyber café. Process synchronization in a multi-user environment. Queue in front of a counter. Type: FIFO: First In First Out LILO: Last In Last Out Queue of vehicles. Queue Working Enqueue Front Dequeue Insert an element 30 10 20 30 10 20 Rear Delete an element 30 Delete an element 10 Delete an element 20 Queue •Queue: –Queue is, •A collection of homogeneous data elements where, –Insertion and Deletion operations take place at, –Two different (extreme) ends. •Hence it is also called: –FIFO: First In First Out. –LILO: Last In Last Out. –Insertion operation is called: •Enqueue and is normally done at, –‘Rear’ end of the Queue. –Deletion operation is called: •Dequeue and is normally done at, –‘Front’ end of the Queue. Queue •Representation of Queue: –Can be represented in 2 ways in memory: •Using an Array: –Gets all the properties (advantages/disadvantages) of Array. •Using a Linked List: –Gets all the properties (advantages/disadvantages) of Linked List. Queue Implemented using an Array Enqueue (Insert an element) 30 10 20 60 40 50 30 10 1 2 20 60 40 3 4 Array A 5 Queue is Full Dequeue (Delete an element) 30 Dequeue (Delete an element) 10 Dequeue (Delete an element) 20 Dequeue (Delete an element) 60 Dequeue (Delete an element) 40 Dequeue (Delete an element) Queue is Empty Queue Implemented using a Linked List Enqueue (Insert an element) 30 10 20 Queue_Head 30 NULL 10 NULL NULL NULL 20 1st Solution: Enqueue: Insert_End Dequeue: Delete_Front NULL 2nd Solution: Dequeue 30 Dequeue 10 Enqueue: Insert_Front Dequeue: Delete_End Dequeue 20 Dequeue Queue is Empty Queue Implemented using an Array Enqueue (Insert an element) 30 10 1 2 20 60 40 3 4 Array A 5 30 10 20 60 40 Dequeue Dequeue Dequeue Dequeue Dequeue Conclusion: Logic of Enqueue/Dequeue is working however, It is highly inefficient to find out position every time by, scanning/looking the entire array. 30 10 20 60 40 Queue implemented using Array Steps: Enqueue Item If(Rear >= 5) 30 10 20 60 40 50 print “Queue is full. Enqueue not possible.” 30 10 20 60 40 Front = Front + 1 1 2 3 4 5 Rear = Rear + 1 R Else Rear = Rear + 1 R F R R R EndIf Dequeue L Else If(Front < 1) AND (Rear < 1) Array A Front = 0 Rear = 0 U A[Rear] = 30 Item EndIf Queue implemented using Array Steps: Item = NULL If(Front < 1) Array A Front = 0 Rear = 0 30 10 20 60 1 2 3 4 F F F R F Dequeue 30 Dequeue 10 Dequeue 20 Dequeue 60 Dequeue Queue is empty. Dequeue not possible. L print “Queue is empty. Dequeue not possible.” 5 Else Item = A[Front] // 30102060 A[Front] = NULL If(Front == Rear) Front = 0 L-1 Rear = 0 Else Front = Front + 1 EndIf EndIf Return(Item) Queue implemented using Array Dequeue Enqueue Steps: Steps: If(Rear >= U) print “Queue is Full. Enqueue not possible.” Else Item = NULL If(Front < L) print “Queue is Empty. Dequeue not possible.” Else Item = A[Front] A[Front] = NULL Full/Empty If(Front < L) AND (Rear < L) Exception Front = Front + 1 First Element Rear = Rear + 1 / Else Last Element Rear = Rear + 1 EndIf Normal Case A[Rear] = Item EndIf Stop If(Front == Rear) Front = L-1 Rear = L-1 Else Front = Front + 1 EndIf EndIf Return(Item) Stop Queue implemented using Array •Algorithm: –Enqueue •Input: –Item: Data to be enqueued / inserted in the Queue. –Front: Pointer to the front end of the Queue. –Rear: Pointer to the rear end of the Queue. •Output: –Item inserted at Rear end of the Queue if successful, message otherwise. •Data Structure: –Queue implemented using array A[L…U] with Front and Rear pointers. Algorithm: Enqueue Steps: If(Rear >= U) print “Queue is Full. Enqueue not possible.” Else If(Front < L) AND (Rear < L) Front = Front + 1 Rear = Rear + 1 Else Rear = Rear + 1 EndIf A[Rear] = Item EndIf Stop Queue implemented using Array •Algorithm: –Dequeue •Input: –Front: Pointer to the front end of the Queue. –Rear: Pointer to the rear end of the Queue. •Output: –Item: Data dequeued/deleted from the Queue if successful, message otherwise. •Data Structure: –Queue implemented using array A[L…U] with Front and Rear pointers. Algorithm: Dequeue Steps: Item = NULL If(Front < L) print “Queue is Empty. Dequeue not possible.” Else Item = A[Front] A[Front] = NULL If(Front == Rear) Front = L-1 Rear = L-1 Else Front = Front + 1 EndIf EndIf Return(Item) Stop Tracing of Enqueue & Dequeue Array A Front = -1 Rear = -1 0 1 2 3 Trace the following steps for the above Queue of Length/Size 4. 1) Dequeue() 2) Enqueue(35) 3) Dequeue() 4) Enqueue(25) 5) Enqueue(45) 6) Enqueue(75) 7) Enqueue(65) 8) Enqueue(85) 9) Dequeue() 10)Enqueue(55) Problem Array A Tracing of Enqueue & Dequeue Enqueue: Dequeue: 15 35 1 F 2 R 3 Enqueue(25) Item = NULL If(Front < L) If(Rear >= U) print “Queue is Empty. print “Queue is Full. Dequeue not possible.” Enqueue not possible.” Else Else Item = A[Front] A[Front] = NULL If(Front < L) AND (Rear < L) Front = Front + 1 If(Front == Rear) Rear = Rear + 1 Front = L-1 Else Rear = L-1 Rear = Rear + 1 Else EndIf Front = Front + 1 EndIf A[Rear] = Item EndIf Return(Item) EndIf Stop Stop 15 35 25 1 F 2 3 R Dequeue() 35 25 2 F 3 R Enqueue(45) 35 25 2 3 R F Queue is full. Queue implemented using Array Problem / Disadvantage Dequeue() 35 Dequeue() 55 Enqueue(65) Array A Enqueue(85): 35 55 45 45 55 25 45 65 25 25 65 1 2 3 4 5 F F R F R R Queue is Full. Enqueue not possible. Dynamic Queue, however, Both solutions require shifting of elements and hence inefficient. Solutions: 1) Change/Rewrite ‘Enqueue’ algorithm to shift the elements in case ‘Front’ is not at the starting of the Queue. 2) Change/Rewrite ‘Dequeue’ algorithm to shift all the elements as soon as one element is deleted from the Queue. 3) Implement the Queue using a Linked List. Queue Circular Queue Array A Enqueue(65) Enqueue(85): Queue is Full. Enqueue not possible. Dequeue() 35 35 85 55 75 45 25 65 1 2 3 4 5 FR R F F F R R F Dequeue() 55 Enqueue(85) Enqueue(75) Enqueue(15) Dequeue() 45 Queue is Full. Enqueue not possible. 1 5 85 65 4 25 75 Dequeue() 25 Dequeue() 65 45 F 3 2 R Normal Queue v/s Circular Queue Steps: Conditions: Enqueue: First element (Exception). Enqueue: Queue is Full. Enqueue: Any other element (Normal). Dequeue: Last element (Exception). Dequeue: Queue is Empty. Dequeue: Any other element (Normal). Enqueue(35) Enqueue(35) Enqueue(65) Enqueue(55) Dequeue() Dequeue() Enqueue(45) Enqueue(25) Enqueue(65) Dequeue() Dequeue() Dequeue() Dequeue() Normal Queue F=0 35 R=0 55 45 25 1 2 3 4 FR FR FR FR Circular Queue F=0 35 R=0 55 45 25 1 2 3 4 FR FR FR FR Normal Queue ENQUEUE Circular Queue Steps: Steps: If(Rear >= U) print “Queue is Full. Enqueue not possible.” If(Rear == U) next = L Else next = Rear + 1 EndIf Else If(Front < L) AND (Rear < L) Front = Front + 1 Rear = Rear + 1 Else Rear = Rear + 1 EndIf A[Rear] = Item EndIf If(next == Front) print “Queue is Full. Enqueue not possible.” Else If(Front < L) AND (Rear < L) Front = Front + 1 Rear = Rear + 1 Else Rear = next EndIf A[Rear] = Item EndIf Normal Queue Steps: Item = NULL If(Front < L) print “Queue is Empty. Dequeue not possible.” Else Item = A[Front] A[Front] = NULL If(Front == Rear) Front = L-1 Rear = L-1 Else Front = Front + 1 EndIf EndIf Return(Item) DEQUEUE Circular Queue Steps: If(Front == U) next = L Else next = Front + 1 EndIf Item = NULL If(Front < L) print “Queue is Empty. Dequeue not possible.” Else Item = A[Front] A[Front] = NULL If(Front == Rear) Front = L-1 Rear = L-1 Else Front = next EndIf EndIf Return(Item) Tracing of Enqueue & Dequeue for Circular Queue Enqueue: If(Rear == U) next = L Else next = Rear + 1 EndIf Dequeue: If(Front == U) next = L Else next = Front + 1 EndIf If(next == Front) print “Queue is Full. Enqueue not possible.” Item = NULL If(Front < L) print “Queue is Empty. Dequeue not possible.” Else Item = A[Front] A[Front] = NULL Else If(Front < L) AND (Rear < L) Front = Front + 1 Rear = Rear + 1 Else Rear = next EndIf A[Rear] = Item EndIf If(Front == Rear) Front = L-1 Rear = L-1 Else Front = next EndIf EndIf Return(Item) Trace the following steps for a Circular Queue of length/size ‘4’ implemented using array A[-2…1]. F = -3 R = -3 -2 -1 0 1) Dequeue() 2) Enqueue(10) 3) Enqueue(30) 4) Enqueue(20) 5) Enqueue(40) 6) Enqueue(50) 7) Dequeue() 8) Dequeue() 9) Enqueue(50) 10) Dequeue() 11) Dequeue() 12) Dequeue() 13) Dequeue() 1 Queue implemented using Array •Algorithm: –Enqueue_CQ •Input: –Item: Data to be enqueued / inserted in the Queue. –Front: Pointer to the front end of the Queue. –Rear: Pointer to the rear end of the Queue. •Output: –Item inserted at Rear end of the Queue if successful, message otherwise. •Data Structure: –Queue implemented using array A[L…U] with Front and Rear pointers. Steps: Algorithm: Enqueue_CQ If(Rear == U) next = L Else next = Rear + 1 EndIf Find the next position of Rear. If(next == Front) print “Queue is Full. Enqueue not possible.” Else If(Front < L) AND (Rear < L) Front = Front + 1 Enqueue the very first element. Rear = Rear + 1 Else Rear = next Enqueue any other element. EndIf A[Rear] = Item EndIf Stop Queue implemented using Array •Algorithm: –Dequeue_CQ •Input: –Front: Pointer to the front end of the Queue. –Rear: Pointer to the rear end of the Queue. •Output: –Item: Data dequeued/deleted from the Queue if successful, message otherwise. •Data Structure: –Queue implemented using array A[L…U] with Front and Rear pointers. Steps: Algorithm: Dequeue_CQ If(Front == U) next = L Else next = Front + 1 EndIf Find the next position of Front. Item = NULL If(Front < L) print “Queue is Empty. Dequeue not possible.” Else Item = A[Front] A[Front] = NULL If(Front == Rear) Front = L-1 Rear = L-1 Else Front = next EndIf EndIf Return(Item) Stop Dequeue the last/only element. Dequeue any other element. Queue Front, Rear pointers? Normal Queue Circular Queue 35 55 45 25 30 50 40 20 1 2 3 4 1 2 3 4 R Not possible to tell. F Circular Queue 1 50 40 20 2 3 4 F R Queue using a Linked List 1st Solution: 2nd Solution: Enqueue: Insert_End Traversal? Yes Dequeue: Delete_Front Traversal? No Front ptr Rear ptr Queue_Head NULL NULL 30 NULL Remove it? Enqueue: Insert_Front Dequeue: Delete_End Front ptr Rear 10 NULL new new Front ptr Rear 20 NULL new Front = NULL Rear = NULL Enqueue(30) Dequeue() 30 Enqueue(10) Dequeue() 10 Enqueue(20) Dequeue() 20 Dequeue() Queue is Empty Queue using a Linked List •Algorithm: –Enqueue_LL •Input: –Item: Data to be enqueued / inserted in the Queue. –Queue_Head: Pointer to the starting of the Queue. –Front: Pointer to the front end of the Queue. –Rear: Pointer to the rear end of the Queue. •Output: –Item inserted at Rear end of the Queue if successful, message otherwise. •Data Structure: –Queue implemented using Single Linked List with Front and Rear pointers. Algorithm: Enqueue_LL Steps: new = GetNode(NODE) If(new == NULL) print “Memory Insufficient. Enqueue not possible.” Else new -> Data = Item new->Link = NULL If(Queue_Head->Link == NULL) Front = new Enqueue the very first element. Rear = new Queue_Head->Link = new Else Rear->Link = new Enqueue any other element. Rear = new EndIf EndIf Stop Queue using a Linked List •Algorithm: –Dequeue_LL •Input: –Queue_Head: Pointer to the starting of the Queue. –Front: Pointer to the front end of the Queue. –Rear: Pointer to the rear end of the Queue. •Output: –Item: Data dequeued/deleted from the Queue if successful, message otherwise. •Data Structure: –Queue implemented using Single Linked List with Front and Rear pointers. Algorithm: Dequeue_LL Steps: Item = NULL If(Queue_Head->Link == NULL) print “Queue is empty. Dequeue not possible.” Else Item = Front->Data Queue_Head->Link = Front->Link ReturnNode(Front) If(Queue_Head->Link == NULL) Dequeue the last/only element. Front = NULL Rear = NULL Else Front = Queue_Head->Link Dequeue any other element. EndIf EndIf Return(Item) Stop Queue Rear Front Pop() Deletion Eject() Deletion Insertion Push(Item) Insertion Inject(Item) DEQUE (Not DEQUEUE) Double Ended Queue Pronounced as ‘DECK’ Queue •Deque / Deck: –Queue where, •Both insertion and deletion can be made at either end of the queue and hence, •Can represent 2 data structures: –Stack –Queue –Operations possible: •Push: –Insert Item at the Front end of a Deque. •Pop: –Remove Item from the Front end of a Deque. •Inject: –Insert Item at the Rear end of a Deque. •Eject: –Remove Item from the Rear end of a Deque. Queue Types/Variations of DEQUE Front Rear Pop() Deletion Insertion Push(Item) Front Pop() Deletion Insertion Push(Item) Normal DEQUE / DECK Eject() Deletion Insertion Inject(Item) Input-restricted DEQUE / DECK Rear Pop() Deletion Front Eject() Deletion Insertion Inject(Item) Rear Insertion Inject(Item) Output-restricted DEQUE / DECK Queue Priority Queue Items/Elements Front Deletion H B D V 2 6 1 2 Rear Insertion Priorities of the Item/Element Element can be inserted or deleted not only at the ends but at any position in the queue depending on the priority. As a result, it does not follow FIFO property and hence cannot be called a Queue. However it is still called a Queue. Queue •Priority Queue: –Queue where, •Every item/element is given a value called, •The ‘priority’ of the element and, –Element can be inserted or deleted not only at the ends but, –At any position in the queue. –As a result, •It does not strictly follow the FIFO (First-in First-out) principle of the Queue. •However, the name is now firmly associated with this data structure. –Example of model of Priority Queue could be: •Element of higher priority is processed before any element of lower priority. •Two elements with the same priority are processed according to the order in which they were added to the Queue. Queue •Applications of Queue: –Simulation: •Queue at a ticket counter. •Queue at a traffic point. –Aspects/Features of an Operating System: •Scheduling in a: –Multiprogramming / Multitasking environment.