ADT - heap(堆)
Posted darkchii
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ADT - heap(堆)相关的知识,希望对你有一定的参考价值。
二叉堆:
以前写过二叉堆,但很少使用,快忘了。最近又查了一些关于堆的资料,于是重新熟悉一下这种数据结构。
一个快速又简单的方式建立二叉堆,仅使用简单vector(或者数组也行):
#include "stdafx.h" #include <iostream> #include <vector> #define LeftChild(i) (2*(i) + 1) #define RightChild(i) (2*((i) + 1)) template<class T> void swap(T & a, T & b) { T tem = a; a = b; b = tem; } class Heap { public: /* 上滤插入 */ void up_insert(int val, std::vector<int> & values, int top); /* 调用上滤插入建立堆 */ void up2build(std::vector<int> & values); /* 下滤插入 */ void down_insert(std::vector<int> & values, int i, int size); /* 调用下滤插入建立堆 */ void down2build(std::vector<int> & values); /* 堆排序 */ void sort(std::vector<int> & values); }; void Heap::up_insert(int val, std::vector<int> & values, int top) { size_t i; for (i = top; i > 0 && values[i >> 1] < val; i >>= 1) values[i] = values[i >> 1]; values[i] = val; } void Heap::up2build(std::vector<int> & values) { int top = 0; for (auto v : values) { up_insert(v, values, top); ++top; } } void Heap::down_insert(std::vector<int> & values, int i, int size) { int last = values[i]; for (int Child; LeftChild(i) < size; i = Child) { Child = LeftChild(i); if (Child != size - 1 && values[Child + 1] > values[Child]) Child++; if (last < values[Child]) values[i] = values[Child]; else break; } values[i] = last; } void Heap::down2build(std::vector<int> & values) { int size = values.size() - 1; for (int i = size >> 1; i >= 0; i--) { down_insert(values, i, size); } } void Heap::sort(std::vector<int> & values) { int size = values.size() - 1; down2build(values); for (int i = size; i > 0; i--) { swap(values[0], values[i]); down_insert(values, 0, i); } } int main() { Heap heap; std::vector<int> values { 5345,332,2341,498,248,89,239,4825,8,43,9892,872,1843 }; //heap.build(values); heap.sort(values); for (auto v : values) std::cout << v << std::endl; getchar(); return 0; }
up_build是形如‘上滤’的过程,平均情况时间复杂度为θ(n),因为up_insert函数只花费θ(1)的平均时间。最坏情况为O(n),空间复杂度O(1);
down_build是形如‘下滤’的过程,时间复杂度为O(n),空间复杂度O(1),有点不可思议,不过这里《数据结构与算法分析》书中说下滤建堆也是O(n),但知乎上有证明下滤是O(nlgn) = = 难道是我看错了?其实我也觉得自顶向下建堆的复杂度为O(nlgn))。
左式堆:
左式堆的性质:任意节点的左孩子的NPL(null path length - 零路径长)至少等于右孩子的NPL,这样的条件使得左式堆十分不平衡。左式堆的基本操作是进行堆合并。
NPL的定义:任一节点到叶节点的最短路径的长。
参考资料:
1.《数据结构与算法分析》第6章 - 堆。
2.知乎相关问题
以上是关于ADT - heap(堆)的主要内容,如果未能解决你的问题,请参考以下文章
Binary Heap ADT 的 increaseKey() 方法