堆的具体实现
来源:互联网 发布:照片摇奖软件 编辑:程序博客网 时间:2024/05/16 04:49
一、定义:
堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。(是静态结构)
二、堆结构的二叉树存储结构:
最大堆:每个父节点的都大于孩子节点。
最小堆:每个父节点的都小于孩子节点。
三、大根堆和小根堆
1.大根堆:
函数声明如下:
template<class T>class Heap{public:Heap();Heap(const T* a, size_t size);Heap(vector<T> & a);//有动态顺序表构造,布斯和有数组构造,外面顺序表会被交换掉void Push(const T& x);void Pop();T& Top();size_t Size();bool Empty();protected:void _AdjustDown(size_t parent);void _AdjustUp(int child);protected:vector<T> _a;};
具体实现如下:
template<class T>Heap<T>::Heap(){}template<class T>Heap<T>::Heap(const T* a, size_t size){_a.reserve(size);for (size_t i = 0; i < size; ++i){_a.push_back(a[i]);}//建堆for (int i = (_a.size() - 2) / 2; i >= 0; --i){_AdjustDown(i);}}template<class T>Heap<T>::Heap(vector<T> & a){_a.swap(a);for (int i = (_a.size() - 2) / 2; i >= 0; --i){_AdjustDown(i);}}template<class T>void Heap<T>::Push(const T& x){_a.push_back(x);_AdjustUp(_a.size() - 1);}template<class T>void Heap<T>::Pop(){size_t size = _a.size();assert(size > 0);std::swap(_a[0], _a[size - 1]);_a.pop_back();_AdjustDown(0);}template<class T>T& Heap<T>::Top(){assert(_a.empty());return _a[0];}template<class T>size_t Heap<T>::Size(){return _a.size();}template<class T>bool Heap<T>::Empty(){return _a.size() == 0;}//下调template<class T>void Heap<T>::_AdjustDown(size_t parent){size_t child = parent * 2 + 1;while (child < _a.size()){//选出左右孩子中最小的,有可能节点不存在if ((child + 1 < _a.size()) && (_a[child] < _a[child + 1])){++child;}if (_a[parent] < _a[child]){std::swap(_a[parent], _a[child]);parent = child;child = 2 * parent + 1;}else{break;}}}//上调template<class T>void Heap<T>::_AdjustUp(int child){int parent = (child - 1) / 2;while (child>0){if (_a[child] > _a[parent]){std::swap(_a[child], _a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}
2、小根堆
小根堆与大根堆的实现大体思路相同,主要是上调和下调的判断条件不相同而已,那么就可以使用仿函数在一份代码里面即实现大根堆又实现小根堆
(1)仿函数
不是函数,而是一个类,但可以像函数一样使用
例子:
比较两个数的大小
代码如下:
template<class T>struct Less{bool operator()(const T& l, const T& r){return l < r;}};template<class T>struct Greater{bool operator()(const T& l, const T& r){return l > r;}};
测试用例:
void TestFuner(){Less<int> less;cout << less(1, 2) << endl;//以为是函数其实是对象,去掉运算符重载}
c++用模版实现这种功能,其实C语言的函数指针可以实现
(2)小根堆的具体实现
代码如下:
template<class T>struct Less{bool operator()(const T& l, const T& r){return l < r;}};template<class T>struct Greater{bool operator()(const T& l, const T& r){return l > r;}};template<class T,template<class> class Compare = Less>class Heap{public:Heap(){}Heap(const T* a, size_t size){_a.reserve(size);for (size_t i = 0; i < size; ++i){_a.push_back(a[i]);}//建堆for (int i = (_a.size() - 2) / 2; i >= 0; --i){_AdjustDown(i);}}//外面顺序表会被交换掉Heap(vector<T> & a){_a.swap(a);for (int i = (_a.size() - 2) / 2; i >= 0; --i){_AdjustDown(i);}}void Push(const T& x){_a.push_back(x);_AdjustUp(_a.size() - 1);}void Pop(){size_t size = _a.size();assert(size > 0);std::swap(_a[0], _a[size - 1]);_a.pop_back();_AdjustDown(0);}T& Top(){assert(_a.empty());return _a[0];}protected:void _AdjustDown(size_t parent){size_t child = parent * 2 + 1;while (child < _a.size()){Compare<T> com;//选出左右孩子中最小的,有可能节点不存在if (child+1 < _a.size() &&com( _a[child] , _a[child + 1])){++child;}if (com(_a[parent] , _a[child])){std::swap(_a[parent], _a[child]);parent = child;child = 2 * parent + 1;}else{break;}}}void _AdjustUp(int child){int parent = (child - 1) / 2;while (child>0){Compare<T> com;//比较关系的对象if (com(_a[child] , _a[parent])){std::swap(_a[child], _a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}protected:vector<T> _a;};
测试用例:
void Test(){int a[] = { 10, 11, 13, 12, 16, 18, 15, 17, 14, 19 };Heap<int,Greater> hp1(a, sizeof(a) / sizeof(int));hp1.Push(20);cout << endl;}
0 0
- 堆的具体实现
- itext的具体实现
- LocalConnection的具体实现
- String的具体实现
- 归并的具体实现
- malloc的具体实现
- 具体功能的实现
- continue的具体实现
- https的具体实现
- Quartz的具体实现
- 具体的一个MD5实现
- Hibernate DAO的具体实现
- Strategy模式的具体实现
- 虚继承的具体实现
- lucene检索的具体实现
- 黑白名单的具体实现
- fd_set的具体实现过程
- 分页的具体实现方法
- bzoj 1097: [POI2007]旅游景点atr(状压DP)
- hello
- Windows 10年度更新Anniversary Update预览版开始推送,版本号Build 14328
- quartz 任取调度
- 见证者安•兰德 ——冷战自由主义与新保守主义
- 堆的具体实现
- 最大似然估计的一个示例
- MVC,MVP 和 MVVM 的图示
- 浅谈网络流的基本算法 [转]
- eclipse启动Tomcat正常,访问报错404
- 【LeetCode-334】Reverse String
- 使用DOM4j解析XML
- yii框架-数据库简单查询
- SAPI 包含sphelper.h编译错误解决方案