0% found this document useful (0 votes)
9 views

CS DataStructure-Lecture 3-Queues Arrays and Linked

Data strructure

Uploaded by

AsmaaGhoniem
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

CS DataStructure-Lecture 3-Queues Arrays and Linked

Data strructure

Uploaded by

AsmaaGhoniem
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

Data Structure

Dr. Ahmed Hesham Mostafa


Lecture 3 –Queue based Arrays and
Linked
TextBooks
• s k chang, “data structures and algorithms”
• Kruse and Leung, “Data Structures & Program Design in C”
Online Martials
• CS214: Data Structures by Prof. Dr Waleed A. Yousef
• https://www.youtube.com/playlist?list=PLoK2Lr1miEm-
5zCzKE8siQezj9rvQlnca
• Data Structures Learning Course by Dr Mohammed El-Said
• https://www.youtube.com/playlist?list=PLfay0LLBd0wiNeOR_SGoYfC
3w-NxFwd0D
• Lectures Source code (updated frequently)
• https://github.com/ahmedheshamostafa/DataStructure
Motivation: Why Queue? First In First Out (FIFO)
• In a queue,
– new values are always added at the rear of the list
– values are removed from the opposite end of the list, the
front

Input D C B A Output

• Examples of queues
– checkout at supermarket
– Toll Station
• Car comes, pays, leaves
– Check-out in Big super market
• Customer comes, checks out and leaves
– More examples: Printer, Office Hours, …
© Waleed A. Yousef 2008 4
E.g., Printing Queue

• A.doc, B.doc, C.doc arrive to printer.

Now printing A.doc


C B A

A.doc is finished. Now printing B.doc


C B

D.doc comes Now still printing B.doc


D C B

B.doc is finished. Now printing C.doc


D C

C.doc is finished. Now printing D.doc


D

© Waleed A. Yousef 2008 5


Array Implementation1: Physical Model
(Front is fixed as in physical lines)

• Shifting all items to front in the array when


dequeue operation. ( Too Costly… )

• Why this was not a problem in the array


implementation of Stacks?

n-1 3 2 1 0 A leaves n-1 3 2 1 0


…… C B A …… C B

rear=2 front=0 rear=1 front=0

© Waleed A. Yousef 2008 6


Array Implementation2: Linear Model
(Two indices, front and rear)

n-1 3 2 1 0
D C B A

Max_Size rear front

After A leaves,
n-1 3 2 1 0
D C B

Max_Size rear front

© Waleed A. Yousef 2008 7


The problem is that there will be many empty places in the
front of array and rear is always incremented.

n-1 3 2 1 0
D C B A

Max_Size rear front

After A,B,C,D leave


n-1 3 2 1 0
K J I H G F E

Max_Size
rear front

© Waleed A. Yousef 2008 8


Array Implementation 3: Circular Implementation
0 Max-1
1

Occupied

Circular Queue
0 Max-1

2 Occupied

Unwinding

Front Rear
Occupied
0 1 … …

Max-1
Linear
© Waleed A. Yousef 2008
Implementation 9
Checking the Boundary conditions
Rear and Front advance in this direction

0 MAX-1
Queue with two elements
F R

Queue with one element


FR

With Empty condition:


Next to Rear = Front. R F

Queue with one element


FR

F R
Full Condition:
Next to Rear = Front
Therefore we waste one location R F 10
© Waleed A. Yousef 2008
Better solution: Use indicator variable to
distinguish between Empty and Full conditions.
Rear and Front advance in this direction

Empty queue:
Next to Rear = Front.
Size=0 R F

R F

Full queue:
Next to Rear = Front.
Size=MAX R F

© Waleed A. Yousef 2008 11


Again: Definitions, where every thing should start from!

Definition: type is a set of values and a set of operations on


those values.

Example: We can define a datatype boolean that takes the set


of values {0, 1} together with the operations AND, OR, and NOT.

Example: int, in C, is the set consisting all of the integers


between INT_MIN (-(215 − 1)) and INT_MAX (215 – 1),
which are defined in the header file limits.h

Definition: A Sequence of length 0 is empty. A sequence of


length n  1 of elements from a set T is an ordered pair (Sn-
1,t) where Sn-1 is a sequence of length n-1 of elements from T,
and t is an element of T.

© Waleed A. Yousef 2008 12


Definition: A queue of elements of type T is a finite sequence of
elements of T together with the following operations:

1. Create the queue, leaving it empty.


2. Determine whether the queue is empty or not
3. Determine whether the queue is full or not
4. Find the size of the queue
5. Append a new entry onto the top of the queue, provided the
queue is not full.
6. Retrieve the front entry in the queue, provided the queue is not
empty.
7. Serve (and remove) the front entry from the queue, provided
the queue is not empty.
8. Traverse the queue, visiting each entry
9. Clear the queue to make it empty

© Waleed A. Yousef 2008 13


User Level
typedef struct queue{ (interface)
int front;
int rear; void main(){
int size;
QueueEntry entry[MAXQUEUE]; Queue q;
}Queue;

front

rear

size

entr
© Waleed A. Yousef 2008
y 14
void CreateQueue(Queue *pq){ User Level
pq->front= 0; (interface)
pq->rear = -1;
void main(){
pq->size = 0;
}
//Initializing front =5 and rear =4 will Queue q;
work if MAXQUEUE >=6. But, since MAXQUEUE
can be 1 we intialize as above. CreateQueue(&q);

MAXQUEUE-1
}

front
&q
rear pq
size
0
entr
© Waleed A. Yousef 2008
y 15
void Append(QueueEntry e, Queue* pq){
pq->rear = (pq->rear + 1) % MAXQUEUE;
pq->entry[pq->rear] = e;
pq->size++;
} if (pq->rear == MAXQUEUE-1)
pq->rear=0;
else
pq->rear++;

MAXQUEUE-1

front
&q
pq rear

size
0
© Waleed A. Yousef 2008
entr 16
void Serve(QueueEntry *pe, Queue* pq){
*pe = pq->entry[pq->front];
pq->front = (pq->front + 1) % MAXQUEUE;
pq->size--;
}

MAXQUEUE-1

front
&q
pq rear

&e size
pe
0
© Waleed A. Yousef 2008
entr 17
int QueueEmpty(Queue* pq){
return !pq->size;
}

int QueueFull(Queue* pq){


return (pq->size == MAXQUEUE);
}

MAXQUEUE-1

front

rear

size
0
© Waleed A. Yousef 2008
entr 18
int QueueSize(Queue* pq){
return pq->size;
}
void ClearQueue(Queue* pq){
pq->front = 0;
pq->rear = -1;
pq->size = 0;
}//same as CreateQueue. No nodes to free.

MAXQUEUE-1

front

rear

size
0
© Waleed A. Yousef 2008
entr 19
void TraverseQueue(Queue* pq, void (*pf)(QueueEntry)){
int pos, s;
for(pos=pq->front, s=0; s<pq->size; s++){
(*pf)(pq->entry[pos]);
pos=(pos+1)%MAXQUEUE;
}
}

MAXQUEUE-1

front

rear

size
0
© Waleed A. Yousef 2008
entr 20
Linked Queues(to overcome fixed size limitations):
Just get the idea now, do not worry about details.
q.rear q.front q.rear q.front

Node
q
Empty Queue Queue of size 1

pn

New
node

First In Second in Last in

q.rear q.Front How to insert a node


© Waleed A. Yousef 2008 21
Linked Queues(to overcome fixed size limitations):
Just get the idea now, do not worry about details.

How to serve a node

Last in

First In Second in Before Last

q.rear q.Front

pn

© Waleed A. Yousef 2008 22


Type Definition
New
node

First In Second in Last in

typedef struct queuenode{


QueueEntry entry;
struct queuenode *next;
}QueueNode;

typedef struct queue{


QueueNode *front;
QueueNode *rear;
int size;//old trick
}Queue;
© Waleed A. Yousef 2008 23
Implementation level User Level
(what really happens) (interface)
void CreateQueue(Queue *pq){ void main(){
pq->front=NULL;
pq->rear=NULL; Queue q;
pq->size=0;
} CreateQueue(&q);

}
CreateQueue
&q
pq

q
© Waleed A. Yousef 2008 24
void Append(QueueEntry e, Queue* pq){
QueueNode*pn=(QueueNode*)malloc(sizeof(QueueNode));
pn->next=NULL;
pn->entry=e;
User Call:
Queue q;
QueueEntry e;
pq->rear->next=pn;
pq->rear=pn; Append(e, &q);
e
pq->size++; pn
}
&q
pq e

First In Second in Last in

© Waleed A. Yousef 2008 25


Always take care of special cases (queue is empty)
void Append(QueueEntry e, Queue* pq){
QueueNode*pn=(QueueNode*)malloc(sizeof(QueueNode));
pn->next=NULL;
pn->entry=e;
if (!pq->rear)
pq->front=pn;
else
pq->rear->next=pn;//run time error for empty queue
pq->rear=pn;
pq->size++;
}

&q pn
pq
e

© Waleed A. Yousef 2008 26


void Serve(QueueEntry *pe, Queue* pq){
QueueNode *pn=pq->front;
*pe=pn->entry;
pq->front=pn->next;
free(pn);

Last in
pq->size--;
}

First In Second in Before last

&q
pq pn

© Waleed A. Yousef 2008 27


Always take care of special cases: Only one element exists

void Serve(QueueEntry *pe, Queue* pq){


QueueNode *pn=pq->front;
*pe=pn->entry;
pq->front=pn->next;
free(pn);
if (!pq->front)
pq->rear=NULL;
pq->size--;
}
Last in

&q
pq pn

© Waleed A. Yousef 2008 28


Implementation level User Level
(what really happens) (interface)
int QueueEmpty(Queue* pq){ void main(){
return !pq->front;
} Queue q;

int QueueFull(Queue* pq){ CreateQueue(&q);


return 0;
}
}
int QueueSize(Queue* pq){
return pq->size;
}
&q
pq

q
© Waleed A. Yousef 2008 29
void ClearQueue(Queue* pq){
while(pq->front){
pq->rear=pq->front->next;
free(pq->front);
pq->front=pq->rear;
}
pq->size = 0;
}/*Moving with two pointers,
Exactly as in LinkedStacks*/ Last in

First In Second in Before last

&q
pq

© Waleed A. Yousef 2008 30


void TraverseQueue(Queue* pq, void(*pf)(QueueEntry)){
for(QueueNode *pn=pq->front; pn; pn=pn->next)
(*pf)(pn->entry);
}

Last in

First In Second in Before last

&q
pq
pn
© Waleed A. Yousef 2008 31
Very important note for all linked structures. E.g., in Queues:
In Push and Append we have to check for exhausted memory. The code can be
modified to:

int Append(QueueEntry e, Queue* pq){


QueueNode*pn=(QueueNode*)malloc(sizeof(QueueNode));
if (!pn)
return 0;
/*This is much better than the Error message of the book
because this is more flexible. Also, the same function for
contiguous implementation has to return 1 always to have consistent
interface*/
else{
//Put here exactly all of the remaining code
return 1; ...;
} If (!Append(e, &q)){
...;
}
© Waleed A. Yousef 2008 32

You might also like