Chapter 4 Heap
Heap is a kind of priority_queue(PQ), which guarantees that the head node is the largest / smallest one
ADT
Operations
- PQ Initialize(int maxElem)
- void Insert(ElemType key, PQ heap)
- ElemType DeleteMin(PQ heap)
- ElemType FindMin(PQ heap)
Simple Implementations
- Array
- Linked List
- Ordered Array
- Ordered Linked List
- BST
Binary Heap
Structure Property
Heap is a fulfilled complete binary tree
完全二叉树 complete binary tree: 除了最后一层全部填满
- h=int(logN)
完美二叉树 perfect binary tree: 最后一层也全部填满
Array Representation
put a complete tree in a array of (N + 1) length without array[0] by level-order traversal
Lemma
For any node with index i:
parent(i)={i//2,None,if i=1if i=1
left_child(i)={2i,None,if 2i≤nif 2i>n
right_child(i)={2i+1,None,if 2i+1≥nif 2i+1>n
typedef int ElemType; const int minData = 0x80000000;
typedef struct{ int capacity, size; ElemType* elems; } HeapStruct; typedef HeapStruct* Priority_Queue;
Priority_Queue Initialize(int maxElem){ Priority_Queue heap; heap = (Priority_Queue)malloc(sizeof(HeapStruct)); heap->elems = (ElemType*)malloc((maxElem + 1) * sizeof(ElemType)); heap->capacity = maxElem; heap->size = 0; heap->elems[0] = minData; return heap; }
|
哨兵 sentinel: 哨兵是小根堆的最小值或大根堆的最大值, 并不是真实存在的, 而是虚拟的, 防止越界
小根堆 min heap: 父节点小于等于子节点
大根堆 max heap: 父节点大于等于子节点
Basic Heap Operations
Insertion
- Percolate up
- Insert
- O(logN)
void Insertion(ElemType key, PriorityQueue heap){ if(heap->capacity == heap->size){ return; } ++heap->size; int i = heap->size; while(heap->elems[i / 2] > key){ heap->elems[i] = heap->elems[i / 2]; i /= 2; } heap->elems[i] = key; }
|
DeleteMin
- Move back to top
- Percolate down
ElemType DeleteMin(PriorityQueue heap){ if(heap->size == 0) return heap->elems[0]; ElemType minElem, lastElem; minElem = heap->elems[1]; lastElem = heap->elems[heap->size]; --(heap->size); int i, child; for(i = 1; 2 * i < heap->size; i = child){ child = 2 * i; if(child < heap->size && heap->elems[child + 1] < heap->elems[child]){ ++child; } if(lastElem > heap->elems[child]){ heap->elems[i] = heap->elems[child]; } else{ break; } } heap->elems[i] = lastElem; return minElem; }
|
Other Heap Operations
DecreaseKey(int position, unsigned delta, PQ heap)
IncreaseKey(int position, unsigned delta, PQ heap)
Delete(int positon, PQ heap)
- Decrease(position, INF, heap)
- DeleteMin(heap)
BuildHeap(Elem* seq, PQ heap)
- Method 1
- heap = Initialize(…)
- N times of Insertion(seq[i], heap)
- O(NlogN)
- Methos 2
- Shift seq to a complete tree
- logN times of precolate down from the last but one level
- O(N)
Theorem: for a perfert binary tree og height h, the sum of the heights of the nodes is 2h+1−1−(h+1)
Applications of Priority Queue
[Eg] Find the kth largest / smallest element from N elements
d-Heaps
the time complexity of Insertion of d-heaps decreases to O(logdN); but DeleteMin may increase to O(dlogdN)
C++
Using C++ STL can help to implement heaps
#include<vector> #include<iostream> #include<queue> typedef std::priority_queue<int> maxPQ; typedef std::priority_queue<int, std::vector<int>, std::greater<int>> minPQ;
int main(){ maxPQ maxHeap; minPQ minHeap; std::vector<int> vec({5, 2, 6, 1, 7, 9}); for(auto i:vec){ maxHeap.push(i); minHeap.push(i); } std::cout<<maxHeap.top()<<std::endl; std::cout<<minHeap.top()<<std::endl;
maxHeap.pop(); minHeap.pop();
std::cout<<maxHeap.top()<<std::endl; std::cout<<minHeap.top()<<std::endl; }
|
在 STL 中, priority_queue 被称为容器适配器, 因此他没有自己的 ADT 实现, 需要依赖既有的容器, 比如 vector, deque 等等
因此 priority_queue 的完整声明如下:
priority_queue<ElemType, Container, CompareFunc>
- ElemType: 数据类型
- Container: 容器类型, 默认为 vector
- CompareFunc: 比较所用的函数对象, 默认为 less(大根堆), 可选 greater(小根堆), 本质上是对 operator() 的重载
然而实际上默认的 greater 和 less 就是对 operator< 的调用, 因此可以直接重载 ElemType 的 operator< 实现自定义排序方式
例如以下的代码就对自定义类 Node 实现了小根堆
struct Node{ int negaVal; };
bool operator< (const Node x, const Node y){ return -(y.negaVal - x.negaVal); }
std::priority_queue<Node, std::vector<Node>> heap;
int main(){ Node x, y, z; x.negaVal = 4, y.negaVal = 6, z.negaVal = 3;
heap.push(x); heap.push(y); heap.push(z);
std::cout<<heap.top().negaVal<<std::endl; }
|