二叉树--堆

来源:互联网 发布:婚礼做电子相册软件 编辑:程序博客网 时间: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;}