Updated Slides of Queue Data Structure (Fall-2023)
Updated Slides of Queue Data Structure (Fall-2023)
structure
Course Instructor:
Inayat-ur-Rehman, PhD
COMSATS University, Islamabad
1
WORDS OF WISDOM
Review of What is
Topics Stack vs
Last Topic : Queue
Covered Queue?
STACK (FIFO)?
Operations of What is
Operations of
Queue Circular
Circular
(Enqueue, Queue
Queue
Dequeue) (FIFO)?
Front Rear
rear
rear
QUEUE AT BUS STOP
Front
Rear
rear
QUEUE AT BUS STOP
rear
Front Rear
STACK VS QUEUE
APPLICATIONS OF QUEUES IN CS
Shared Printer
Operating system Communication Software
BASIC OPERATIONS OF QUEUE
Enqueue – insert at end
Dequeue – delete from front
Is_empty()
Is_full()
Front()
Static Dynamic
Queue is implemented by an A queue can be implemented
array, and size of queue as a linked list, and expand
remains fix or shrink with each enqueue
or dequeue operation.
STATIC QUEUE IMPLEMENTATION
Front
First Element
When queue is empty both front and rear are set to -1
Second While enqueueing increment rear by 1, and while
Element
.
.
dequeueing increment front by 1
When there is only one value in the Queue, both rear
Rear and front have same index (0)
Last Element
maxlength
IMPLEMENTATION OF QUEUES
12. else{
13. rear++;
14. }
15. q[rear]=x;
16. }
17. }
DEQUEUE OPERATION
1. int Dequeue()
2. {
3. if (is_empty())
4. {
5. cout<<“Queue is already empty”;
6. return -1;
7. }
8. else
9. {
10. int x= q[front];
11. if(front==rear)
12. {
13. front=rear=-1;
14. }else{
15. front++;
16. }
17. return x;
18. }
MAIN METHOD
1. Void main ()
2. {
3. Que q1; //Default constructor: object of que class with default
size
4. Que q2(5); //Overloaded constructor: object of que class (q2) with
size 5
5. Que q3(15);
6. q1.enqueue(5);
7. q2.enqueue(7);
8. q3.enqueue(6);
9. int x= q2.dequeue();
10.Cout<<“Dequeued element from q3 is: “<<x;
Shifting values/Quiz
4 5 7 2
0 1 2 3 4 5 6 7
Front=0 Rear = 3
5 7 2 2
0 1 2 3 4 5 6 7
After Dequeue();
Front=0 Rear = 2
Value at index 3 is now garbage as it is repeated, so
after new equeue() new value will be at index 3.
Hence value 2 at index 3 will be overwritten.
DYNAMIC QUEUE IMPLEMENTATION
PROBLEMS RELATED TO ARRAY
IMPLEMENTATION OF QUEUES
Front = 3 Rear = 5
Question:
What to do now?
SOLUTIONS
• Shift the elements while dequeuing
– Not efficient solution
• Implement by Circular Queue
Circular Queue
CIRCULAR IMPLEMENTATION
• We can see that , in this implementation the
first element immediately follows last
element.
• Even if the last element is occupied , we can
insert new element in the first position, as
long as the first element is empty.
• In this implementation , we have an additional
variable count , to keep track of the number of
elements in the queue.
SOLUTION: USING CIRCULAR QUEUE
• If the queue is not full and rear is at size-1?
if(rear == queueSize-1)
rear = 0;
else
rear++;
• Or use module arithmetic
rear = (rear + 1) % queueSize;
EXAMPLE-1
When the queue is empty: front=rear=-1;
After enqueuer(8) front and rear will move to index 0.
front
Size - 1 rear
0
5 2
4 3
CIRCULAR ARRAY
To enqueue, advance the REAR pointer, and insert in its
new position.
Size - 1 0 front
To dequeue the element, we
move the front to new 6 2 1
location by: 4
F=(f+1)%queue_size 1
5 2
so 7
F= (0+1)%8 = 1 Rear
4 3
EMPTY
Size - 1 0
Rear front
Size - 1 0
Front = 0 and Rear = size-1 6 9 2 1
7 4
4 6 2
5 5 7
4 3
FULL CASE-2
Size - 1 0
6 1 7 1
count = size;
if(Rear+1)%queue_size = = front 4 4 Full !!
2 3 2
5 9 7
front
4 3
Rear
ENQUEUE
EXAMPLE-2 OPERATION
0 1 2 3 4 5 6 7 8
Front= -1
Rear= -1
Enqueue 9 As the queue is empty so we move front and rear to 0
9
0 1 2 3 4 5 6 7 8
Front=0
Rear=0
9 3
0 1 2 3 4 5 6 7 8
Front=0
9 5 1 6
0 1 2 3 4 5 6 7 8
Front=5 Display Queue
Rear=8
3 4 2 3 9 7 6 5 1
0 1 2 3 4 5 6 7 8
Front=5
Rear=4
if(rear+1%queue_size==front) – FULL
(4+1)%9 = = 5
DEQUEUE OPERATION
7 6 5 1
0 1 2 3 4 5 6 7 8
Front=5
Rear=8
3 4 1
0 1 2 3 4 5 6 7 8
Front=8
Rear=1
3 4
0 1 2 3 4 5 6 7 8
Front=0
Rear=1
DEQUEUE OPERATION
1
0 1 2 3 4 5 6 7 8
Front=8
Rear=8
0 1 2 3 4 5 6 7 8
Front= -1 QUEUE
Rear= -1
BECOMES
EMPTY
void Equeue(int x )
{
if(Is_full())
{
cout<<“Queue is already full”;
}
else{
if(IsEmpty())
{
front=rear=0;
}
else
{
Rear=(Rear+1) % QueueSize;
}
que[rear]=x;
}
int Dequeue( )
{
if (IsEmpty())
{
cout<<“Underflow”;
return -1;
}
else
{
int ReturnValue=Data[Front];
if (Front==Rear) //only one element in
the queue
Front=Rear=-1;
else
Front=(Front+1) % QueueSize;
return ReturnValue;
}
bool IsEmpty()
{
if (Front==-1)
return true;
else return false;
}
bool IsFull()
{
if (((Rear+1)%QueueSize)==Front)
return true;
else return false;
}
Double Ended Queue (Deque)
49
ADT Deque
• Need for an ADT which offers
– Add, remove, retrieve
– At both front and back of a queue
• Double ended queue
– Called a deque
– Pronounced “deck”
• Actually behaves more like a combination of Stack and Queue
ADT Deque
Double-Ended Queues (deque)( "D.Q.")
Supports insertion and deletion at both the front and the rear of the queue.
The Deque Abstract Data Type
• addFirst(e): Insert a new element e at the beginning of the deque.
• addLast(e): Insert a new element e at the end of the deque.
• removeFirst(): Remove and return the first element of the deque; an error occurs if
the deque is empty.
• removeLast(): Remove and return the last element of the deque; an error occurs if
the deque is empty.
• getFirst(): Return the first element of the deque; an error occurs if the deque is
empty.
• getLast(): Return the last element of the deque; an error occurs if the deque is empty.
• size(): Return the number of elements of the deque.
• isEmpty(): Determine if the deque is empty.
Double-Ended Queues (cont.)
• Operation Output D
• addFirst(3) - (3)
• addFirst(5) - (5,3)
• removeFirst() 5 (3)
• addLast(7) - (3,7)
• removeFirst() 3 (7)
• removeLast() 7 ()
• removeFirst() "error" ()
• isEmpty() true ()
Implementing a Deque
• There are:
– Input-restricted Deque.
– Output-restricted Deque.
• Bellow show a figure a empty Deque Q[5] which
can accommodate five elements.
deletion insertion
insertion deletion
Q[0] Q[1] Q[2] Q[3] Q[4]
Fig: A Deque
Double Ended Queue (Deque)
There are:
Input-restricted Deque: An input restricted Deque
deletion 10 20 30 40 50 insertion
deletion
Q[0] Q[1] Q[2] Q[3] Q[4]
There are:
Output-restricted Deque: on the contrary, an
insertion 10 20 30 40 50 insertion
deletion
Q[0] Q[1] Q[2] Q[3] Q[4]
while( !thePQ.isEmpty() )
{
long item = thePQ.remove();
cout<<item<<“ “; // 10, 20, 30, 40, 50 Note: ORDERED!
} // end while
} // end main()
//-------------------------------------------------------------
} // end class PriorityQApp
62
Array implementations
• A priority queue could be implemented as an unsorted array (with a count
of elements)
– Adding an element would take O(1) time (why?)
– Removing an element would take O(n) time (why?)
– Hence, adding and removing an element takes O(n) time
– This is an inefficient representation
• A priority queue could be implemented as a sorted array (again,
with a count of elements)
– Adding an element would take O(n) time (why?)
– Removing an element would take O(1) time (why?)
– Hence, adding and removing an element takes O(n) time
– Again, this is inefficient
63
Linked list implementations
•A priority queue could be implemented as an unsorted linked list
– Adding an element would take O(1) time (why?)
– Removing an element would take O(n) time (why?)
•A priority queue could be implemented as a sorted linked list
– Adding an element would take O(n) time (why?)
– Removing an element would take O(1) time (why?)
•As with array representations, adding and removing an element takes O(n) time
– Again, these are inefficient implementations
– Efficient implementations of priority queues can be done using balanced binary tree
implementations …… we will see in the coming lectures.
64
References
• Dr. Yasir Faheem, COMSATS University, Islamabad
• C++ plus data structures / Nell Dale
• Data Structures and Algorithms in C++, Second Edition by
Adam Drozdek
• https://www.geeksforgeeks.org/