2. Introduction to Queues
The queue data structure is very similar to the stack.
In a stack, all insertions and deletions occur at one
end, the top, of the list.
In the queue, as in the stack, all deletions occur at the
head (front) of the list.
However, all insertions to the queue occur at the tail
(back or rear) of the list.
3. Introduction to Queues
Basically, data enters the queue at one end and exits
at the other end.
This characteristic gives a queue its first-in, first-out
(FIFO) behavior.
4. ADT Queue
Collection of Data Elements:
An ordered collection of data items with the property that items can be removed only at one end, called
the front of the queue, and items can be added only at the other end, called the rear (end) of the queue
Basic Operations:
1. MAKENULL(Q): Makes Queue Q be an empty list.
2. FRONT(Q): Returns the first element on Queue Q.
3. ENQUEUE(x,Q): Inserts element x at the rear (end) of Queue Q.
4. DEQUEUE(Q): Deletes the first element of Q.
5. EMPTY(Q): Returns true if and only if Q is an empty queue.
5. Implementation
Static
Queue is implemented by an array, and size of
queue remains fix
Dynamic
A queue can be implemented as a linked list, and
expand or shrink with each enqueue or dequeue
operation.
6. Enqueue
The queue insert is known as enqueue.
After the data has been inserted, this new element
becomes the rear of the queue.
7. Dequeue
The queue delete operation is known as dequeue.
The data at the front of the queue is returned to the
user and deleted from the queue.
9. Queue Front
Data at the front of the queue can be examined with
queue front.
This function returns the data at the front of the queue
but does not remove it from the queue.
10. Queue Rear
Similar to queue front is queue rear.
This function examines the data stored in the rear
element of the queue, but does not remove it.
13. Linked List Implementation
Several data structures could be used to implement a
queue (including an array).
However, we will discuss a linked list implementation
first.
As with any linked list, we have 2 structures:
List
Node
14. Linked List Implementation
The List structure contains the metadata (e.g., number
of elements in the queue) and pointers to the front and
rear elements of the queue.
The Node structure contains the data and a pointer to
the next element in the queue.
16. Queue Algorithms
We now develop the pseudocode to implement some
basic operations that can be performed on a queue.
Then, we will discuss an actual C++ implementation.
17. Create Queue
This function initializes the metadata for the queue structure.
? ?
count front
queue
0 count = 0
Pseudocode
front = NULL
rear = NULL
rear
? 0
0
18. Enqueue
This function inserts an element into the queue.
We need to:
Allocate memory for the new node.
Update the link field of the rear node to point to the
new rear (the inserted element).
Update the rear pointer to point to the new rear
element of the queue.
Increment the count of nodes in the queue.
21. Dequeue
This function removes an element from the
queue.
We need to:
Return the data at the front of the queue.
Recycle the memory from the front node.
Update the front pointer to point to the new
front of the queue.
Decrement the count of nodes in the queue.
22. Dequeue
Pseudocode
dltPtr = front
3
count front
queue
134
39
Here, we want to remove the
first node in the queue (39).
75
0
dltPtr
delete dltPtr
(available)
2
dataOut = front->data
front = front->link
0
dataOut
rear
23. Dequeue Pseudocode
if( queue not empty )
dltPtr = front
dataOut = front->data
front = front->link
delete dltPtr
count--
if( count == 0)
rear = NULL
end if
end if
24. Queue Front
This function returns the data from the front of the
queue, but does not remove the node from the
queue.
if (queue empty)
success = false
else
dataOut = front->data
success = true
end if
return success
25. Queue Rear
This function returns the data from the rear of the
queue, but does not remove the node from the
queue.
if (queue empty)
success = false
else
dataOut = rear->data
success = true
end if
return success
26. IsEmpty Queue
This function checks to see if the queue is empty.
if (queue empty)
return true
else
return false
end if
27. Queue Count
This function returns the number of elements
currently in the queue.
return count
28. Destroy Queue
This function deletes all of the elements in the
queue.
loop (front not null)
dltPtr = front
front = front->next
delete dltPtr
end loop
rear = null
count = 0
29. Applications
Computers use queues in a variety of applications:
To service print requests (the first print job in the queue
gets serviced first … ever have to wait for your print job at
the computer lab?)
Most computers only have 1 processor so processes must
wait in a queue to get serviced by the processor.
Packets traveling over the internet arrive at routers and
other internet hardware and are processed in the order in
which they arrive.
30. A class for Dynamic Queue implementation
class DynIntQueue
{
private:
struct QueueNode
{
int value;
QueueNode *next;
};
QueueNode *front;
QueueNode *rear;
int numItems;
public:
DynIntQueue(void);
~DynIntQueue(void);
void enqueue(int);
int dequeue(void);
bool isEmpty(void);
void makeNull(void);
};
32. //********************************************
// Function enqueue inserts the value in num *
// at the rear of the queue. *
//********************************************
void DynIntQueue::enqueue(int num)
{
QueueNode *newNode;
newNode = new QueueNode;
newNode->value = num;
newNode->next = NULL;
if (isEmpty())
{
front = newNode;
rear = newNode;
}
else
{
rear->next = newNode;
rear = newNode;
}
numItems++;
}
33. //**********************************************
// Function dequeue removes the value at the *
// front of the queue, and copies it into num. *
//**********************************************
int DynIntQueue::dequeue(void)
{
QueueNode *temp;
int num;
if (isEmpty())
cout << "The queue is empty.n";
else
{
num = front->value;
temp = front->next;
delete front;
front = temp;
numItems--;
}
return num;
}
36. Program
// This program demonstrates the DynIntQeue class
void main(void)
{
DynIntQueue iQueue;
cout << "Enqueuing 5 items...n";
// Enqueue 5 items.
for (int x = 0; x < 5; x++)
iQueue.enqueue(x);
// Deqeue and retrieve all items in the queue
cout << "The values in the queue were:n";
while (!iQueue.isEmpty())
{
int value;
value =iQueue.dequeue();
cout << value << endl;
}
}
38. Array Implementation
We can also implement the queue data structure using
an array.
There are a couple of differences between the linked
list approach and the array approach.
First, the front and rear of the queue are represented as
indices into the array instead of as pointers.
Also, we’ll need to store the max number of elements
we can store in the queue (i.e., the size of the array).
Finally, we can eliminate link fields (the array is a
contiguous structure).
40. Array Implementation
First Element
Last Element
maxlength
Front
Second
Element
.
.
Rear
When queue is empty both front
and rear are set to -1
While enqueueing increment
rear by 1, and while dequeueing
increment front by 1
When there is only one value in
the Queue, both rear and front
have same index
41. Array Implementation
5 4 6 7 8 7 6
0 1 2 3 4 5 6 7 8
Front=0
Rear=6
8 7 6
0 1 2 3 4 5 6 7 8
Front=4
Rear=6
7 6 12 67
0 1 2 3 4 5 6 7 8
Front=5
Rear=8
How can we insert more elements? Rear index can
not move beyond the last element….
42. Solution: Using circular queue
Allow rear to wrap around the array.
if(rear == queueSize-1)
rear = 0;
else
rear++;
Or use module arithmetic
rear = (rear + 1) % queueSize;
44. Implementation
class IntQueue
{
private:
int *queueArray;
int queueSize;
int front;
int rear;
int numItems;
public:
IntQueue(int);
~IntQueue(void);
void enqueue(int);
int dequeue(void);
bool isEmpty(void);
bool isFull(void);
void clear(void);
};
Note, the member function clear, which clears the queue by resetting the
front and rear indices, and setting the numItems to 0.
46. //********************************************
// Function enqueue inserts the value in num *
// at the rear of the queue. *
//********************************************
void IntQueue::enqueue(int num)
{
if (isFull())
cout << "The queue is full.n";
else
{
// Calculate the new rear position
rear = (rear + 1) % queueSize;
// Insert new item
queueArray[rear] = num;
// Update item count
numItems++;
}
}
47. //*********************************************
// Function dequeue removes the value at the *
// front of the queue, and copies t into num. *
//*********************************************
int IntQueue::dequeue(void)
{
if (isEmpty())
cout << "The queue is empty.n";
else
{
// Retrieve the front item
int num = queueArray[front];
// Move front
front = (front + 1) % queueSize;
// Update item count
numItems--;
}
return num;
}
51. //Program demonstrating the IntQueue class
void main(void)
{
IntQueue iQueue(5);
cout << "Enqueuing 5 items...n";
// Enqueue 5 items.
for (int x = 0; x < 5; x++)
iQueue.enqueue(x);
// Attempt to enqueue a 6th item.
cout << "Now attempting to enqueue again...n";
iQueue.enqueue(5);
// Deqeue and retrieve all items in the queue
cout << "The values in the queue were:n";
while (!iQueue.isEmpty())
{
int value;
iQueue.dequeue(value);
cout << value << endl;
}
}
52. Program Output
Enqueuing 5 items...
Now attempting to enqueue again...
The queue is full.
The values in the queue were:
0
1
2
3
4
53. Another implementation of Queues
using Arrays
class CQueue
{
int Data*,QueueSize,Front,Rear;
public:
CQueue(int size);
~CQueue(int size);
bool IsFull();
bool IsEmpty();
void Enqueue(int num);
int Dequeue();
void MakeNull;
};
55. int CQueue ::Dequeue(int num);
{
if (IsEmpty()) { cout<<“Underflow”; return; }
int ReturnValue=Data[Front];
if (Front==Rear) //only one element in the queue
Front=Rear=-1;
else
Front=(Front+1) % QueueSize;
return ReturnValue;
}