0% found this document useful (0 votes)
36 views47 pages

Lecture 7 - Queues

asd

Uploaded by

toprakcihalil0
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views47 pages

Lecture 7 - Queues

asd

Uploaded by

toprakcihalil0
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

SE 2005

DATA
STRUCTURES
QUEUE
Real world examples Queues in computer science

Access to shared resources:


queue of print jobs to send to
the printer

People on an escalator or
waiting in line for payment

queue of network data queue of programs /


packets to send processes to be run
QUEUE
• A queue is a homogeneous collection of elements in which
– deletions can take place only at the front end, known as dequeue
– insertions can take place only at the rear end, known as enqueue.

• The working mechanism: The element to enter the queue first will be deleted from
the queue first (First-In-First-Out (FIFO) system).
STACK VS QUEUE
• One of the main difference between stacks and queues is in removing.
– In a stack we remove the item the most recently added;
– in a queue, we remove the item the least recently added.

• Also, significant structural difference is that the queue implementation needs to keep
track of the front and the rear of the queue, whereas the stack only needs to worry
about one end: the top.
OPERATIONS ON QUEUE

Empty condition (Front = Rear = -1)


Full condition (Rear = Max-1).
Two indexes (or pointers) called FRONT When enqueuing the first
and REAR are used to keep track of the element, we set the value of
first and last elements in the queue. FRONT and REAR to 0.
When initializing the queue, we set the
value of FRONT and REAR to -1.

HOW
On enqueuing an element, we
increase the value of REAR index

QUEUE
and place the new element in the
position pointed to by REAR.

WORKS Before enqueuing, we check if the


queue is already full.

On dequeuing an element, we return When dequeuing the last


the value pointed to by FRONT and element, we reset the values
increase the FRONT index. of FRONT and REAR to -1.

Before dequeuing, we check if the


queue is already empty.
EXERCISE
enqueue(8)
enqueue(3)
dequeue()
enqueue(2)
enqueue(5)
dequeue()
enqueue(9)
Front=-1 Queue is empty Front=1 Enqueue 2

1 5 3 2
0 1 2 3 4 0 1 2 3 4
Rear=-1 Rear=2
Front=0 enqueue 8 Front=1 Enqueue 5

2 8 6 3 2 5
0 1 2 3 4 0 1 2 3 4
Rear=0 Rear=3
Front=0 enqueue 3 Front=2 dequeue

3 8 3 7 2 5
0 1 2 3 4 0 1 2 3 4
Rear=1 Rear=3
Front=1 dequeue Front=2 Enqueue 9

4 3 8 2 5 9
0 1 2 3 4 0 1 2 3 4
Rear=1 Rear=4
THE TYPES OF QUEUE
• Types
– Simple Queue
• CPU scheduling, Disk Scheduling
• Synchronization between two process.
– Circular Queue
• Memory management, Traffic Management
– Deque
• To execute undo and redo operation.
– Priority Queue
• Sorting heap

• Representations
– Queue Representation with Array
– Queue Representation with Linked List
QUEUE REPRESENTATION WITH ARRAY

// A structure to represent a queue


struct Queue {
int front, rear;
unsigned capacity;
int* array;
};

Note: The queue may contain


MAX – 1 data.
struct Queue {
int front, rear;
unsigned capacity;
int* array;
};

struct Queue* createQueue(unsigned capacity) {


struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));
queue->capacity = capacity;
queue->front = -1;
queue->rear = -1;
queue->array = (int*)malloc(queue->capacity * sizeof(int));
return queue;
}

// Queue is full when size becomes equal to the capacity


int isFull(struct Queue* queue) {
return (queue->rear == queue->capacity -1);
}

// Queue is empty when size is 0


int isEmpty(struct Queue* queue) {
return (q->front == -1 || q->front > q->rear);
}
void enqueue(struct Queue* queue, int item) {
if (isFull(queue))
return;
if(queue->front == -1)
queue->front++;

queue->array[++queue->rear] = item;

printf("%d enqueued to queue\n", item);


printf("\t%d %d\n", queue->rear, queue->front);
}

int dequeue(struct Queue* queue) {


if (isEmpty(queue))
return INT_MIN;

int item = queue->array[queue->front++];

return item;
}
It is known as a
boundary case problem.

Is this the only solution?


QUEUE REPRESENTATION WITH LINKED
LIST The front pointer contains the address of the starting element
of the queue while the rear pointer contains the address of the
last element of the queue.
• The array implementation can
not be used for the large scale
applications where the queues
are implemented.

• One of the alternative of array


implementation is linked list
implementation of queue.
ALGORITHMS FOR ENQUEUE AND
DEQUEUE OPERATIONS
Queue Front : 40
Queue Rear : 50
COMPARISONS OF QUEUE REPRESENTATION
USING LINKED LIST OVER THE ARRAY
• The array is fixed size, therefore, a number of
elements will be limited in the queue. Since
linked list is dynamic and can be changed easily,
so the number of elements can be changed.

• The pointers in linked list consume additional


memory compared to an array.

• In array implementation, sometimes dequeue


operation not possible, although there are free
slots. This drawback can be overcome in linked
list representation
CIRCULAR QUEUE
• Boundary case problem in array implementation can be
overcome in two different ways.
– The first solution is by left-shifting all elements after
every deletion.
• However, this is not suitable since after every
deletion, the entire elements required shifting left
and front and rear should be readjusted according
to that.

– The second solution is by implementing a circular


queue.
• A circular queue (also known as a circular buffer) is
a linear data structure that uses a single, fixed-size
buffer as if it were connected end-to-end.
Example: Consider the following circular queue with N = 5.
1. Initially, Rear = 0, Front = 0. 4. Insert 20, Rear = 3, Front = 1.
Front

Rear

2. Insert 10, Rear = 1, Front = 1. 5. Insert 70, Rear = 4, Front = 1.


Rear Front
Front

Rear
3. Insert 50, Rear = 2, Front = 1. 6. Delete front, Rear = 4, Front = 2.
Front Rear Front

Rear

Note: Circular Queue‘s circularity is only logical. There cannot be a physical circularity in main memory.
7. Insert 100, Rear = 5, Front = 2. 10. Delete front, Rear = 1, Front = 3.
Front Rear

Front

Rear

8. Insert 40, Rear = 1, Front = 2. 11. Delete front, Rear = 1, Front = 4.


Rear
Rear Front

Front

9. Insert 140, Rear = 1, Front = 2. 12. Delete front, Rear = 1, Front = 5.


As Front = Rear + 1, so Queue overflow. Rear

Rear Front

Front
ALGORITHMS FOR ENQUEUE AND
DEQUEUE OPERATIONS
10 enqueued to queue
20 enqueued to queue
30 enqueued to queue
40 enqueued to queue
10 dequeued from queue
Front item is 20
Rear item is 40
#include <stdio.h>
#include <stdlib.h>
#define SIZE 6

struct Queue {
int front, rear, currSize;
unsigned maxSize;
int* a;
};

struct Queue* createQueue(unsigned maxSize) {


struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue));
queue->maxSize = maxSize;
queue->front = queue->rear = -1;
queue->a = (int*) malloc(queue->maxSize * sizeof(int));
return queue;
}
// Checking for Overflow condition
int isFull(struct Queue* queue){
if ((queue->front == queue->rear + 1) || (queue->front == 0 && queue->rear == queue->maxSize - 1)){
return 1;
}
return 0;
}

// Checking for Underflow condition


int isEmpty(struct Queue* queue){
if (queue->front == -1)
return 1;

return 0;
}
// Function to do dequeue
int dequeue(struct Queue* queue)
{
int item;
// Function to do enqueue if (isEmpty(queue))
void enqueue(struct Queue* queue,int value){ {
if (isFull(queue)) printf("Can't add the queue is empty \n");
printf("Can't add the queue is full \n"); return (-1);
}
else else
{ {
if (queue->front == -1) item = queue->a[queue->front];
queue->front = 0; if (queue->front == queue->rear)
{
queue->rear = (queue->rear + 1) % queue->maxSize; queue->front = queue->rear = -1 ;
queue->a[queue->rear] = value; }
printf("%d was added\n", value); else
} {
} queue->front = (queue->front + 1) % queue->maxSize;
}
printf("%d dequeued\n", item);
}
}
// Function to print the queue
void print(struct Queue* queue) {
int i;
if (isEmpty(queue))
printf("Empty Queue\n");
else {

printf("\nThe items in the queue are : \n");

for (i = queue->front; i != queue->rear; i = (i + 1) % queue->maxSize) {


printf("%d ", queue->a[i]);
}

printf("%d \n\n", queue->a[i]);


}
}
int main() {
struct Queue* queue = createQueue(6);
dequeue(queue);//Underflow condition

enqueue(queue,12);
enqueue(queue,14);
enqueue(queue,16);
enqueue(queue,18);
enqueue(queue,20);

print(queue);
dequeue(queue);
dequeue(queue);

print(queue);

enqueue(queue,22);
enqueue(queue,24);
enqueue(queue,26);
enqueue(queue,28);//Overflow condition
print(queue);

return 0;
}
A DOUBLE-ENDED QUEUE (DEQUE)
• A linear list that generalizes a queue, in which the insertion and deletion operations are
performed at both the ends (front and rear), but not in the middle (FIFO rule).
– It is also often called a head-tail linked list

• Deque can be represented in 2 ways;


– Input Restricted Double Ended Queue
– Output Restricted Double Ended Queue
A DOUBLE-ENDED QUEUE (DEQUE)
• Input Restricted Double Ended Queue: Insertions can be made at only one end of the
list but deletions can be made from both ends of the list

• Output Restricted Double Ended Queue: Deletions can be made from only one end
of the list but insertions can be made at both ends of the list
OPERATIONS
• There are four basic operations in usage of Deque.
– Insertion at rear end
– Insertion at front end
– Deletion at front end
– Deletion at rear end

• In addition to above operations, following operations are also


supported :
– getFront() : Gets the front item from queue.
– getRear() : Gets the last item from queue.
– isEmpty() : Checks whether Deque is empty or not.
– size() : Gets number of elements in Deque.
– erase() : Deletes all the elements from Deque.
INSERTION AT REAR END
FOR ARRAY IMPLEMENTATION
INSERTION AT FRONT END
FOR ARRAY IMPLEMENTATION
INSERTION
FOR LINKED LIST IMPLEMENTATION
Insertion at Front end : Insertion at Rear end :
DELETION AT FRONT END
FOR ARRAY IMPLEMENTATION
DELETION AT REAR END
FOR ARRAY IMPLEMENTATION
DELETION
FOR LINKED LIST IMPLEMENTATION

Deletion from Front end : Deletion from Rear end :


Examples
USING QUEUES: CODED MESSAGES
• A Caesar cipher is a substitution code that encodes
a message by shifting each letter in a message by a
constant amount k
• If k is 5, a becomes f, b becomes g, etc.
• Example: n qtaj ofaf
• Used by Julius Caesar to encode military messages
for his generals (around 50 BC)
• This code is fairly easy to break!
USING QUEUES: CODED MESSAGES
• Modern version: ROT13
• Each letter is shifted by 13
• “used in online forums as a means of hiding
spoilers, punchlines, puzzle solutions, and
offensive materials from the casual glance”
(Wikipedia)
USING QUEUES: CODED MESSAGES
• An improvement: change how much a letter is shifted
depending on where the letter is in the message
• A repeating key is a sequence of integers that determine
how much each character is shifted
• Example: consider the repeating key
3 1 7 4 2 5
• The first character in the message is shifted by 3, the next by 1, the
next by 7, and so on
• When the key is exhausted, start over at the beginning of the key
AN ENCODED MESSAGE USING A REPEATED
KEY
Encoded message

n o v a n g j h l m u u r x l v
Key 3 1 7 4 2 5 3 1 7 4 2 5 3 1 7 4
k n o w l e d g e i s p o w e r

Decoded message

6-46
USING QUEUES: CODED MESSAGES
• We can use a queue to store the values of the key
• dequeue a key value when needed
• After using it, enqueue it back onto the end of
the queue

• So, the queue represents the constantly cycling


values in the key

https://www.csd.uwo.ca/Courses/CS1027b/notes/queues.pdf

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy