Link

Priority Queues and Heaps

Complete the Reading Quiz by noon before lecture.

In class, we’ve already studied 5 abstract data types: List, Stack, Queue, Set, and Map. There’s one more ADT that’s frequently used called the Priority Queue.

Priority Queue
An abstract data type characterized by two operations: removing the maximum item and adding new items. Duplicate items are allowed.
public interface MaxPQ<Item> {

    /** Adds the item to the priority queue. */
    public void add(Item x);

    /** Returns the item with the highest priority. */
    public Item max();

    /** Removes and returns the item with the highest priority. */
    public Item removeMax();

    /** Returns the number of items in the priority queue. */
    public int size();
}

Imagine we’re developing an emergency room patient management system. We’d like to know, at any given time, which patient requires the most urgent care. We can say that this patient has the maximum priority in our priority queue. When we remove this patient from the priority queue, we’d like to know which patient has the next-highest priority. However, we don’t necessarily need to maintain a perfect sorted order for all the patients: all we need to know is the patient with the current highest priority.

As we saw when implementing Queue ADT in ArrayQueue, restricting the Priority Queue ADT gives the ADT implementer more flexibility to design faster data structures. That said, we can use existing data structures, such as linked nodes, to implement a priority queue. Let’s compare some of these implementations now.

Describe how we could implement the MaxPQ interface with an unordered linked list.

In an unordered linked list, we can put our items anywhere in the list. This will make insertion fast because we can add the item to the front of the list in constant time, but finding the maximum slow since we need to scan across the entire linked list.

Describe how we could implement the MaxPQ interface with an ordered linked list.

In an ordered linked list, the opposite is true. We can find the maximum quickly since we can maintain a reference to it (either the front or back of the list, our choice), allowing us to remove and return the maximum priority item in constant time. However, this slows down the insertion process since we need to find the exact, ordered position for the item in the list.

Describe how we could implement the MaxPQ interface with a balanced search tree.

A balanced search tree maintains the order of items in the structure of the tree. The smallest key is the very leftmost node in the tree while the largest key is the very rightmost node in the tree. Therefore, we can keep a reference to the rightmost node in the tree and maintain it as we add items and remove the maximum priority item from the priority queue.

This yields the following table comparing the asymptotic running time for each implementation in Big-O notation, where N is the size of the priority queue.

OperationUnordered Linked ListOrdered Linked ListBalanced Search Tree
addO(1)O(N)O(log N)
maxO(N)O(1)O(1)
removeMaxO(N)O(1)O(log N)

While the balanced search tree implementation is appealing, handling items with duplicate priority values requires additional complexity in a search tree. In class, we’ll discuss another potential principle for implementing the priority queue with a new data structure that we’ll develop called a heap.


Reading Quiz