Laboratory Exercises For Computer Science 195

Queues Implemented in C Using Circular Lists

Goals: This laboratory applies the concept of circular lists to implement a queue.

Background: From your past work, you know that a queue is a data structure that provides access to its elements on ``first-in, first-out'' basis, rather than the ``last-in, first-out'' constraint that a stack imposes. (For example, it might be prudent to treat that pile of unpaid bills a little differently, adding new elements at the bottom of the pile rather than the top. Paying off the most recent bill first, as in a stack, can make one's other, older creditors a little testy.) /p>

Like a line of people waiting for some service, a queue acquires new elements at one end (the rear of the queue) and releases old elements at the other (the front). While queues sometimes are given a large number of properties, the basic queue operations are as follows:

A Conceptual Implementation of Queues

While queues may be implemented in many ways, one of the simplest conceptually uses a singly-linked list with pointers front and rear giving access to the two ends:

A Queue as a Singly-Linked List

With this perspective, an element on a queue is stored in a data field within a list node:


struct node {
   char data [maxLength];
   struct node * next;
}

The queue itself involves two pointer variables:


struct queue {
   struct node * front;
   struct node * rear;
}

With such a structure, each queue operation is reasonably straightforward:

While enqueue and dequeue require a little care to handle empty lists, the code follows the outline fairly closely.

Queues Implemented as Circular Lists

While the linear, singly-linked list structure just described works fine, the implementation is sometimes considered inelegant. Specifically, a queue variable utilizes an entire structure, and this structure contains two fields.

As an alternative, the list may be made circular, with the last item pointing to the first. With this modification, the front pointer is no longer needed. Such a structure is shown in the following diagram:

A Queue as a Circular List

Such a perspective utilizes exactly the same node structure defined previously. However, with this revised picture, a queue variable reduces to just the rear pointer:


  struct node * queue; /* pointer specifing the rear of the queue structure */

Operations on this queue are quite similar to those for the singly-linked list version:

Steps for this Lab

Program ~walker/c/lists/queue.c contains a shell for maintain the standard queue operations. In addition, a print operation is added, so one can check all elements on a queue. Of these operations, however, only the empty and print functions are implemented.

  1. Implement the enqueue operation. Note that this function could be tested with the empty and print functions.

  2. Implement the dequeue operation.

  3. Test your program thoroughly, developing a careful testing plan to cover all reasonable scenarios.

Work to turn in:


This document is available on the World Wide Web as

     http://www.cs.grinnell.edu/~walker/courses/195.fa01/lab.queues.html

created September 27, 2001
last revised October 11, 2001
Valid HTML 3.2!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.