Date post: | 14-Dec-2015 |
Category: |
Documents |
Upload: | stacey-deagle |
View: | 213 times |
Download: | 1 times |
Queue Definition
Ordered list with property:– All insertions take place at one end (tail)– All deletions take place at other end (head)
Queue: Q = (a0, a1, …, an-1)
a0 is the front element, an-1 is the tail, and ai is behind ai-1 for all i, 1 <= i < n
Queue Definition
Because of insertion and deletion properties,
Queue is very similar to:
Line at the grocery store
Cars in traffic
Network packets
….
Also called first-in first out lists
Array-Based Queue Definitiontemplate <class KeyType>class Queue{
public:Queue(int MaxQueueSize = DefaultSize);~Queue();
bool IsFull();bool IsEmpty();void Add(const KeyType& item);KeyType* Delete(KeyType& item);
private:void QueueFull(); // error handlingvoid QueueEmpty(); // error handlingint head, tail;KeyType* queue;int MaxSize;
};
Queue Implementation
Constructor:template <class KeyType>
Queue<KeyType>::Queue(int MaxQueueSize): MaxSize(MaxQueueSize){
queue = new KeyType[MaxSize];head = tail = -1;
}
Queue Implementation
Destructor:template <class KeyType>
Queue<KeyType>::~Queue(){
delete [] queue;head = tail = -1;
}
Queue Implementation
IsFull() and IsEmpty():
template <class KeyType>bool Queue<KeyType>::IsFull()
{return (tail == (MaxSize-1));
}
template <class KeyType>bool Queue<KeyType>::IsEmpty()
{return (head == tail);
}
Queue Implementation
Add() and Delete():template <class KeyType>void Queue<KeyType>::Add (const KeyType& item)
{if (IsFull()) {QueueFull(); return;}else { tail = tail + 1; queue[tail] = item; }
}
template <class KeyType>KeyType* Queue<KeyType>::Delete(KeyType& item)
{
if (IsEmpty()) {QueueEmpty(); return 0};else { head = head + 1; item = queue[head]; return
&item; }}
Example: OS Job Scheduling
OS has to manage how jobs (programs) are executed on the processor – 2 typical techniques:-Priority based: Some ordering over of jobs based on importance
(Professor X’s jobs should be allowed to run first over Professor Y).-Queue based: Equal priority, schedule in first in first out order.
Queue Based Job Processing
Front Rear Q[0] Q[1] Q[2] Q[3] Comments
-1 -1 Initial
-1 0 J1 Job 1 Enters
-1 1 J1 J2 Job 2 Enters
-1 2 J1 J2 J3 Job 3 Enters
0 2 J2 J3 Job 1 Leaves
0 3 J2 J3 J4 Job 4 Enters
1 3 J3 J4 Job 2 Leaves
Job Processing
• When J4 enters the queue, rear is updated to 3.• When rear is 3 in a 4-entry queue, run out of space.• The array may not really be full though, if head is
not -1.• Head can be > -1 if items have been removed from
queue.
Possible Solution: When rear = (maxSize – 1) attempt to shift data forwards into empty spaces and then do Add.
Queue Shift
private void shiftQueue(KeyType* queue, int & head, int & tail)
{int difference = head – (-1); // head + 1for (int j = head + 1; j < maxSize; j++){
queue[j-difference] = queue[j];}head = -1;tail = tail – difference;
}
Queue ShiftWorst Case For Queue Shift:
Full Queue
Alternating Delete and Add statements
Front Rear Q[0] Q[1] Q[2] Q[3] Comments
-1 3 J1 J2 J3 J4 Initial
0 3 J2 J3 J4 Job 1 Leaves
-1 3 J2 J3 J4 J5 Job 5 Enters
0 3 J3 J4 J5 Job 2 Enters
-1 3 J3 J4 J5 J6 Job 6 Leaves
Worst Case Queue Shift
• Worst Case:– Shift entire queue: Cost of O(n-1)– Do every time perform an add– Too expensive to be useful
Worst case is not that unlikely, so this suggests finding an alternative implementation.
‘Circular’ Array Implementation
Basic Idea: Allow the queue to wrap-around
Implement with addition mod size: tail = (tail + 1) % queueSize;
01
2
3
4
N-1
N-2J1
J2
J3
J4
01
2
3
4
N-1
N-2J2J3J1
Linked Queues• Problems with implementing queues on top
of arrays– Sizing problems (bounds, clumsy resizing, …)– Non-circular Array – Data movement problem
• Now that have the concepts of list nodes, can take advantage of to represent queues.
• Need to determine appropriate way of:– Representing front and rear– Facilitating node addition and deletion at the
ends.
Linked Queues
Class QueueNode{friend class Queue;public:
QueueNode(int d, QueueNode * l); private:
int data;QueueNode *link;
};
Linked Queues
class Queue{
public:Queue();~Queue();void Add(const int);int* Delete(int&);bool isEmpty();
private:QueueNode* front;QueueNode* rear;void QueueEmpty();
}
Linked Queues
Queue::Queue(){
front = 0;rear = 0;
}bool Queue::isEmpty(){
return (front == 0);}
Front Rear
0 0
Linked Queuesvoid Queue::Add(const int y){
// Create a new node that contains data y// Has to go at end// Set current rear link to new node pointer// Set new rear pointer to new node pointerrear = rear->link = new QueueNode(y, 0);
}
CAT
Front
MATHAT
Rear Rear
Linked Queuesint * Queue::Delete(int & retValue){
// handle empty caseif (isEmpty()) {return 0;}QueueNode* toDelete = front;retValue = toDelete.data;front = toDelete->link;delete toDelete;return &retValue;
}
CAT
Front
MATHAT
ReartoDelete
HAT
returnValue
Front
Queue DestructorQueue destructor needs to remove all nodes
from head to tail.
CAT
Front
MATHAT
RearFront FrontTemp Temp
0 0if (front) {QueueNode* temp;while (front != rear) {
temp = front;front = front -> link;delete temp; }
delete front;front = rear = 0; }
Front vs Delete
• Implementation as written has to remove the item from the queue to read data value.
• Some implementations provide two separate functions:– Front() which returns the data in the first
element– Delete() which removes the first element from
the queue, without returning a value.