Module 2 Data Structure Queue
Module 2 Data Structure Queue
QUEUES: Queues, Circular Queues, Using Dynamic Arrays, Multiple Stacks and queues.
LINKED LISTS : Singly Linked, Lists and Chains, Representing Chains in C, Linked Stacks
and Queues, Polynomials.
DEFINITION
• “A queue is an ordered list in which insertions (additions, pushes) and deletions (removals and
pops) take place at different ends.”
• The end at which new elements are added is called the rear, and that from which old elements
are deleted is called the front.
• Given a queue Q = (a0, a1,……… an-1) , a0, is the front element an-1 is the rear element, ai+1 is
behind ai 0< =i < n-1.
If the elements are inserted A, B, C, D and E in this order, then A is the first element deleted from
the queue. Since the first element inserted into a queue is the first element removed, queues are
also known as First-In-First-Out (FIFO) lists.
• Figure indicates the way elements will be deleted from the queue and the way new elements will
be added to the queue.
• Whenever an element is deleted from the queue, the value of FRONT is increased by 1; this can
be implemented by the assignment FRONT := FRONT + 1
1
• When an element is added to the queue, the value of REAR is increased by 1; this can be
2
Implementation of the queue operations as follows.
1. Queue Create
Queue CreateQ(maxQueueSize) ::=
#define MAX_QUEUE_SIZE 100 /* maximum queue size */ typedef struct
{
int key;
/* other fields */
} element; element
queue[MAX_QUEUE_SIZE];
3
In the queue, two variables are used which are front and rear. The queue increments rear in addq(
) and front in delete( ). The function calls would be addq (item); and item =delete( );
4. addq(item)
void addq(int *rear, element item)
{
// add an item to the queue
if (rear == MAX_QUEUE_SIZE-1)
{
queue_Full();
return;
}
queue [++rear] = item;
}
Program: Add to a queue
5. deleteq( )
element deleteq(int *front, int *rear)
{ /* remove element at the front of the queue */
if (front == rear)
6. Queue Full ( )
The queue Full function which prints an error message and terminates execution void
4
Queue Full ()
exit (EXIT_FAILURE);
• Figure illustrates how an operating system process jobs using a sequential representation
for its queue.
Drawback of Queue
When item enters and deleted from the queue, the queue gradually shifts to the right as shown
in figure.
5
In this above situation, when we try to insert another item, which shows that the queue is full .
This means that the rear index equals to MAX_QUEUE_SIZE -1. But even if the space is
available at the front end, rear insertion cannot be done.
• When an item is deleted from the queue, move the entire queue to the left so that the
first element is again at queue[0] and front is at -1. It should also recalculate rear so that
it is correctly positioned.
• Shifting an array is very time-consuming when there are many elements in queue &
queueFull has worst case complexity of O(MAX_QUEUE_SIZE)
Method 2:
Circular Queue
• It is “The queue which wrap around the end of the array.” The array positions are
arranged in a circle.
6
• In this convention the variable front is changed. front variable points one position
counterclockwise from the location of the front element in the queue. The convention
for rear is unchanged.
CIRCULAR QUEUES
• It is “The queue which wrap around the end of the array.” The array positions are
arranged in a circle as shown in figure.
• In this convention the variable front is changed. front variable points one position
counterclockwise from the location of the front element in the queue. The convention
for rear is unchanged.
7
• When the array is viewed as a circle, each array position has a next and a previous
position. The position next to MAX-QUEUE-SIZE -1 is 0, and the position that
precedes 0 is MAX-QUEUE-SIZE -1.
• When the queue rear is at MAX_QUEUE_SIZE-1, the next element is inserted at
position 0.
• In circular queue, the variables front and rear are moved from their current position to
the next position in clockwise direction. This may be done using code
if (rear = = MAX_QUEUE_SIZE-1)
rear = 0;
else
rear++;
• To delete an element, increment front one position clockwise. The element A is deleted
from queue and if we perform 6 deletions from the queue of Figure (b) in this fashion,
then queue becomes empty and that front =rear.
• If the element I is added into the queue as in figure (c), then rear needs to increment by
1 and the value of rear is 8. Since queue is circular, the next position should be 0 instead
of 8.
This can be done by using the modulus operator, which computes remainders.
8
void addq(element item)
{ /* add an item to the queue */ rear = (rear +1) %
MAX_QUEUE_SIZE; if (front == rear) queueFull(rear); /*
print error and exit */
element deleteq()
{ /* remove front element from the queue */ element item;
if (front == rear)
return queueEmpty( ); /* return an error key */
front = (front+1)% MAX_QUEUE_SIZE; return
queue[front];
}
Program: Delete from a circular queue
9
CIRCULAR QUEUES USING DYNAMIC ARRAYS
• A dynamically allocated array is used to hold the queue elements. Let capacity be the
number of positions in the array queue.
• To add an element to a full queue, first increase the size of this array using a function
realloc.
Consider the full queue of figure (a). This figure shows a queue with seven elements in an
array whose capacity is 8. A circular queue is flatten out the array as in Figure (b).
To get a proper circular queue configuration, slide the elements in the right segment (i.e.,
elements A and B) to the right end of the array as in figure (d)
10
To obtain the configuration as shown in figure (e), follow the steps
3. Copy the first segment (i.e., the elements queue [0] through queue [rear]) to positions in
newQueue beginning at capacity – front – 1.
Below program gives the code to add to a circular queue using a dynamically allocated array.
void addq( element item)
{ /* add an item to the queue
rear = (rear +1) % capacity;
if(front == rear)
Below program obtains the configuration of figure (e) and gives the code for queueFull. The
function copy (a,b,c) copies elements from locations a through b-1 to locations beginning at
c.
void queueFull( )
{ /* allocate an array with twice the capacity */
element *newQueue;
11
/* copy from queue to newQueue */ int
start = ( front + ) % capacity;
else
{ /* queue wrap around */
copy(queue, queue+capacity, newQueue); copy(queue,
queue+rear+1, newQueue+capacity-start);
}
/* switch to newQueue*/
front = 2*capacity – 1;
rear = capacity – 2;
capacity * =2;
free(queue); queue=
newQueue;
}
Program: queueFull
• Assume that i refers to the stack number of one of the n stacks. To establish this stack,
create indices for both the bottom and top positions of this stack. boundary[i] points
to the position immediately to the left of the bottom element of stack i, top[i] points to
the top element. Stack i is empty iff boundary[i]=top[i].
12
#define MAX_STACKS 10 /* max number of stacks plus 1 */ element
memory[MEMORY_SIZE]; /* global memory declaration */ int top
[MAX_STACKS]; int boundary [MAX_STACKS] ;
int n; /*number of stacks entered by the user
*/
13
}
Program: Add an item to the ith stack
The top[i] == boundary[i+1] condition in push implies only that a particular stack ran out of
memory, not that the entire memory is full. But still there may be a lot of unused space between
other stacks in array memory as shown in Figure.
Therefore, create an error recovery function called stackFull , which determines if there is any
free space in memory. If there is space available, it should shift the stacks so that space is
allocated to the full stack.
14