Lecture 15:  ADT–Queue

 

Objectives of this lecture

q       Implement Queue using Array

q       Learn how to apply queue in problem solving

 

What is Queue?

q       An ADT Queue is another linear structure that holds homogeneous data elements.  Unlike stack, a queue has two ends which are used as follows:

Ø      Items are added (enqueued) at only one end, called the rear

Ø      Items are removed (dequeued) at the other end, called the front.

q       Thus, the first element to be enqueued is the first to be dequeued – hence, a queue is sometimes called a first-in-first-out (FIFO) structure.

q       Queue also has many applications especially in system software and operating systems.  E.g. handling print jobs by a print server.

q       The common operations that are defined on queue are:

Create_queue – make queue logically accessible

Destroy_queue – make queue logically inaccessible

Empty_queue – checks if a queue is empty

Full_queue – checks if a queue is full

enqueue  - add item at the rear of the queue

dequeue – remove item from the front of the queue.

 

Implementation of Queue using Array

q      One way of implementing a queue is to use a structure consisting of an array (to hold the items of the queue )and two integer fields, front and rear (to hold the positions of the front ant rear items).

q       Initially, front and rear may be the same (say 0) indicating that the queue is empty.

 

 

 

 

 

 

 

          When an item is added, the rear is incremented by one to point to the next free cell.

 

A

B

 

 

 

 

                   

q       When an item is removed, the front is incremented by one to point to the next item.

 

 

B

 

 

 

 

                                           

 

q       However, there are two problems that must be solved for this representation to work:

q       Problem1: (utilizing cells left by deleted elements)

Consider the following situation:

 

A

B

C

D

E

 

                                                                                            

 

Suppose A and B are dequeued, then the situation is as follows:

 

 

 

C

D

E

 

                                                                                           

 

Suppose we now attempt to enqueue F and G. even though there is room in the queue, this operation is not possible since adding 1 to rear will make it go beyond queue size.

 

This problem is solved by considering the array to be circular – that is, the first element is assumed to follow the last.  With this assumption, the addition of F and G can be done as follows:

 

G

 

C

D

E

F

                           

 

q       Problem2: (conditions for full and empty queue are the same)

The second problem is that there is no difference between empty and full queue.  For example, if we add H to the above queue, the situation is as follows:

 

G

H

C

D

E

F

                                             

 

rear=front (same as empty queue).

 

This problem can be solved if we have another integer field, queue_count to keep track of the number of elements in the queue.

 

However, a more common solution is to leave one cell free and let front point to it.  With this approach, the empty and full queue are as follows:

Empty Queue

 

 

 

 

 

 

             

Full Queue

G

 

C

D

E

F

                         

 

With this understanding, we can implement queue as follws:

 

The user_inteface:

q       This should be stored in a header file queue.h

#define MAX_Q 100

typedef char ITEM_TYPE;

typedef enum { FALSE, TRUE} BOOLEAN;

typedef struct { ITEM_TYPE item[MAX_Q];

                    int front; /* always point to cell prior to front */

                    int rear;  /* always point to the rear item */

                 } Q_TYPE;

 void create_queue(Q_TYPE *queue);

 void destroy_queue(Q_TYPE *queue);

 BOOLEAN empty_queue(Q_TYPE *queue);

 BOOLEAN full_queue(Q_TYPE *queue);

 void enqueue(Q_TYPE *queue, ITEM_TYPE new_item);

 void dequeue(Q_TYPE *queue, ITEM_TYPE *front_item);

 

Implementation details

q       These can be stored in a separate library file queue.c

 

 #include "queue.h"

 

 /* initializes queue by setting rear and front to 0 */

 void create_queue(Q_TYPE *queue)

 { queue->front=0;

   queue->rear=0;

 }

 

 /* resets queue by resetting rear and front to zero */

 void destroy_queue(Q_TYPE *queue)

 { queue->front = 0;

   queue->rear = 0;

 }

 

 /* returns true if front and rear are the same */

 BOOLEAN empty_queue(Q_TYPE *queue)

 { if (queue->rear == queue->front)

      return TRUE;

   else

      return FALSE;

 }

 

 /* returns true if rear+1 is same as front */

 BOOLEAN full_queue(Q_TYPE *queue)

 { if ((queue->rear+1)%MAX_Q ==queue->front)

      return TRUE;

   else

      return FALSE;

 }

 

 /* adds item to the rear of the queue */

 void enqueue(Q_TYPE *queue, ITEM_TYPE new_item)

 {  queue->rear++;

   /* we need to take modulo MAX_Q in case rear is now bigger than MAX_Q */

    queue->rear = queue->rear%MAX_Q;

    queue->item[queue->rear]=new_item;

 }

 

 

 

/* removes item from the front of the queue */    

 void dequeue(Q_TYPE *queue, ITEM_TYPE *front_item)

{  /* we need to add 1 to fromt to reach the front item */

   queue->front++;

  /* we need to take modulo MAX_Q in case front is now bigger than

       MAX_Q */

   queue->front = queue->front%MAX_Q;

   *front_item = queue->item[queue->front];

 }

 

Example:

q       The following program shows how ADT queue may be used in a program:

 

#include <stdio.h>

#include "queue.c"

 

void input_queue(Q_TYPE *queue);

void output_queue (Q_TYPE *queue);

 

main()

{  Q_TYPE queue;

   create_queue(&queue);

   input_queue(&queue);

   output_queue(&queue);

   destroy_queue(&queue);

   return 0;

}

 

void input_queue(Q_TYPE *queue)

{  ITEM_TYPE in_value;

   printf("\nEnter a string of caharacters: ");

   while (((in_value=getchar()) != '\n') &&

             (full_queue(queue)==FALSE))

               enqueue(queue,in_value);

}

 

void output_queue (Q_TYPE *queue)

{  ITEM_TYPE out_value;

   printf("\nThe string in order is: ");

   while ( empty_queue(queue)== FALSE)

   {    dequeue(queue,&out_value);

          putchar(out_value);

   }

}