data structures lecture 13: queues azhar maqsood nust institute of information technology (niit)

Post on 14-Dec-2015

225 Views

Category:

Documents

6 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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