Data StructuresData Structures
Lecture 13: Lecture 13: QUEUESQUEUES
Azhar MaqsoodNUST Institute of Information Technology (NIIT)
A queue is an ordered collection of items from A queue is an ordered collection of items from which items may be deleted at one end (called which items may be deleted at one end (called the the front front of the queue) and into which items of the queue) and into which items may be inserted at the other end (called the may be inserted at the other end (called the rearrear of the queue) of the queue)
DefinitionsDefinitions Data structure which implements a Data structure which implements a first-in, first-out first-in, first-out
listlist; e.g. print queue, which contains a list of jobs to ; e.g. print queue, which contains a list of jobs to be printed in order.be printed in order.
In In pprogramming, a queue is a , a queue is a data structuredata structure in which in which elements are removed in the same order they were elements are removed in the same order they were entered. This is often referred to as FIFO (first in, entered. This is often referred to as FIFO (first in, first out). first out).
In contrast, a In contrast, a stackstack is a data structure in which is a data structure in which elements are removed in the reverse order from which elements are removed in the reverse order from which they were entered. This is referred to as LIFO (last in, they were entered. This is referred to as LIFO (last in, first out). first out).
Introduction to QueuesIntroduction to Queues The queue data structure is very similar to the The queue data structure is very similar to the
stack.stack. In a stack, all insertions and deletions occur at one In a stack, all insertions and deletions occur at one
end, the top, of the list.end, the top, of the list. In the queue, as in the stack, all deletions occur at In the queue, as in the stack, all deletions occur at
the head of the list.the head of the list. However, all insertions to the queue occur at the However, all insertions to the queue occur at the
tail of the list.tail of the list.
Introduction to QueuesIntroduction to Queues
Basically, data enters the queue at Basically, data enters the queue at one end and exits at the other end.one end and exits at the other end.
AA BB CC
Front Rear
BB CC
Front Rear
Introduction to QueuesIntroduction to Queues
You get in line at the end and get serviced You get in line at the end and get serviced when you get to the front of the line.when you get to the front of the line.
This characteristic gives a queue its first-in, This characteristic gives a queue its first-in, first-out (FIFO) behavior.first-out (FIFO) behavior.
ApplicationsApplications
Ticketing counterTicketing counter Bus stop lineBus stop line Bank CustomersBank Customers Printer SPOOLPrinter SPOOL CPU Scheduling (at times)CPU Scheduling (at times) Etc etc etcEtc etc etc
Queue OperationsQueue Operations
Initialize the queue, Initialize the queue, QQ, to be the empty queue. , to be the empty queue. Determine whether or not if the queue Determine whether or not if the queue QQ is is
empty. empty. Determine whether or not if the queue Determine whether or not if the queue QQ is is
full. full. Insert (enqueue) a new item onto the rear of Insert (enqueue) a new item onto the rear of
the queue the queue QQ. . Remove (dequeue) an item from the front of Remove (dequeue) an item from the front of
QQ, provided , provided QQ is nonempty. is nonempty.
Queue OperationsQueue Operations
isEmpty()isEmpty() – check to see if the queue is – check to see if the queue is empty.empty.
isFull() isFull() – check to see if the queue is – check to see if the queue is full.full.
enqueue(element)enqueue(element) - put the element - put the element at the end of the queue.at the end of the queue.
dequeue() dequeue() – take the first element – take the first element from the queue.from the queue.
first() first() – return the first element in the – return the first element in the queue without removing it.queue without removing it.
EnqueueEnqueue
The queue insert is known as The queue insert is known as enqueueenqueue.. After the data has been inserted, this new After the data has been inserted, this new
element becomes the rear of the queue.element becomes the rear of the queue.
DequeueDequeue
The queue delete operation is known as The queue delete operation is known as dequeuedequeue..
The data at the front of the queue is returned to The data at the front of the queue is returned to the user and deleted from the queue.the user and deleted from the queue.
Array Array ImplementationImplementation
Any implementation of a queue requires: storage for the data as well as markers (“pointers”) for the front and for the back of the queue.
An array-based implementation would need structures like items, an array to store the elements of the queue Front, an index to track the front queue element
Rear, an index to track the position following last queue element
Additions to the queue would result in incrementing Rear. Deletions from the queue would result in incrementing Front.
Clearly, we’d run out of space soon!
Queue using ArraysQueue using Arrays#define length 10#define length 10Struct queueStruct queue{{
int items[length];int items[length];int front, rear;int front, rear;
}}
Insert(q,x)Insert(q,x)q.items[++q.rear]=x;q.items[++q.rear]=x;
X=remove(q)X=remove(q)x=q.items[q.front++];x=q.items[q.front++];
C
BAq.front=0
q.rear=-1
q.front=0
q.rear=2
•The queue is empty whenever q.rear<q.front
•The number of elements in the queue at any time is equal to the value of q.rear –q.front +1
0
1
2
3
4
0
1
2
3
4
= q.frontC q.rear=2 C
E
q.front=2
q.rear=4
D
•Now there are 3 elements the queue but there is room for 5
•If to insert F in the queue the q.rear must be increased by 1 to 5 and q. items[5] must be set to the value F. but q.items is an array of only 5 elements so this insertion cannot be made
0
1
2
3
4
0
1
2
3
4
Solution to ProblemSolution to Problem
Clearly, we’have run out of space
Solutions include:• Shifting the elements downward with each deletion • Viewing array as a circular buffer, i.e. wrapping the
end to the front
Solution 1Solution 1
For arrays there are two methodsFor arrays there are two methods First is do it as we do in real worldFirst is do it as we do in real world
Check if array is not emptyCheck if array is not emptySimply dequeue from the first location Simply dequeue from the first location
of array say array[0] i.e. the zeroof array say array[0] i.e. the zerothth index indexAfter dequeue shift all the elements of After dequeue shift all the elements of
the array from array[index] to the array from array[index] to array[index-1]array[index-1]
DequeueDequeue
AA BB CC DD
Rear
BB CC DD
Rear
DE-QUEUE
0 1 2 3 4
0 1 2 3 4
Dequeue OperationDequeue Operation
x=q.items[0];x=q.items[0];
for(i=0; i<q.rear; i++)for(i=0; i<q.rear; i++)
q.items[i]=q.items[i+1]q.items[i]=q.items[i+1]
q.rear--;q.rear--;
Method is costly as we have to move all the Method is costly as we have to move all the elements of the arrayelements of the array
Do we need Front Index in this case?Do we need Front Index in this case? No, Because we are always dequeue(ing) from the first No, Because we are always dequeue(ing) from the first
indexindex
Solution2: Circular QueueSolution2: Circular Queue To avoid the costly operation of coping all the To avoid the costly operation of coping all the
elements again we employ another method called elements again we employ another method called circular queuecircular queue
Simply dequeue the element and move the front Simply dequeue the element and move the front pointer to next indexpointer to next index
If If q.rear==q.front q.rear==q.front queue is emptyqueue is empty q.front=q.rear=max_size-1;q.front=q.rear=max_size-1;
q[3]
?
q[4]
?
q[5]
?
q[0]
?
q[1] q[2]
? ?
frontMAX_SIZE = 6
back
ImplementationImplementationStruct queueStruct queue{{
int items[length];int items[length];int front, rear;int front, rear;
};};Struct queue q;Struct queue q;q.front=q.rear=Max_size –1;q.front=q.rear=Max_size –1;
bool IsEmpty(struct queue bool IsEmpty(struct queue *pq)*pq)
{{return(pq->front==pq-return(pq->front==pq->rear)>rear)
}}
int remove (struct queue *pq)int remove (struct queue *pq){{ if (empty(pq)){if (empty(pq)){
cout<<“queue cout<<“queue underflow”underflow”
return 0;return 0;}}If (pq->front==Max_size-1)If (pq->front==Max_size-1)
pq->front=0;pq->front=0;elseelse
(pq->front)++;(pq->front)++;Return(pq->items[pq->front])Return(pq->items[pq->front])}}
Implementation cont.Implementation cont.int insert(struct queue *pq, int x)int insert(struct queue *pq, int x){{
//make room for new element//make room for new elementIf (pq->rear==Max_size-1)If (pq->rear==Max_size-1)
pq->rear=0;pq->rear=0;elseelse
(pq->rear)++;(pq->rear)++;
//Check for overflow//Check for overflowIf (pq->rear==pq->front)If (pq->rear==pq->front){{
cout<<“queue overflow”;cout<<“queue overflow”;exit(1);exit(1);
}}pq->items[pq->rear]=x;pq->items[pq->rear]=x;
return;return;}}
Queue OperationsQueue Operations
q[3]
?
q[4]
?
q[5]
?
q[0]
?
q[1] q[2]
? ?
back
front
q[3]
?
q[4]
?
q[5]
?
q[0]
A
q[1] q[2]
? ?
front
back
q[3]
?
q[4]
?
q[5]
?
q[0]
A
q[1] q[2]
D ?
front
back
q[3]
?
q[4]
?
q[5]
?
q[0]
A
q[1] q[2]
D T
front
back
Queue Operations cont.Queue Operations cont.
q[3]
E
q[4]
?
q[5]
?
q[0]
A
q[1] q[2]
D T
front
back
q[3]
E
q[4]
?
q[5]
?
q[0]
A
q[1] q[2]
D T
front
back
q[3]
E
q[4]
?
q[5]
?
q[0]
A
q[1] q[2]
D T
front
back
q[3]
E
q[4]
?
q[5]
?
q[0]
A
q[1] q[2]
D T
front
back
Queue Operations cont.Queue Operations cont.
q[3]
E
q[4]
X
q[5]
?
q[0]
A
q[1] q[2]
D T
front
back
q[3]
E
q[4]
X
q[5]
A
q[0]
A
q[1] q[2]
D T
front
q[3]
E
q[4]
X
q[5]
A
q[0]
M
q[1] q[2]
D T
front
back
wrap-around
back
Circular QueueCircular Queue
[2] [3] [2] [3]
[1] [4] [1] [4]
[0] [5] [0] [5]
J2
J1
J3
Can be seen as a circular queue
Problems with above solutionProblems with above solution
How to know if the queue is empty How to know if the queue is full What is the relation between front and back when
queue is full?
Solution
1. Keep it simple… add counter to the queue
2. Keep an empty slot between Front and Rear i.e., items array uses QUEUE_CAPACITY - 1 elements
Solution (a)Solution (a)
define MAXQUEUESIZE 100; define MAXQUEUESIZE 100; struct {struct {
char personName[25];char personName[25];
int personNIC;int personNIC;//lets assume NIC to be integer type. //lets assume NIC to be integer type.
} Person;} Person;
struct { struct { int Count; /* number of queue items */ int Count; /* number of queue items */
int Head; /* head of queue */ int Head; /* head of queue */
int Tail; /* tail of queue */ int Tail; /* tail of queue */
Person Items[MAXQUEUESIZE]; Person Items[MAXQUEUESIZE];
}Queue; }Queue;
Solution (a) cont.Solution (a) cont.
void InitializeQueue(Queue *Q) void InitializeQueue(Queue *Q) { { Q->Count = 0; /* zero count of items */Q->Count = 0; /* zero count of items */
Q->Head = MAXQUEUESIZE-1; Q->Head = MAXQUEUESIZE-1; Q->Tail = MAXQUEUESIZE-1; Q->Tail = MAXQUEUESIZE-1;
} }
int Empty(Queue *Q) int Empty(Queue *Q) { return (Q->Count == 0); } { return (Q->Count == 0); }
int Full(Queue *Q)int Full(Queue *Q) { return (Q->Count == MAXQUEUESIZE); } { return (Q->Count == MAXQUEUESIZE); }
FULL QUEUE FULL QUEUE
[2] [3] [2] [3]
[1] [4][1] [4]
[0] [5] [0] [5]
front =0rear = 5
front =4rear =3
J2 J3
J1 J4
J5 J6 J5
J7
J8 J9
Solution b:Leave one empty space Solution b:Leave one empty space when queue is fullwhen queue is full
EMPTY QUEUE
[2] [3] [2] [3]
[1] [4] [1] [4]
[0] [5] [0] [5]
front = 0 front = 0 rear = 0 rear = 3
J2
J1
J3
Top Related