L14 Heaps
L14 Heaps
reference
3 4 5 6
It is expensive to grow
and wastes space
proportional to 2h for a
tree of depth h with n
nodes.
Recall: Array Binary Trees
Binary Trees starting at index 0 Binary Trees starting at index 1 (Book
Examples)
We can represent a tree with n keys by means
of an array/vector of length n We can represent a tree with n keys by means
of an array/vector of length n + 1
Cell at index 0 is the root node
Cell at index 0 is not used, cell 1 the root node
Where i is the parent’s index:
Where i is the parent’s index:
● A left child is held at index 2i + 1
● A right child is held at index 2i + 2 ● A left child is held at index 2i
● A right child is held at index 2i + 1
A parent is at ⌊(i - 1) / 2⌋ for a node at index i
A parent is at ⌊i / 2⌋ for a node at index i
Data Structures: Heaps
Learn about heaps. This video is a part of HackerRank's Cracking The Coding Interview Tutorial with Gayle Laakmann McDowell.
http://www.hackerrank.com/domains/tutorials/cracking-the-coding-interview?utm_source=videoutm_medium=youtubeutm_campaign=ctci
Heaps
A heap is (typically) a binary tree storing keys at its nodes and satisfying the
following properties:
Heap Property: if P is a parent node of C, then the key of P is either greater than
or equal to (in a max heap) or less than or equal to (in a min heap) the key of
C
This avoids the need for pointers between elements, like in linked trees
After an element is inserted into or deleted from a heap, the heap property may
be violated and the heap must be balanced by internal operations
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Complete Binary Tree
Complete Binary Tree: let h be the
height of the heap
Interface
Position right(const Position& p); // get right child
Position parent(const Position& p); // get parent
bool hasLeft(const Position& p) const; // node left child?
bool hasRight(const Position& p) const; // node right child?
(Partial) private:
std::vector<E> V; // tree contents
Implementation
int size() const { return V.size() - 1; }
(Partial)
Position last() { return pos(size()); }
Complete Tree for Heap using a void swap(const Position& p, const Position& q) {
Vector E e = *q;
*q = *p;
*p = e;
}
};
Note: This Binary Tree is starting at index 1 (like the Book Examples)
template <typename E>
class VectorCompleteTree {
public:
Implementation
Position left(const Position& p)
{ return pos(2 * idx(p)); }
Position right(const Position& p)
(Partial)
{ return pos(2 * idx(p) + 1); }
Position parent(const Position& p)
{ return pos(idx(p)/2); }
Note: This Binary Tree is starting at index 1 (like the Book Examples)
Left child is held at index 2i, Right child is held at index 2i + 1,
A parent is at floor( i / 2 ) for a node at index i
Recall: Priority Queue ADT
A priority queue stores a collection of entries
Typically, an entry is a pair(key, value), where the key indicates the priority
Upheap restores the heap-order by swapping k along an upward path from the insertion
node
Upheap terminates when key k reaches the root or a node whose parent has a key smaller
than or equal to k
Since a heap has height O(log n), upheap runs in O(log n) time
Removal from a Heap
Method removeMin of the priority queue ADT
corresponds to the removal of the root key from
the heap
Downheap restores the heap property by swapping key k along a downward path from the
root
Downheap terminates when key k reaches a leaf or a node whose children have keys
greater than or equal to k
Since a heap has height O(log n), downheap runs in O(log n) time
Note on Min vs Max Heaps
The examples in this book and presentation are showing a
min-heap where key(P) ≤ key(C)
Interface
const E& min(); // minimum element
void removeMin(); // remove minimum
private:
Simple
return T.size();
}
Functions
// is the queue empty?
template <typename E, typename C>
bool HeapPriorityQueue<E,C>::empty() const {
return size() == 0;
// minimum element
template <typename E, typename C>
const E& HeapPriorityQueue<E,C>::min() {
return *(T.root()); // return reference to root element
}
// insert element
template <typename E, typename C>
void HeapPriorityQueue<E,C>::insert(const E& e) {
// add e to heap
T.addLast(e);
// e's position
Position v = T.last();
Remove Min
// down-heap bubbling
while (T.hasLeft(u)) {
Position v = T.left(u);
if (T.hasRight(u) && isLess(*(T.right(u)), *v)) {
v = T.right(u); // v is u's smaller child
Priority Queue with a Heap }
For the node at index i: left child is at index 2i and right child is at index 2i + 1
• Static Huffman coding assigns variable length codes to symbols based on their
frequency of occurrences in the given message. Low frequency symbols are
encoded using many bits, and high frequency symbols are encoded using fewer
bits.
• The coding process generates a binary tree, the Huffman code tree, with branches
labeled with bits (0 and 1).
• The Huffman tree (or the character codeword pairs) must be sent with the
compressed information to enable the receiver decode the message.
Static Huffman Coding Algorithm
Find the frequency of each character in the file to be compressed;
For each distinct character create a one-node binary tree containing the character and its frequency as its
priority;
Insert the one-node binary trees in a priority queue in increasing order of frequency;
while (there are more than one tree in the priority queue) {
Create a tree t that contains t1 as its left subtree and t2 as its right subtree; // 1
Assign 0 and 1 weights to the edges of the resulting tree, such that the left and right edge of each node do
not have the same weight; // 3
Note: The Huffman code tree for a particular set of characters is not unique.
(Steps 1, 2, and 3 may be done differently).
Static Huffman Coding example
Character a e l n o s t
Frequency 45 65 13 45 18 22 53
Use Huffman technique to answer the following questions:
• Use the Huffman tree to find the codeword for each character.
• If the data consists of only these characters, what is the total number of bits to be
transmitted? What is the compression ratio?
Static Huffman Coding example (cont’d)
Static Huffman Coding example (cont’d)
Static Huffman Coding example (cont’d)
Static Huffman Coding example (cont’d)
Static Huffman Coding example (cont’d)
The sequence of zeros and ones that are the arcs in the path from the root to each leaf node are
the desired codes:
character a e l n o s t
Huffman 110 10 0110 111 0111 010 00
codeword
Static Huffman Coding example (cont’d)
If we assume the message consists of only the characters a,e,l,n,o,s,t then the
number of bits for the compressed message will be 696:
If the message is sent uncompressed with 8-bit ASCII representation for the
characters, we have 261*8 = 2088 bits.