Ch 9: Heaps, Priority Queues, and Heap Sort
parent =
(index - 1) / 2
What is the main application for a heap?
The main application for a heap is as an implementation structure for a priority queue.
What are the 3 steps in the general approach of the heap sort?
1. Take the root (maximum) element off the heap, and put it in its place. 2. Reheap the remaining elements. (This action puts the next-largest element into the root position.) 3. Repeat until no more elements are left.
Full Binary Tree
A binary tree in which all of the leaves are located on the same level and every nonleaf node has two children.
Complete Binary Tree
A binary tree that is either full or full through the next-to-last level, with the leaves on the last level located as far to the left as possible.
Heap
A complete binary tree, each of whose elements contains a value that is greater than or equal to the value of each of its children.
What is the implementation structure for a priority queue?
A type of binary tree called a heap that enables enqueing and dequeing in O(log2N) time, but also keeps the number of levels from growing beyond log2N.
What is the purpose of the Enqueue operation?
Adding an element in its "appropriate" place in the heap.
What is a priority queue?
An ADT with an interesting accessing protocol: Only the highest-priority element can be accessed (a FIFO queue can be considered a priority queue whose highest-priority element is the one that has been queued the longest).
What is the best way to implement a heap?
An array based implementation is an excellent means of implementing a heap, which is a complete binary tree by definition.
What is the algorithm for the BuildHeap funciton?
BuildHeap for index going from first nonleaf node up to the root node { ReheapDown(values, index, numValues - 1) }
What is the algorithm for the Dequeue function?
Dequeue Set item to root element from queue Move last leaf element into root position Decrement length items.ReheapDown(0, length - 1)
What changes are made to the function ReheapDown when using it within the funciton BuildHeap?
Earlier, ReheapDown was a member function of HeapType, a struct type. There, the function had two parameters: the indexes of the root node and the bottom node. Here, we assume a slight variation: ReheapDown is a global function that takes a THIRD PARAMETER--an array that is treated as a heap.
What is the algorithm for the Enqueue function?
Enqueue Increment length Put newItem in next available position items.ReheapUp(0, length - 1)
How efficient is the heap implementation of a priority queue?
Enqueue & Dequeue is an O(log2N) operation.
Describe in detail how the SortNodes function works.
First swap the root and the last-used array position (values[numValues - 1]). Then we call ReheapDown. Next, swap the new root with the element in values[numValues - 2], then call ReheapDown again. We repeat this process until all elements are in their correct positions--that is, until the heap contains only a single element, which must be the smallest item in the array, values[0]. This location is its correct position, so the array is now completely sorted from the smallest to the largest element.
What two properties does a heap satisfy?
One concerning its shape & the other concerning the order of its elements.
What is the purpose of the function ReheapDown?
Given a complete binary tree whose elements satisfy the heap order property except in the root position, ReheapDown moves the element down from the root position until it ends up in a position where the order property is satisfied.
What is a heap NOT good for?
It is not a good structure for accessing a randomly selected element, but that is not one of the operations defined for priority queues.
What does the shape property permit us to do with a heap?
It permits us to efficiently store the tree in a n array, without the need for explicit links.
We keep the number of elements in a priority queue in the data member ____________.
Length.
What should you not confuse the heap (as a data structure) with?
Heap is also a synonym for the free store--the area of memory available for dynamically allocated data.
All the leaf nodes (subtrees with only a single node) are _________.
Heaps.
What are some other benefits of using an array based implementation of a binary tree?
It also offers the benefits of being able to directly determine which nodes are leaves, and of being able to access the parent of a node as easily as its children.
How do we store the tree elements in an array?
Level by level, & left to right within a level.
The array based implementation of a binary tree is _______________.
Linked in both directions--from parent to child & from child to parent.
We can also create a "___________________," each of whose elements contains a value that is less than or equal to the value of each of its children.
Minimum heap
The heap is always a tree of __________________.
Minimum height.
When referring to the heap sort, because the shape property of heaps guarantees a binary tree of minimum height, we make only _____________ comparisons in each iteration, as compared with _____________ comparisons in each iteration of the selection sort.
O(log2N); O(N)
What is the algorithm for the function ReheapDown?
ReheapDown(heap, root, bottom) if heap.elements[root] is not a leaf { Set maxChild to index of child with larger value if heap.elements[root] < heap.elements[maxChild] { Swap(heap.elements[root], heap.elements[maxChild] ReheapDown(heap, maxChild, bottom) }}
What is the purpose of the function ReheapUp?
ReheapUp takes a leaf node that violated the order property of heaps and moves it up until its correct position is found. We compare the value in the bottom node with the value in its parent node. If the parent's value is smaller, the order property is violated, so we swap the two nodes. Then we examine the parent, repeating the process until (1) the current node is the root of the heap or (2) the value in the current node is less than or equal to the value in its parent node.
What is the algorithm for ReheapUp?
ReheapUp(heap, root, bottom) if bottom > root { Set parent to index of parent of bottom node if heap.elements[parent] < heap.elements[bottom] { Swap(heap.elements[parent], heap.elements[bottom]) ReheapUp(heap, root, parent) }}
An unsorted array of data elements already _______________.
Satisfies the shape property of heaps.
What is the algorithm for the SortNodes function?
SortNodes for index going from last node up to next-to-root node { Swap data in root node with values[index] ReheapDown(values, 0, index - 1)
How do you find the first nonleaf node?
The first nonleaf node may be found at position numValues / 2 - 1.
What is the order property of a heap?
The order property says that, for every node in the heap, the value stored in that node is greater than or equal to the value in each of its children.
How efficient is HeapSort?
The overall sort requires work proportional to O(Nlog2N) time, which is equivalent to the time for the Quick Sort from Chapter 7.
What parameters are passed to the ReheapDown function and why?
The root and the bottom-rightmost element of the heap are passed as parameters to ReheapDown which generalizes the routine, allowing us to perform the reheap operation on any subtree, as well as the original heap.
What is the purpose of the Dequeue operation?
The root element is returned to the caller.
Where is the tree root and the last node in the tree located in an array?
The root is located in tree.nodes[0] & the last node in tree.nodes[numElements - 1].
What is the shape property of a heap?
The shape property is simple: A heap must be a complete binary tree.
What do the functions ReheapUp & ReheapDown have in common?
They are both recursive.
The basic shape of a full binary tree is _____________.
Triangular.
In an array based implementation of a binary tree, how do you determine which element is a node's parent?
Using integer division, tree.nodes[index]'s parent is in tree.nodes[(index - 1) / 2].
What is the special feature of heaps?
We always know the location of the maximum value: It is in the root node.
How do you determine if a node is a leaf node?
We know that a nonleaf node must have at least a left child, so if the calculated position of the left child is greater than bottom, it is a leaf node.
Where do we put an element when we want to add it to the heap?
We put the element in the next bottom-rightmost place in the tree.
The choice of a dummy value depends on ____________.
What information is stored in the tree.
When does an array representation of a binary tree waste space? When is it space efficient?
When the tree has many empty nodes. However, when the tree is complete, the array representation is highly space efficient.
How is the heap used differently between priority queues & the HeapSort function?
When we use heaps to implement priority queues, the heap structure stayed around for the duration of the use of the queue. The heap in HeapSort, in contrast, is not a retained data structure. It exists only for a while inside the HeapSort function.
In an array based implementation of a binary tree, what do you do when a tree is not full or complete?
You must account for the gaps created by missing nodes; we must store a dummy value in those positions in the array in order to maintain the proper parent-child relationship.
If your array based implementation of a binary tree has dummy values, what must you do to determine whether the node in tree.nodes[index] has a left child?
You must check whether index * 2 + 1 < tree.numElements, and then check whether the value in tree.nodes[index * 2 + 1] is the dummy value.
What do you do when you want to remove the element with the largest value from the heap?
You remove the root node and replace it with the bottom rightmost element from the heap; then call the function ReheapDown.
Not only can we use an ___________ to represent a binary tree, we can also reverse this process, creating a _____________ from the elements in an ____________.
array; binary tree; array
A binary tree can be stored in an _______ in such a way that the relationships in the tree are not physically represented by ____________, but rather are _____________ in the algorithms that manipulate the tree stored in the array.
array; link members; implicit
The operating system uses queues to ______________.
maintain lists of processes that are ready to execute or that are waiting for a particular event to occur. Such requests might be handled according to the priority of the event.
The order property says that, for every nonleaf node heap.elements[index], ____________________ and if there is a right child, ___________________.
heap.elements[index] >= heap.elements[index * 2 + 1]; heap.elements[index] >= heap.elements[index * 2 + 2]
Priority queues are also useful in ____________.
sorting. Given a set of elements to sort, we can enqueue the elements into a priority queue and then dequeue them in a sorted order (e.g., from largest to smallest).
The nodes in the array from __________________ to _________________ are leaf nodes, so a simple comparison of a node's index with that range enables us to tell whether or not it is a leaf.
tree.nodes[tree.numElements / 2]; tree.nodes[tree.numElements - 1]
The HeapSort function does not actually use the ________________. Rather, it uses the __________________ with the ________________ passed as a parameter.
struct HeapType; ReheapDown function; array of values
For any node tree.nodes[index], its left child is in _______________ & its right child is in _________________ (provided that these child nodes exist.
tree.nodes[index * 2 + 1]; tree.nodes[index * 2 + 2]