Queue Stack and Queue Slide 2 OBJECTIVES TO
Queue
Stack and Queue / Slide 2 OBJECTIVES * TO IDENTIFY THE OPERATION IN QUEUE * UNDERSTAND THE QUEUE CONCEPT
Stack and Queue / Slide 3 Queue Overview * Queue ADT * Basic operations of queue n Enqueuing, dequeuing etc. * Implementation Array n Linked list n of queue
Stack and Queue / Slide 4 Queue ADT * Like a stack, a queue is also a list. However, with a queue, insertion is done at one end, while deletion is performed at the other end. * Accessing the elements of queues follows a First In, First Out (FIFO) order. n Like customers standing in a check-out line in a store, the first customer in is the first customer served.
Stack and Queue / Slide 5 The Queue ADT * Another n form of restricted list Insertion is done at one end, whereas deletion is performed at the other end * Basic operations: enqueue: insert an element at the rear of the list n dequeue: delete the element at the front of the list n
Stack and Queue / Slide 6 Enqueue and Dequeue * Primary queue operations: Enqueue and Dequeue * Like check-out lines in a store, a queue has a front and a rear. * Enqueue n Insert an element at the rear of the queue * Dequeue n Remove an element from the front of the queue Remove (Dequeue) front rear Insert (Enqueue)
Stack and Queue / Slide 7 Implementation of Queue * Just as stacks can be implemented as arrays or linked lists, so with queues. * Dynamic queues have the same advantages over static queues as dynamic stacks have over static stacks
Stack and Queue / Slide 8 Queue Implementation of Array * There are several different algorithms to implement Enqueue and Dequeue * Naïve way n When enqueuing, the front index is always fixed and the rear index moves forward in the array. rear 3 3 front Enqueue(3) rear 6 Enqueue(6) 3 6 9 front Enqueue(9)
Stack and Queue / Slide 9 Queue Implementation of Array * Naïve way When enqueuing, the front index is always fixed and the rear index moves forward in the array. n When dequeuing, the element at the front the queue is removed. Move all the elements after it by one position. (Inefficient!!!) n 6 rear 9 9 front Dequeue() rear = -1 front Dequeue()
Stack and Queue / Slide 10 Queue Implementation of Array * Better way When an item is enqueued, make the rear index move forward. n When an item is dequeued, the front index moves by one element towards the back of the queue (thus removing the front item, so no copying to neighboring elements is needed). n (front) XXXXOOOOO OXXXXOOOO OOXXXXXOO OOOOXXXXX (rear) (after 1 dequeue, and 1 enqueue) (after another dequeue, and 2 enqueues) (after 2 more dequeues, and 2 enqueues) The problem here is that the rear index cannot move beyond the last element in the array.
Stack and Queue / Slide 11 Implementation using Circular Array * Using a circular array * When an element moves past the end of a circular array, it wraps around to the beginning, e. g. OOOOO 7963 4 OOOO 7963 (after Enqueue(4)) n After Enqueue(4), the rear index moves from 3 to 4. n
Stack and Queue / Slide 12
Stack and Queue / Slide 13 Empty or Full? * Empty n queue back = front - 1 * Full queue? the same! n Reason: n values to represent n+1 states n * Solutions Use a boolean variable to say explicitly whether the queue is empty or not n Make the array of size n+1 and only allow n elements to be stored n Use a counter of the number of elements in the queue n
Stack and Queue / Slide 14 Queue Implementation of Linked List class Queue { public: Queue(int size = 10); // constructor ~Queue() { delete [] values; } // destructor bool Is. Empty(void); bool Is. Full(void); bool Enqueue(double x); bool Dequeue(double & x); void Display. Queue(void); private: int front; // front index int rear; // rear index int counter; // number of elements int max. Size; // size of array queue double* values; // element array };
Stack and Queue / Slide 15 Queue Class * Attributes of Queue front/rear: front/rear index n counter: number of elements in the queue n max. Size: capacity of the queue n values: point to an array which stores elements of the queue n * Operations of Queue n n n Is. Empty: return true if queue is empty, return false otherwise Is. Full: return true if queue is full, return false otherwise Enqueue: add an element to the rear of queue Dequeue: delete the element at the front of queue Display. Queue: print all the data
Stack and Queue / Slide 16 Create Queue * Queue(int size = 10) Allocate a queue array of size. By default, size = 10. n front is set to 0, pointing to the first element of the array n rear is set to -1. The queue is empty initially. n Queue: : Queue(int size /* = 10 */) { values = new double[size]; max. Size = size; front = 0; rear = -1; counter = 0; }
Stack and Queue / Slide 17 Is. Empty & Is. Full * Since we keep track of the number of elements that are actually in the queue: counter, it is easy to check if the queue is empty or full. bool Queue: : Is. Empty() { if (counter) return false; else return true; } bool Queue: : Is. Full() { if (counter < max. Size) return false; else return true; }
Stack and Queue / Slide 18 Enqueue bool Queue: : Enqueue(double x) { if (Is. Full()) { cout << "Error: the queue is full. " << endl; return false; } else { // calculate the new rear position (circular) rear = (rear + 1) % max. Size; // insert new item values[rear] = x; // update counter++; return true; } }
Stack and Queue / Slide 19 Dequeue bool Queue: : Dequeue(double & x) { if (Is. Empty()) { cout << "Error: the queue is empty. " << endl; return false; } else { // retrieve the front item x = values[front]; // move front = (front + 1) % max. Size; // update counter--; return true; } }
Stack and Queue / Slide 20 Printing the elements void Queue: : Display. Queue() { cout << "front -->"; for (int i = 0; i < counter; i++) { if (i == 0) cout << "t"; else cout << "tt"; cout << values[(front + i) % max. Size]; if (i != counter - 1) cout << endl; else cout << "t<-- rear" << endl; } }
Stack and Queue / Slide 21 Using Queue int main(void) { Queue queue(5); cout << "Enqueue 5 items. " << endl; for (int x = 0; x < 5; x++) queue. Enqueue(x); cout << "Now attempting to enqueue again. . . " << endl; queue. Enqueue(5); queue. Display. Queue(); double value; queue. Dequeue(value); cout << "Retrieved element = " << value << endl; queue. Display. Queue(); queue. Enqueue(7); queue. Display. Queue(); return 0; }
Stack and Queue / Slide 22 Stack Implementation based on Linked List class Queue { public: Queue() { // constructor front = rear = NULL; counter = 0; } ~Queue() { // destructor double value; while (!Is. Empty()) Dequeue(value); } bool Is. Empty() { if (counter) return false; else return true; } void Enqueue(double x); bool Dequeue(double & x); void Display. Queue(void); private: Node* front; // pointer to front node Node* rear; // pointer to last node int counter; // number of elements };
Stack and Queue / Slide 23 Enqueue void Queue: : Enqueue(double x) { Node* new. Node = new Node; new. Node->data = x; new. Node->next = NULL; if (Is. Empty()) { front = new. Node; rear = new. Node; } else { 8 rear->next = new. Node; rear = new. Node; } 8 5 counter++; } rear 5 rear new. Node
Stack and Queue / Slide 24 Dequeue bool Queue: : Dequeue(double & x) { if (Is. Empty()) { cout << "Error: the queue is empty. " << endl; return false; } else { x = front->data; Node* next. Node = front->next; delete front; front = next. Node; counter--; } front } 3 8 5 front 8 5
Stack and Queue / Slide 25 Printing all the elements void Queue: : Display. Queue() { cout << "front -->"; Node* curr. Node = front; for (int i = 0; i < counter; i++) { if (i == 0) cout << "t"; else cout << "tt"; cout << curr. Node->data; if (i != counter - 1) cout << endl; else cout << "t<-- rear" << endl; curr. Node = curr. Node->next; } }
Stack and Queue / Slide 26 Result * Queue implemented using linked list will be never full based on array based on linked list
Stack and Queue / Slide 27 QUESTION * * * Imagine you have a stack of integers, S and a queue of integers, Q. draw a picture of S and Q after the following operations: push. Stack (S, 3) Push. Stack (S, 12) Enqueue (Q, 5) Enqueue (Q, 8) Pop. Stack (S, x) Push. Stack (S, 2) Enqueue (Q, x) Dequeue (Q, y) push. Stack (S, x) push. Stack (S, y)
Stack and Queue / Slide 28 Circular Queue * When a new item is inserted at the rear, the pointer to rear moves upwards. * Similarly, when an item is deleted from the queue the front arrow moves downwards. * After a few insert and delete operations the rear might reach the end of the queue and no more items can be inserted although the items from the front of the queue have been deleted and there is space in the queue.
Stack and Queue / Slide 29 Circular Queue * To solve this problem, queues implement wrapping around. Such queues are called Circular Queues. * Both the front and the rear pointers wrap around to the beginning of the array. * It is also called as “Ring buffer”. * Items can inserted and deleted from a queue in O(1) time.
Implementing a Queue Using a Circular Array (continued) Stack and Queue / Slide 30 Chapter 6: Queues
Implementing a Queue Using a Circular Array (continued) Stack and Queue / Slide 31 Chapter 6: Queues
Implementing a Queue Using a Circular Array (continued) Stack and Queue / Slide 32 Chapter 6: Queues
Implementing a Queue Using a Circular Array (continued) Stack and Queue / Slide 33 Chapter 6: Queues
Stack and Queue / Slide 34 * When item is removed from the data structure, it is physically still present but correct use of the structure cannot access it.
- Slides: 34