Queues

A classic data structure giving First-In, First-Out (FIFO) or First-Come, First-Serve (FCFS) access to elements.

Examples of queues: lines, others? (line to get into DAKA)

Two basic operations:

Implementation of Queues

Physical Model

In a line when the first person exits the line, the entire line moves up. We can use a similar model where we store the queue as an array of items and always take from the front of the queue. Have a variable of where the rear of the queue is. Front of the queue is always the first element.

Problem that DeleteQueue() is expensive because we must shift elements of the array.

Linear Implementation

Can have a front variable and a rear variable (front chases the rear). Problem is what to do when we get to the end of the array.

Leads to thinking about what MAXQUEUE represents. It should be the maximum number of items contained in the queue at a time, not the total number that passed through the queue.

Circular Arrays (Queues)

Look at Fig 3-6. Act as if we have a circle rather than a linear array of elements. (0 to MAXQUEUE-1). Use the modulo function % to keep within the range.

Boundary Conditions

Let the variable rear indicate the location of the rear of the queue (last element inserted). Front of the queue indicates next element to take from the queue.

Look at Fig 3.7. How to differentiate an empty and a full queue?

Queue Implementation

Reuse the stack example. What do we expect for output? Same as the input.

/* /cs/cs2005/pub/example/queue.h -- header file for queue example */

#define MAXQUEUE 10

typedef char Item_type;

typedef short Boolean;

class Queue {
  private:
    int rear;        /* last slot used for insertion */
    int front;       /* next slot to delete */
    int count;       /* count of items in queue */
    Item_type rgItem[MAXQUEUE];
  public:
    Queue();
    Boolean EmptyQueue();
    Boolean FullQueue();
    int AddQueue(Item_type);       /* enqueue */
    int DeleteQueue(Item_type &);  /* dequeue */
    int AddQueueSort(Item_type);   /* enqueue sorted */
};

/*
 * /cs/cs2005/pub/example/reread.C -- print a line in the same order using queue
 *
 * compile: gcc -o reread reread.c queue.c
 */

#include <iostream.h>
#include "queue.h"

void main(void)
{
    Queue queue;
    Item_type item;

    // read a character and check for end-of-file (^D) on input
    // cin of a character does not read newline char
    while ((cin >> item) && (!cin.eof())) {
        if (queue.AddQueue(item) < 0) {
            cout << "No more room in queue.\n";
            exit(1);
        }
    }

    while (queue.DeleteQueue(item) >= 0)
        cout << item;
    cout << "\n";
}

/*
 * /cs/cs2005/pub/example/queue.C -- queue routines
 *
 * These routines keep a count of the items in the queue to determine if it
 * is full or empty.
 */

#include "queue.h"

/*
 * Queue - initialize the queue
 */
Queue::Queue()
{
    count = 0;
    front = 0;
    rear = -1;
}

/*
 * AddQueue - add an item to the queue, return zero for success, -1 on error.
 */
int Queue::AddQueue(Item_type item)
{
    if (count >= MAXQUEUE)
        return(-1);
    else {
        count++;
        rear = (rear + 1)%MAXQUEUE;
        rgItem[rear] = item;
        return(0);
    }
}

/*
 * DeleteQueue - delete an item from the queue, return zero for success, -1 on error.
 */
int Queue::DeleteQueue(Item_type &item)
{
    if (count <= 0)
        return(-1);
    else {
        count--;
        item = rgItem[front];
        front = (front + 1)%MAXQUEUE;
        return(0);
    }
}

/*
 * FullQueue - is the queue full?
 */
Boolean Queue::FullQueue()
{
    return(count >= MAXQUEUE);
}

/*
 * EmptyQueue - is the queue empty?
 */
Boolean Queue::EmptyQueue()
{
    return(count <= 0);
}

/*
 * AddQueueSort - add an item to a sorted queue, return zero for success, -1 on error.
 */
int Queue::AddQueueSort(Item_type item)
{
    int i, iSave;

    if (count >= MAXQUEUE)
        return(-1);
    else if (count <= 0) {
        /* insert the first element */
        count++;
        rear = (rear + 1)%MAXQUEUE;
        rgItem[rear] = item;
        return(0);
    }
    else {
        count++;
        for (i = front; 
             (rgItem[i] <= item) && (i != (rear+1)%MAXQUEUE); 
             i = (i+1)%MAXQUEUE)
            ;

        /* insert the item at this point in the queue */
        iSave = i;                /* save insertion point */
        /* move items down in the array by one slot */
        for (i = rear; i != (iSave-1+MAXQUEUE)%MAXQUEUE; 
                                      i = (i-1+MAXQUEUE)%MAXQUEUE)
            rgItem[(i+1)%MAXQUEUE] = rgItem[i];

        rgItem[iSave] = item;        /* insert item */
        rear = (rear + 1)%MAXQUEUE;
        return(0);
    }
}