A priority queue is a collection in which items can be added at any time, but the only item that can be removed is the one with the highest priority.
Operations
Unsorted Array
Unsorted Linked List
Sorted Array
Sorted Linked List
Heap
What's a heap, anyway?
A heap is a complete binary tree in which the value of a node is less than all the values in its subtrees. By convention, the smallest element is the one with the highest priority.

Therefore, the smallest element, the one with the highest priority, is always on top, so peek() is Θ(1).
To insert, add the new item to the last slot in the array and sift it up.

Since the tree is complete, it has minimum height, and the worst case number of moves up is logarithmic in the heap size. So cool.
To remove, return the value at the top, replace the top node with the value of the last slot, destroy the last slot, and sift down.

It should be pretty easy to prove that deletion is done in logarithmic time.
A cool operation you'll sometimes see is called heapify — it turns a random array into a heap:
for (int i = a.length/2; i >= 0; i--) {
siftdown(i);
}
By the way...
There's already a PriorityQueue class in the Java Core API. It implements the Queue interface, and has the following characteristics:
There's also the PriorityBlockingQueue class.
However we're going to write a PriorityQueue class from scratch because:
We'll develop this during class
Here are some of the things we need to test:
Here is a rough unit test:
We'll develop this during class
Here's a binary heap-based, non-thread-safe, non-blocking, implementation in Ruby:
# A priority queue class
class PriorityQueue
def initialize
@heap = []
end
# Add an element to the queue
def add!(x)
@heap << x
sift_up(@heap.length - 1)
self
end
# Return the smallest element in the queue
def peek
@heap[0]
end
# Remove the smallest element from the queue
def remove!()
raise RuntimeError, "Empty Queue" if @heap.length == 0
if @heap.length == 1
@heap = []
else
@heap[0] = @heap.pop
sift_down(0)
end
self
end
private
# Sift up the element at index i
def sift_up(i)
parent = (i - 1) / 2
if parent >= 0 and @heap[parent] > @heap[i]
@heap[parent], @heap[i] = @heap[i], @heap[parent]
sift_up(parent)
end
end
# Sift down the element at index i
def sift_down(i)
child = (i * 2) + 1
return if child >= @heap.length
child += 1 if child + 1 < @heap.length and @heap[child] > @heap[child+1]
if @heap[i] > @heap[child]
@heap[child], @heap[i] = @heap[i], @heap[child]
sift_down(child)
end
end
end
And here's a unit test
require 'test/unit'
require 'priorityqueue'
class PriorityQueueTest < Test::Unit::TestCase
def test_new
q = PriorityQueue.new
assert_equal(q.peek, nil)
assert_raise(RuntimeError) {q.remove!}
end
# Add 1..100 in at random, they should come out in order
def test_adds_and_removes
q = PriorityQueue.new
(1..100).to_a.sort_by {rand}.each {|x| q.add!(x)}
1.upto(100) do |i|
assert_equal(q.peek, i)
q.remove!
end
end
end