340 likes | 435 Views
CHAPTER 7. Queues. Queues. A queue is a linear collection whose elements are added on one end and removed from another Elements are removed in the same order they arrive A queue is FIFO – first in, first out. A conceptual view of a queue. Basic operations. Enqueue :
E N D
CHAPTER 7 Queues
Queues • A queueis a linear collection whose elements are added on one end and removed from another • Elements are removed in the same order they arrive • A queue is FIFO – first in, first out
Basic operations • Enqueue: • store a data item at the rear end of the queue • make rear to be the new end of the queue • Dequeue: • retrieve and remove a data item from the front of the queue • make frontto be the element that was after the removed element
Example • enqueue Item 1 • enqueue Item 2 • enqueue Item 3 • dequeue • enqueue Item 4 Item 4 Item 3 Item 2 Item 3 Item 2 Item 1 Item 3 Item 2 Item 2 Item 1 Item 1
ADT definition of Queue • Notation: • Q queue • e item of same type as the elements of Q • b boolean value
Operations • InitQueue(Q) Procedure to initialize Q to an empty queue • Preconditions: none • Postconditions: Q empty
Operations • Enqueue(Q,e) Procedure to place an item e into Q • Preconditions:Q not full • Postconditions: size of Q increased by 1 • Dequeue(Q) e Procedure to remove and return the front item in Q if Q is not empty • Preconditions:Q not empty • Postconditions:front element removed, size of Q decreased by 1
Operations • first(Q) e Procedure to return (without removing) the front item in Q if Q is not empty • Preconditions: Q not empty • Postconditions: Q not changed
Operations • IsEmpty(Q) b Boolean function that returns TRUE if Q is empty • Preconditions: none • Postconditions: Q not changed
Queue AXIOMS • q.InitQueue().IsEmpty() = true • q.MakeEmpty().IsEmpty() = true • Note: MakeEmpty is not listed in the textbook • q.Enqueue(g).IsEmpty() = false • q.First() = q
Queue applications • Wait line simulations • Radix sorting • Breadth-first search in a tree/graph
Queue implementation • The interface class • Linked implementation • Array implementation
The interface class public interface QueueADT<T> { // Adds one element to the rear of this queue public void enqueue (T element); // Removes and returns the front element from this queue public T dequeue(); // Returns without removing the front element of this queue public T first(); // Returns true if this queue contains no elements public boolean isEmpty(); // Returns the number of elements in this stack public int size(); // Returns a string representation of this queue public String toString(); }
Linked implementation Internally, a queue is represented as a linked list of nodes, with a reference to the front of the queue, a reference to the rear end of the queue, and an integer count of the number of nodes in the queue LinearNode class is reused to define the nodes
Linked Implementation: Enqueue • Create a new node • If queue is empty • Make front equal to the new node • Make rear equal to the new node • Otherwise • Attach the new node to the rear end of the queue • Make rear to be the new node • Increment count
Linked Implementation: Enqueue public void enqueue (T element) { LinearNode<T> node = new LinearNode<T>(element); if (isEmpty()) front = node; else rear.setNext (node); rear = node; count++; }
Linked Implementation: Dequeue • Get the contents of the front node • Make front to be the node after the first node, or null if this was the only node • Decrement count • If queue is empty • Make rear equal to null • Return the contents of the retrieved node
Linked Implementation: Dequeue public T dequeue() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException ("queue"); T result = front.getElement(); front = front.getNext(); count--; if (isEmpty()) rear = null; return result; }
Array implementation • A queue can be managed using an array in which index 0 represents one end • An integer value rear represents the next open slot in the array and the number of elements currently in the queue • The challenge with this approach is that a queue operates on both ends, so the elements in the array must be shifted to keep one end at index 0
Array implementation Not efficient
Circular Array Implementation • If we don't fix one end of the queue at index 0, we won't have to shift the elements • A circular queue is an implementation of a queue using an array that conceptually loops around on itself
Enqueue in circular array • When an element is enqueued, the value of rear is incremented • But it must take into account the need to loop back to 0: rear = (rear+1) % queue.length; • Note that this array implementation can also reach capacity and may need enlarging
Dequeue in Circular Array • When an element is dequeued, the value of front is incremented • But it must take into account the need to loop back to 0: front = (front+1) % queue.length; • The queue is empty when front becomes equal to rear
Complexity of the queue operations • The enqueue operation is O(1) for all implementations • The dequeue operation is O(1) for linked and circular array implementations, but O(n) for the noncircular array version
Examples 1a • Problem 1: • AppendQueue(Q,P): A procedure to append a queue P onto the end of a queue Q, leaving P empty. • Pre: queue P and queue Q, initialized (possibly empty) • Post: Q contains all elements originally in Q, followed by the elements that were in P in same order. P is empty.
Examples 1b • Algorithm: while not isEmpty(P) e dequeue(P) enqueue(Q,e) • Complexity of the algorithm: O(N), N - the number of elements in P.
Examples 2a • Problem 2: ReverseQueue(Q): A procedure to reverse the elements in a queue Q, using a stack • Pre: queue Q, initialized (possibly empty) • Post: Q contains all elements re-written in reverse order
Examples 2b • Algorithm: Create a new stack S while not isEmpty(Q) push(S, dequeue(Q)) while not isEmpty(S) enqueue(Q,pop(S))