二叉树--堆
来源:互联网 发布:婚礼做电子相册软件 编辑:程序博客网 时间:2024/04/29 10:56
对数据结构是一种数组对象,它可以被视为一颗完全二叉树结构。
堆结构的存储有两种:大堆和小堆,大堆的结构特点是每个父亲的节点都大于孩子的节点,小堆的结构特点是每个父节点的节点都小于孩子节点。
我们以大堆为例进行讲解,如下图所示:
最后得到的二叉树为:
我们代码实现大堆,主要步骤是建堆和向下调整算法。
#include<iostream>#include<vector>using namespace std;template <class>class Heap{public:Heap(){}Heap(T* a, size_t, n){_a.reserve(n);for (size_t i = 0; i < n; ++i){_a.push_back(a[i]);}}void AdjustDown(size_t root)//1,向下调整算法{size_t parent = root;size_t child = parent * 2 + 1;//左孩子while (child < _a.size()){if (_a[child + 1]>_a[child]){++child;}if (_a[child] > _a[parent]){swap(_a[child], _a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}for (int i = (_a.size() - 2) / 2; i > 0; --i){AdjustDown(i);}}void Push(const& T x){_a.push_back(x);AdjustDown(_a, size() - 1);}void Pop(){assert(_a.empty());swap(_a[0], _a[_a.size() - 1]);_a.pop_back();AdjustDown();}const& T Top{return _a[0];}size_t Size(){return _a.size();}bool empty(){return _a.empty();}protected:vector<T> _a;};void TestHeap(){int a[] = { 10, 11, 13, 12, 16, 18, 15, 17, 14, 19 };Heap<int> hp(a, sizeof(a) / sizeof a[0]);hp.Push(20);hp.Pop();}int main(){TestHeap();return 0;}
但是,当我们编写小堆的时候难免会重复很多代码,为了避免这种代码的重复性,提高代码的速率,我们写一个伪函数,这样可以提高效率,因为仿函数是通过模板传递。所以我们将代码改写为下面方式既可以大堆调用也可以小堆调用:
#include<iostream>#include<vector>using namespace std;template <class T>struct Greater{bool operator()(const T& x1, const T& x2){return x1 > x2;}};template <class T>struct Less{bool operator()(const T& x1, const T& x2){return x1 < x2;}};template <class T ,class Compare>class Heap{public:Heap(){}Heap(T* a, size_t, n){_a.reserve(n);for (size_t i = 0; i < n; ++i){_a.push_back(a[i]);}}void AdjustDown(size_t root)//1,向下调整算法{Compare com;size_t parent = root;size_t child = parent * 2 + 1;//左孩子while (child < _a.size()){if (child + 1 < _a.size() && com(_a[child + 1], _a[child)){++child;}if (com(_a[child] , _a[parent])){swap(_a[child], _a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}for (int i = (_a.size() - 2) / 2; i > 0; --i){AdjustDown(i);}}void Push(const& T x){_a.push_back(x);AdjustDown(_a, size() - 1);}void Pop(){assert(_a.empty());swap(_a[0], _a[_a.size() - 1]);_a.pop_back();AdjustDown();}const& T Top{return _a[0];}size_t Size(){return _a.size();}bool empty(){return _a.empty();}protected:vector<T> _a;};void TestHeap(){Greater<int>greater;cout << greater(1, 2) << endl;int a[] = { 10, 11, 13, 12, 16, 18, 15, 17, 14, 19 };Heap<int,Greater<int>> hp(a, sizeof(a) / sizeof a[0]);hp.Push(20);hp.Pop();}int main(){TestHeap();return 0;}
阅读全文
0 0
- 二叉树、二叉堆
- 二叉树 最小堆
- 二叉树堆排序
- 二叉树 - 最大堆
- 堆二叉树
- 二叉树--堆
- 二叉搜索树,堆
- 二叉树与堆
- 二叉树+二叉树搜索树+堆
- 树:二叉树和堆
- 二叉树及堆排序
- 二叉树存储 最小堆
- 二叉树之堆排序
- 二叉搜索树和堆
- 二叉树--堆的实现
- 二叉堆
- 二叉堆
- 二叉堆
- Java遍历包中所有类(完整转载:-))
- struts2第十四讲学习笔记,手动验证与框架验证
- ubuntu17.04下Java开发环境配置(详细步骤)
- 线性表之双链表
- redis完全解读
- 二叉树--堆
- vs2010设置问题
- google搜索
- Mac Python路径总结
- 浮点数精度计算
- 在ubuntu系统下安装lrzsz出现“E: Unable to locate package ...”
- 5月项目经验和技术点文章总结
- VS2010整合NUnit进行单元测试
- JavaWeb开发知识总结(Listener)