370 likes | 1.15k Views
The Queue Data Structure. Mugurel Ionu ț Andreica Spring 2012. Operations. enqueue(x) Adds the element x at the tail of the queue dequeue() Removes the element from the head of the queue and returns it Returns an error if the stack is empty peek()
E N D
The Queue Data Structure Mugurel Ionuț Andreica Spring 2012
Operations • enqueue(x) • Adds the element x at the tail of the queue • dequeue() • Removes the element from the head of the queue and returns it • Returns an error if the stack is empty • peek() • Returns (but does not remove) the element at the head of the queue • isEmpty() • Returns 1 if the queue is empty and 0 otherwise • The axioms are given implicitly – they determine the expected behavior of the queue for a given sequence of operations • See the examples on the upcoming slides
Queue – Array-based Implementation (queue1.h) T peek() { if (isEmpty()) { fprintf(stderr, "Error 103 - The queue is empty!\n"); T x; return x; } return queueArray[head]; } int isEmpty() { return (head == tail); } Queue() { head = tail = 0; // the queue is empty in the beginning } }; #define NMAX 100 template<typename T> class Queue { private: T queueArray[NMAX]; int head, tail; public: void enqueue(T x) { if (tail >= NMAX) { fprintf(stderr, "Error 101 - The queue is full!\n"); return; } queueArray[tail] = x; tail++; } T dequeue() { if (isEmpty()) { fprintf(stderr, "Error 102 - The queue is empty!\n"); T x; return x; } T x = queueArray[head]; head++; return x; }
Using the Queue q.enqueue(2); printf("%d\n", q.dequeue()); printf("%d\n", q.isEmpty()); printf("%d\n", q.peek()); q.dequeue(); printf("%d\n", q.dequeue()); printf("%d\n", q.isEmpty()); return 0; } #include <stdio.h> #include “queue1.h” int main(){ Queue<int> q; q.enqueue(7); q.enqueue(8); q.enqueue(6); printf("%d\n", q.dequeue()); printf("%d\n", q.dequeue()); printf("%d\n", q.peek()); q.enqueue(4);
Disadvantages of the Array-based Queue Implementation • The head and tail variables are constantly increasing • As elements are removed from the queue, the portion of the array which is effectively used shifts to the right • We may reach the end of the array and be unable to enqueue any other elements, although a large fraction of the array (its left part) is empty (unused) • Improved solution: circular array
Circular Array-based Queue - Example • Circular array with NMAX=3 entries
Queue – Circular Array-based Implementation (queue2.h) T peek() { if (isEmpty()) { fprintf(stderr, "Error 103 - The queue is empty!\n"); T x; return x; } return queueArray[head]; } int isEmpty() { return (size == 0); } Queue() { head = tail = size = 0; } }; #define NMAX 100 template<typename T> class Queue { private: T queueArray[NMAX]; int head, tail, size; public: void enqueue(T x) { if (size == NMAX) { fprintf(stderr, "Error 101 - The queue is full!\n"); return; } queueArray[tail] = x; tail = (tail + 1) % NMAX; size++; } T dequeue() { if (isEmpty()) { fprintf(stderr, "Error 102 - The queue is empty!\n"); T x; return x; } T x = queueArray[head]; head = (head + 1) % NMAX; size--; return x; }