In computer science, a queue (/ˈkjuː/ kyew) is a particular kind of abstract data type or collection in which the entities in the collection are kept in order and the principal (or only) operations on the collection are the addition of entities to the rear terminal position, known as enqueue, and removal of entities from the front terminal position, known as dequeue. This makes the queue a First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the queue will be the first one to be removed. This is equivalent to the requirement that once a new element is added, all elements that were added before have to be removed before the new element can be removed. Often a peek or front operation is also entered, returning the value of the front element without dequeuing it. A queue is an example of a linear data structure, or more abstractly a sequential collection.
1. 1
Queues
•Definition of a Queue
•Examples of Queues
•Design of a Queue Class
•Different Implementations of the
Queue Class
2. 2
Definition of a Queue
• A queue is a data structure that models/enforces the first-come first-
serve order, or equivalently the first-in first-out (FIFO) order.
• That is, the element that is inserted first into the queue will be the
element that will deleted first, and the element that is inserted last is
deleted last.
• A waiting line is a good real-life example of a queue. (In fact, the
Britich word for “line” is “queue”.)
3. 3
A Graphic Model of a Queue
Tail:
All new items
are added on
this end
Head:
All items are
deleted from
this end
4. 4
Operations on Queues
• Insert(item): (also called enqueue)
• It adds a new item to the tail of the queue
• Remove( ): (also called delete or dequeue)
• It deletes the head item of the queue, and returns to the caller. If the queue is already empty, this
operation returns NULL
• getHead( ):
• Returns the value in the head element of the queue
• getTail( ):
• Returns the value in the tail element of the queue
• isEmpty( )
• Returns true if the queue has no items
• size( )
• Returns the number of items in the queue
5. 5
Examples of Queues
• An electronic mailbox is a queue
• The ordering is chronological (by arrival time)
• A waiting line in a store, at a service counter, on a one-lane road
• Equal-priority processes waiting to run on a processor in a computer
system
6. 6
Queue as a Class
• Much like stacks and linked lists were designed and implemented as
classes, a queue can be conveniently packaged as a class
• It seems natural to think of a queue as similar to a linked list, but with
more basic operations, to enforce the FIFO order of insertion and
deletion
7. 7
A Rough Class for Queue
• class Queue{
public:
typedef int datatype; // datatype is the type of items to be
//added to the queue. By changing int to some other type, the
// queue is easily changed to handle other data types
Queue( );
void enqueue(datatype x);
datatype dequeue( );
datatype peekHead( );
datatype peekTail( );
int size( );
bool isEmpty( );
private:
//A container for items. It’s determined in the implementation
};
8. 8
A Linked List Implementation of the Queue
Class
• The container for items is a linked list, that is, an object of type List
• Let’s call it: List q;
9. 9
A Class for Queue: A Linked List
Implementation
• class Queue{
public:
typedef int datatype;
Queue( ) { };
void enqueue(datatype x) {q.insertTail(x);};
datatype peekHead( ) {assert(size()>0);q.getHead( )->getData( );};
datatype peekTail( ) {assert(size()>0);q.getTail( )->getData( );};
datatype dequeue( ) {assert(size()>0); int x=peekHead( );
q.removeHead( ); return x;};
int size( ) {return q.size( );};
bool isEmpty( ) {return q.isEmpty( );};
private:
List q;
}; // Time: All member functions take O(1) time.
10. 10
A Dynamic-Array Implementation of the Queue
Class
• The container for items is a dynamic array
• It is accomplished as:
datatype *p=new datatype[50];
11. 11
A Class for Queue using Dynamic Arrays
• class Queue{
public:
typedef int datatype;
Queue(int capacity = 50) ;
void enqueue(datatype x); datatype dequeue( );
datatype peekHead( ); datatype peekTail( );
int size( ); bool isEmpty( );
private:
int capacity; // default value is 50
datatype *p; // pointer a dynamic array created by constructor
int length; // number of actual elements in the queue
int head; // index of the head element in the array
int tail; // index of the tail element in the array
};
12. 12
How head and tail Change
• head increases by 1 after each dequeue( )
• tail increases by 1 after each enqueue( )
012474849 4 3
012474849 4 3
012474849 4 3
Now:
After enqueue:
After dequeue:
tail head
tail head
tail head
13. 13
False-Overflow Issue First
• Suppose 50 calls to enqueue have been made, so
now the queue array is full
• Assume 4 calls to dequeue( ) are made
• Assume a call to enqueue( ) is made now. The tail
part seems to have no space, but the front has 4
unused spaces; if never used, they are wasted.
012474849
012474849
34
34
14. 14
Solution: A Circular Queue
• Allow the head (and the tail) to be moving targets
• When the tail end fills up and front part of the array has empty slots,
new insertions should go into the front end
• Next insertion goes into slot 0, and tail tracks it. The insertion after
that goes into a lot 1, etc.
012474849
headtail
34
15. 15
Illustration of Circular Queues
• Current state:
• After One Call to enqueue()
• After One Call to enqueue()
012474849 34
tail
head
012474849 34
tailhead
012474849 34
head tail
16. 16
Numerics for Circular Queues
• head increases by (1 modulo capacity) after each dequeue( ):
head = (head +1) % capacity;
• tail increases by (1 modulo capacity) after each enqueue( ):
tail = (tail +1) % capacity;
17. 17
Complete Implementation of Queues with Dynamic
Arrays
• Show the class structure as a refresher (next slide)
• The implementations of the constructor and member functions will
follow afterwards
18. 18
The Class Structure (revisited)
• class Queue{
public:
typedef int datatype;
Queue(int capacity = 50) ;
void enqueue(datatype x); datatype dequeue( );
datatype peekHead( ); datatype peekTail( );
int size( ); bool isEmpty( );
private:
int capacity; // default value is 50
datatype *p; // pointer a dynamic array created by constructor
int length; // number of actual elements in the queue
int head; // index of the head element in the array
int tail; // index of the tail element in the array
};
19. 19
Implementations of the Members
Queue::Queue(int capacity){
this.capacity = capacity;
p = new datatype[capacity];
length=0; head=0; tail=0;
};
int Queue::size( ){return length;};
bool Queue::isEmpty( ) {return (length==0);};
Queue::datatype Queue::peekHead( ){assert(length>0);return p[head];};
Queue::datatype Queue::peekTail( ){assert(length>0); return p[tail];};
Time: All O(1) time.
20. 20
Implementation enqueue( )
void Queue::enqueue(datatype x){
if (length==0) {p[tail]=x; length++;}
else if (length<capacity) {length++; tail=tail+1 % capacity; p[tail]=x; }
else {// Filled. Create a new array twice big. Copy current array to it. Add x.
datatype *q= new datatype[2*capacity];
int j = head; // copy filled array p (from head to tail) to array q[0…]
for (int i=0;i<capacity;i++) {q[i]=p[j]; j=j+1 % capacity;}
head = 0;
tail = capacity; // pointing to the first empty slot for now
q[tail]=x; // put x in the first empty slot
length++; // account for adding x
capacity = 2*capacity; // reflect that capacity is now doubled
delete [] p; // deletes the old array pointed to by p
p =q; // makes p point to the new array.
}
};
Time: O(1) except at overflow, in which case O(length).