Download presentation
Presentation is loading. Please wait.
Published byFranklin Edwards Modified over 9 years ago
1
CS2006 - Data Structures I Chapter 7 Queue I
2
2 Topics Introduction Queue Application Implementation Linked List Array ADT List
3
3 Queues A queue differs from a stack in that it follows the first-in-first-out (FIFO) principle. Inserting an item to the rear is known as "enqueueing". Removing an item from the front is known as "dequeueing". cashier Front of lineBack of line
4
4 Queues Linear, homogeneous structure Has First-In-First-Out (FIFO) behavior; Items added at one end and removed from the other end Middle elements are logically inaccessible Add/ Enqueue Remove/ Dequeue Back/RearFront/Head
5
5 Queue Applications Real-World Applications Buy a movie ticket Check out at a bookstore Cashier lines in any store Computer Science Applications OS task scheduling Print lines of a document Convert digit strings to decimal Shared resource usage (CPU, memory access, … )
6
6 ADT Queue Specification: Elements Homogeneous Linear Structure: Elements added to rear & removed from front
7
7 ADT Queue Specification: Operations Create an empty queue Destroy a queue Check if a queue is empty / Full Enqueue (Enq, Enque, Add, Insert): Adding new element at the back (rear) Dequeue (Deq, Deque, Remove, Serve): Deleting an element from the front Retrieve an element from a queue
8
8 Queue Applications Converting Digit Strings to Decimal Enter characters from the keyboard and retain them in order Assumption: No typing mistakes Blank spaces may precede or follow the digits Formula used: Initial value DigitSum = 0
9
9 Queue Applications Converting Digit Strings to Decimal Pseudocode // Convert digits in aQueue into decimal integer n // Get first digit, ignoring any leading blanks do { ch=queue.dequeue() } while ( ch is blank) // Assertion: ch contains first digit // Compute n from digits in queue n = 0; done = false; do {n = 10 * n + integer that ch represents if (! queue.isEmpty( ) ) ch=queue.dequeue() else done = true } while (! done and ch is a digit) // Assertion: n is result
10
10 Queue Applications Recognizing Palindromes Uses a queue & a stack Idea: 1. Insert the string in both queue & stack 2. Remove characters from both stack's Top & queue's Front, comparing them 3. Repeat until: a) Either the stack or the queue are empty String is a palindrome b) The character from the stack and the corresponding character from the queue are not similar String isn't a palindrome
11
11 Queue Applications Recognizing Palindromes Pseudocode IsPal(in str:string) : boolean // Determines whether String is a palindrome aQueue.createQueue ( ) // Create an empty queue aStack.createStack ( ) // Create an empty stack // Insert each character of String into both aQueue and aStack length = length of str for ( i = 1 through length) {nextChar = i th character of str aQueue.enqueue ( nextChar ) aStack.push(NextChar) } // end for // Compare aQueue with aStack charactersAreEqual = true; while ( ! aQueue.isEmpty() && charactersAreEqual) {aQueue.getFront ( queueFront ) aStack.getTop ( stackTop ) if ( queueFront equals stackTop) {aQueue.dequeue ( ) aStack.pop ( ) } elsecharactersAreEqual = false } // end while return charactersAreEqual
12
12 ADT Queue Implementation Possible implementations: Linked List-based Linear Circular Array-based Linear Circular ADT List-based
13
13 Linked List-Based Implementation More straightforward than array-based Possible options: Linear linked list Two external “ pointer ” (Front & Back) Circular linked list One “ pointer ” will be enough (Back)
14
14 Linked List Queue Implementation Linked List -Based Implementation: Option 1 Insertion to an empty list front = newNode back = newNode
15
15 Linked List Queue Implementation LL -Based Implementation: Option 1 Insertion to a non-empty list newNode.setNext ( NULL); Back.setNext (newNode); back = newNode Deletion temp = front front = front.getNext() temp.setNext ( NULL ) 2015 front 2684 back
16
16 Linked List Queue Implementation LL -Based Implementation: option 1 Deletion form a one-node (one item) queue If (front = back&&front!=null){ back = null front=null } form a non-empty, more than one item queue front = front.getNext()
17
17 Linked List Queue Implementation LL based Implementation: option 2 Insertion Into an empty queue newNode.setNext (newNode) back = newNode Into a non-empty queue newNode.setNext (back.getNext()) Back.setNext (newNode); back = newnode
18
18 Linked List Queue Implementation LL -Based Implementation: option 2 Deletion form a one-node (one item) queue Node front = back.getNext() If (front = back) back = NULL Front=null form a non-empty, more than one item queue Node front = back.getNext() Back.setNext ( front.getNext()) Front=null
19
19 Queue Interface public interface QueueInterface { public boolean isEmpty(); // Determines whether a queue is empty. // Precondition: None. // Postcondition: Returns true if the queue is empty; // otherwise returns false. public void enqueue(Object newItem) throws QueueException; // Adds an item at the back of a queue. // Precondition: newItem is the item to be inserted. // Postcondition: If the operation was successful, newItem // is at the back of the queue. Some implementations // may throw QueueException if newItem cannot be added to the queue. public Object dequeue() throws QueueException; // Retrieves and removes the front of a queue. // Precondition: None. // Postcondition: If the queue is not empty, the item that was added to the // queue earliest is returned and the item is removed. If the queue is empty, // the operation is impossible and QueueException is thrown.
20
20 Queue Interface (2) public void dequeueAll(); // Removes all items of a queue. // Precondition: None. // Postcondition: The queue is empty. public Object peek() throws QueueException; // Retrieves the item at the front of a queue. // Precondition: None. // Postcondition: If the queue is not empty, the item // that was added to the queue earliest is returned. // If the queue is empty, the operation is impossible // and QueueException is thrown. } // end QueueInterface
21
21 Queue Exception public class QueueException extends RuntimeException { public QueueException(String s) { super(s); } // end constructor } // end QueueException
22
22 LListQueue Implementation public class LListQueue implements QueueInterface { private Node lastNode; public LListQueue() { lastNode = null; } // end default constructor // queue operations: public boolean isEmpty() { return lastNode == null; } // end isEmpty public boolean isFull() { return false; } // end isFull public void dequeueAll() { lastNode = null; } // end dequeueAll
23
23 LListQueue Implementation (2) public void enqueue(Object newItem) { Node newNode = new Node(newItem); if(isFull()) throw new QueueException("QueueException on enqueue:"+ "queue full"); // insert the new node if (isEmpty()) { // insertion into empty queue newNode.setNext(newNode); } else { // insertion into nonempty queue newNode.setNext(lastNode.getNext()); lastNode.setNext(newNode); } // end if lastNode = newNode; // new node is at back } // end enqueue
24
24 LListQueue Implementation (3) public Object dequeue() throws QueueException { if (!isEmpty()) { // queue is not empty; remove front Node firstNode = lastNode.getNext(); if (firstNode == lastNode) { // special case? lastNode = null; // yes, one node in queue } else { lastNode.setNext(firstNode.getNext()); } // end if return firstNode.getItem(); } else { throw new QueueException("QueueException on dequeue:" + "queue empty"); } // end if } // end dequeue
25
25 LListQueue Implementation (4) public Object peek() throws QueueException { if (!isEmpty()) { // queue is not empty; retrieve front Node firstNode = lastNode.getNext(); return firstNode.getItem(); } else { throw new QueueException("QueueException on peek:" + "queue empty"); } // end if } // end peek } // end ListQueue
26
26 LListQueue Test public class LListQueueTest { public static void main(String[ ] args) { LListQueue aQueue = new LListQueue(); System.out.println("Enqueuing:"); for (int i = 0; i < 9; i++) { System.out.print(" "+i); aQueue.enqueue(new Integer(i)); } // end for System.out.println("\nDequeuing:"); for (int i = 0; i < 9; i++) { System.out.print(" "+aQueue.dequeue()); } // end for System.out.println(); } // end main } // QueueTest
27
27 Array-Based Queue Implementation Array-Based Implementation Fix-size Have the following definition final int MAZ_QUEUE = maxinum-size-of-queue; Object [] items; Int front; Int back;
28
28 Array-Based Queue Implementation 1. Linear Array implementation Front & Back are indexes in the array Initial condition: Front =0 & Back = -1 Initial state After 5 additions 04 FrontBack 20 45 51 76 84 0 1 2 3 4 MAX_QUEUE -1 0 FrontBack 0 1 2 3 4 MAX_QUEUE -1
29
29 Array-Based Queue Implementation 1. Linear Array implementation Back will point to the last added element Initial values: front = 0 back = -1 Insertion Increment back Insert item in item [ back ] Deletion Increment front Queue Empty Condition back < front Queue is Full back == MAX_QUEUE-1
30
30 Array-Based Queue Implementation 1. Linear Array implementation Problem: Rightward-Drifting: After a sequence of additions & removals, items will drift towards the end of the array Full if back==MAX_QUEUE-1, even only a few items 4749 FrontBack 16 60 20 0 1 47 48 49 MAX_QUEUE -1 Rightward drifting
31
31 Array-Based Queue Implementation 1. Linear Array implementation Rightward drifting solutions Use a circular array: When Front or Back reach the end of the array, wrap them around to the beginning of the array Problem: Front & Back can't be used to distinguish between queue-full & queue-empty conditions
32
32 Array-Based Queue Implementation 2. Circular Array Implementation Back Front 45 51 76 MAX_QUEUE -1 Back Front 45 51 76 MAX_QUEUE -1 Back Front 45 51 76 MAX_QUEUE -1 58 Deletion and Insertion on the queue
33
33 Array-Based Queue Implementation 2. How to determine if queue is full or empty? Back 1 76 MAX_QUEUE -1 Front Back MAX_QUEUE -1 0 Front 0 Queue wiith one item Delete, queue becomes empty
34
34 Array-Based Queue Implementation 2. How to determine if queue is full or empty? Back 1 76 MAX_QUEUE -1 0 Front Queue wiith single empty After insertion, queue becomes full 7 56 32 45 89 5 Back 1 76 MAX_QUEUE -1 0 Front 7 56 32 45 89 5 47
35
35 Array-Based Queue Implementation 2. Circular Arrays Implementation That is why we need a count If count ==MAX_QUEUE Queue is FULL Else if count ==0 Queue is EMPTY
36
36 Array-Based Queue Implementation 2. Circular Array Implementation final int MAZ_QUEUE = maxinum-size-of-queue; Object [] items; Int front; Int back; int count; Back Front 20 45 51 76 MAX_QUEUE -1
37
37 Array-Based Queue Implementation 2. Circular Arrays Implementation Initial condition: Count = 0, Front = 0, Back = MAX_QUEUE – 1 The Wrap-around effect is obtained by using modulo arithmetic (%-operator) Insertion Increment Back, using modulo arithmetic Insert item Increment Count back = ( back + 1 ) % MAX_QUEUE; items[back} = newItem; ++count;
38
38 Array-Based Queue Implementation 2. Circular Array Implementation Deletion Increment Front using modulo arithmetic Decrement Count front = ( front + 1 ) % MAX_QUEUE; - - count;
39
39 Array-Based Queue Implementation public class ArrayQueue implements QueueInterface { private final int MAX_QUEUE = 50; // maximum size of queue private Object[ ] items; private int front, back, count; public ArrayQueue() { items = new Object[MAX_QUEUE]; front = 0; back = MAX_QUEUE-1; count = 0; } // end default constructor // queue operations: public boolean isEmpty() { return count == 0; } // end isEmpty public boolean isFull() { return count == MAX_QUEUE; } // end isFull
40
40 Array-Based Queue Implementation (2) public void enqueue(Object newItem) { if (!isFull()) { back = (back+1) % (MAX_QUEUE); items[back] = newItem; ++count; } else throw new QueueException("QueueException on enqueue: "+ "Queue full"); } // end enqueue public Object dequeue() throws QueueException { if (!isEmpty()) { // queue is not empty; remove front Object queueFront = items[front]; front = (front+1) % (MAX_QUEUE); --count; return queueFront; } else throw new QueueException("QueueException on dequeue: "+ "Queue empty"); } // end dequeue
41
41 Array-Based Queue Implementation (3) public void dequeueAll() { items = new Object[MAX_QUEUE]; front = 0; back = MAX_QUEUE-1; count = 0; } // end dequeueAll public Object peek() throws QueueException { if (!isEmpty()) { // queue is not empty; retrieve front return items[front]; } else { throw new QueueException("Queue exception on peek: " + "Queue empty"); } // end if } // end peek } // end ArrayQueue
42
42 Array Based Queue Test public class ArrayQueueTest { public static void main(String[] args) { ArrayQueue aQueue = new ArrayQueue(); System.out.println("Enqueuing:"); for (int i = 0; i < 9; i++) { System.out.print(" "+i); aQueue.enqueue(new Integer(i)); } // end for System.out.println("\nDequeuing:"); for (int i = 0; i < 9; i++) { System.out.print(" "+aQueue.dequeue()); } // end for System.out.println(); } // end main } // QueueTest
43
43 Full/Empty Determination without Counters Disadvantage of Using a counter Overhead of maintaining a counter or flag Using a flag isFull Flag is set to true when it is full Flag is set to false when the queue is not full Expense as using the counter
44
44 Full/Empty Determination without Counters Queue size counters will not be used Use extra array location Declare MAX_QUEUE +1 locations, but only use MAX_QUEUE of them for queue items Full/Empty determinations will be made using the relative positions of front and back. back will be initialized to –-1 and front to 0 as before. Both front and back will be incremented with wraparound.
45
45 Array-Based Queue Implementation 2. Circular Array Implementation Full QueueEmpty Queue Back Front 7 6 3 8 MAX_QUEUE-1 1 4 2 0 1 3 4 5 6 7 2 Front & Back MAX_QUEUE-1 0 1 3 4 5 6 7 2
46
46 Final Method for Full/Empty Determination without Counters To allow different tests for empty and full Sacrifice one array slot so that a full Queue uses all but one array slot Thus the test for a full Queue becomes: (back + 1) % (MAX_QUEUE+1) == front While the test for an empty Queue remains: back== front If the elements of the queue are complex data structure, the memory wasted may be significant
47
47 ADT List Queue Implementation Use ADT List to implement the queue Pre- & Post-conditions are the same as before The implementation is much simpler
48
48 ADT List Queue Implementation Front is the position 1 of the list Back is the item at the end of the list
49
49 ADT List Queue Implementation Dequeue () List.remove(1); Peek() List.get(1); Enqueue (newItem) List.add(list.size()+1, newitem);
50
50 ListQueue Implementation public class ListQueue implements QueueInterface { private ListInterface list; public ListQueue() { list = new ListReferenceBased (); } // end default constructor // queue operations: public boolean isEmpty() { return list.isEmpty(); } // end isEmpty public void dequeueAll() { list.removeAll(); } // end dequeueAll
51
51 ListQueue Implementation (2) public void enqueue(Object newItem) { list.add(list.size()+1, newItem); } } // end enqueue
52
52 ListQueue Implementation (3) public Object dequeue() throws QueueException { if (!isEmpty()) { // queue is not empty; remove front Object queueFront = list.get(1); list.remove(); return queueFront; } else { throw new QueueException("QueueException on dequeue:" + "queue empty"); } // end if } // end dequeue
53
53 ListQueue Implementation (4) public Object peek() throws QueueException { if (!isEmpty()) { return flist.get(1); } else { throw new QueueException("QueueException on peek:" + "queue empty"); } // end if } // end peek } // end ListQueue
54
54 ADT Queue Implementation Comparison Reference-Based More complicated than ADT List Most flexible No size restrictions Array-Based No overhead of pointer manipulation Prevents adding elements if the array is full ADT List-Based Simpler to write Not as efficient as using a linked list directly
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.