CS2006 - Data Structures I Chapter 7 Queue I. 2 Topics Introduction Queue Application Implementation...
-
Upload
franklin-edwards -
Category
Documents
-
view
232 -
download
0
Transcript of CS2006 - Data Structures I Chapter 7 Queue I. 2 Topics Introduction Queue Application Implementation...
CS2006 - Data Structures I
Chapter 7
Queue I
2
Topics
Introduction Queue Application Implementation
Linked List Array ADT List
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 line Back of line
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/Rear Front/Head
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
ADT Queue
Specification: Elements
Homogeneous Linear
Structure: Elements added to rear & removed from front
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
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
Queue Applications Converting Digit Strings to Decimal
Pseudocode// Convert digits in aQueue into decimal integer n// Get first digit, ignoring any leading blanksdo {
ch=queue.dequeue()} while ( ch is blank)// Assertion: ch contains first digit// Compute n from digits in queuen = 0;done = false;do { n = 10 * n + integer that ch represents
if (! queue.isEmpty( ) ) ch=queue.dequeue()
elsedone = true
} while (! done and ch is a digit)// Assertion: n is result
10
Queue Applications
Recognizing Palindromes Uses a queue & a stack Idea:
1. Insert the string in both queue & stack2. Remove characters from both stack's Top & queue's Front,
comparing them3. 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
Queue Applications Recognizing Palindromes
PseudocodeIsPal(in str:string) : boolean// Determines whether String is a palindromeaQueue.createQueue ( ) // Create an empty queue aStack.createStack ( ) // Create an empty stack// Insert each character of String into both aQueue and aStacklength = length of strfor ( i = 1 through length){ nextChar = ith character of str
aQueue.enqueue ( nextChar )aStack.push(NextChar)
} // end for// Compare aQueue with aStackcharactersAreEqual = true;while ( ! aQueue.isEmpty() && charactersAreEqual){ aQueue.getFront ( queueFront )
aStack.getTop ( stackTop )if ( queueFront equals stackTop){ aQueue.dequeue ( )
aStack.pop ( )} else charactersAreEqual = false
} // end whilereturn charactersAreEqual
12
ADT Queue Implementation
Possible implementations:
Linked List-based Linear Circular
Array-based Linear Circular
ADT List-based
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
Linked List Queue Implementation
Linked List -Based Implementation: Option 1 Insertion to an empty list
front = newNodeback = newNode
15
Linked List Queue Implementation
LL -Based Implementation: Option 1 Insertion to a non-empty list
newNode.setNext ( NULL);Back.setNext (newNode);back = newNode
Deletiontemp = front front = front.getNext()temp.setNext ( NULL )
20 15
front
26 84
back
16
Linked List Queue Implementation
LL -Based Implementation: option 1 Deletion
form a one-node (one item) queueIf (front = back&&front!=null){
back = null front=null }
form a non-empty, more than one item queuefront = front.getNext()
17
Linked List Queue Implementation
LL based Implementation: option 2 Insertion
Into an empty queuenewNode.setNext (newNode)back = newNode
Into a non-empty queuenewNode.setNext (back.getNext())Back.setNext (newNode);back = newnode
18
Linked List Queue Implementation
LL -Based Implementation: option 2 Deletion
form a one-node (one item) queueNode front = back.getNext()If (front = back)
back = NULLFront=null
form a non-empty, more than one item queueNode front = back.getNext()Back.setNext ( front.getNext())Front=null
19
Queue Interfacepublic 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
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
Queue Exception
public class QueueException extends RuntimeException {
public QueueException(String s) {
super(s);
} // end constructor
} // end QueueException
22
LListQueue Implementationpublic 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
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
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
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
LListQueue Testpublic 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
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
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
0 4
Front Back
20 45 51 76 84
0 1 2 3 4 MAX_QUEUE -1
0 -1
Front Back 0 1 2 3 4 MAX_QUEUE -1
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
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
47 49
Front Back
16 60 20
0 1 47 48 49
MAX_QUEUE -1
Rightward drifting
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
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
Array-Based Queue Implementation2. 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 itemDelete, queue becomes empty
34
Array-Based Queue Implementation2. 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
Array-Based Queue Implementation
2. Circular Arrays Implementation That is why we need a count
If count ==MAX_QUEUEQueue is FULL
Else if count ==0Queue is EMPTY
36
Array-Based Queue Implementation
2. Circular Array Implementationfinal 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
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
Array-Based Queue Implementation 2. Circular Array Implementation
Deletion Increment Front using modulo arithmetic Decrement Count
front = ( front + 1 ) % MAX_QUEUE;
- - count;
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
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
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
Array Based Queue Testpublic 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
Full/Empty Determinationwithout 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
Full/Empty Determinationwithout 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
Array-Based Queue Implementation
2. Circular Array Implementation
Full Queue Empty Queue
BackFront
7
6
3
8
MAX_QUEUE-1
14
2
0
1
34
5
6
7
2
Front & Back
MAX_QUEUE-1 0
1
34
5
6
7
2
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
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
ADT List Queue Implementation
Front is the position 1 of the list Back is the item at the end of the list
49
ADT List Queue Implementation
Dequeue ()List.remove(1);
Peek()List.get(1);
Enqueue (newItem)List.add(list.size()+1, newitem);
50
ListQueue Implementationpublic 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
ListQueue Implementation (2) public void enqueue(Object newItem) {
list.add(list.size()+1, newItem);
}
} // end enqueue
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
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
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