Queues

Queues

Draw a diagram showing a queue, front, back, enqueue, dequeue, and peek operations.

Member functions

q.dequeue() O(1) removes front value and returns it; throws error if queue is empty
q.enqueue(value) O(1) places given value at back of queue
q.isEmpty() O(1) returns true if queue has no elements
q.peek() O(1) returns front value without removing; throws error if queue is empty
q.size() O(1) returns number of elements in queue
The Queue class in Stanford's C++ libraries.

Food for thought: what is not an O(1) operation?

Example

Queue<int> q;                // {} front -> back
q.enqueue(42);               // {42}
q.enqueue(-3);               // {42, -3}
q.enqueue(17);               // {42, -3, 17}
cout << q.dequeue() << endl; // 42 (q is {-3, 17})
cout << q.peek() << endl;    // -3 (q is {-3, 17})
cout << q.dequeue() << endl; // -3 (q is {17}

Applications

Exercise

What is the output of the following code?
Queue<int> queue;
for (int i = 1; i <= 6; i++) {
  queue.enqueue(i);
} // {1, 2, 3, 4, 5, 6}
for (int i = 0; i < queue.size(); i++) {
  cout << queue.dequeue() << " ";
}
cout << queue << " size " << queue.size() << endl;
Options
A. 1 2 3 4 5 6 {} size 0
B. 1 2 3 {4, 5, 6} size 3
C. 1 2 3 4 5 6 {1, 2, 3, 4, 5, 6} size 6
D. none of the above

Exercise: Write a function duplicate that accepts a queue of integers and replaces every element with two copies of itself. For example, {1, 2, 3} becomes {1, 1, 2, 2, 3, 3}.

void duplicate(Queue<int>& q) {
  int size = q.size();
  for (int i = 0; i < size; i++) {
    int n = q.dequeue();
    q.enqueue(n);
    q.enqueue(n);
  }
}

Tips or using queues:

Mixing stacks and queues

How can we reverse the order of elements in a queue?
Queue<int> q {1, 2, 3};  // q={1, 2, 3}
Stack<int> s;

while (!q.isEmpty()) { //transfer queue to stack
  s.push(q.dequeue()); //q = {}, s = {1, 2, 3}
}

while (!s.isEmpty()) { //transfer stack to queue
  q.enqueue(s.pop());  //q = {3, 2, 1}, s = {}
}

cout << q << endl;   // {3, 2, 1}
What is the time complexity?

Exercise: Write a function mirror that accepts a queue of strings and appends the queue's contents to itself in reverse order. For example, {"a", "b", "c"} becomes {"a", "b", "c", "c", "b", "a"}.

void mirror(Queue<string>& q) {
  Stack<string> s;
  int size = q.size();
  for (int i = 0; i < size; i++) {
    string str = q.dequeue();
    s.push(str);
    q.enqueue(str);
  }
  while (!s.isEmpty()) {
    q.enqueue(s.pop());
  }
}

Brief introduction to Dequeues: doubly-ended queues (pronounced "deck")

Show figure with dequeue.

Mapping to C++ STL functions

Member functions (first Stanford function, then STL function, then description): reference http://www.cplusplus.com/reference/queue/queue/:
q.isEmpty() q.empty() returns true if queue has no elements
q.peek() q.front() returns front value without removing it; throws an error if queue is empty
q.dequeue() q.pop() C++ STL version only removes front value (but does not return it); throws an error if queue is empty
q.enqueue(value) q.push(value) places given value on top of queue, increasing its size by one
q.size() q.size() returns number of elements in queue.