您的位置:首页 > 其它

最大堆最小堆的建立

2017-05-22 11:41 316 查看
堆是一种数据结构,它是一颗完全二叉树,最大堆和最小堆是二叉堆的两种形式。

最大堆:每个父亲结点的键值都大于孩子结点

最小堆:每个父亲结点的键值都小于孩子结点

下面看一下我的实现方式↓

#pragma once
#include
using namespace std;

template
struct Great
{
bool	operator()(const T& left ,const T& right)const
{
return left > right;
}
};

template
struct Less
{
bool	operator()(const T& left, const T& right)const
{
return left < right;
}
};

template>
class Heap
{
public:
Heap()
{}

Heap(T* a, size_t n)      //用一个数组构建堆的构造函数
{
_arr.reserve(n);
for (int i = 0; i < n; i++)
{
_arr.push_back(a[i]);
}

//调整堆
for (int i = (_arr.size() - 2) / 2; i >= 0; --i)
{
AdjustDown(i);
}
}

void AdjustDown(int root)      //向下调整算法
{
Comp com;
int parent = root;
int child = parent * 2 + 1;
while (child < _arr.size())
{
if (child + 1 < _arr.size() && com(_arr[child + 1] , _arr[child]))
{
child++;
}
if (com(_arr[child],_arr[parent]))
{
swap(_arr[child], _arr[parent]);
parent = child; child = parent * 2 + 1;
}
else break;    //循环到孩子小于父亲便可停止
}
}
void AdjustUp(int child)    //向上调整算法
{
Comp com;
int parent = (child - 1) / 2;
while (parent >= 0)
{
if (com(_arr[child], _arr[parent]))
{
swap(_arr[parent], _arr[child]);
child = parent;
parent = (child - 1) / 2;
}
else
break;
}
}

void Push(const T& x)    //从堆尾插入一个数据  (数组尾)
{
_arr.push_back(x);
AdjustUp(_arr.size() - 1);
}
void Pop()             //删除堆顶数据  (数组头)
{
swap(_arr[0], _arr[_arr.size() - 1]);
_arr.pop_back();
AdjustDown(0);
}
size_t Size()   //返回大小
{
return _arr.size();
}

bool Empty()  //是否为空
{
return _arr.empty();
}
T& Top()   //返回 堆顶数据
{
assert(_arr.size() > 0);
return _arr[0];
}
protected:
vector _arr;    //一个vector  堆的底层是一个数组;
};


其中 向上调整与向下调整是建立一个最大最小堆的关键;调整时的比较大小是利用一个仿函数进行选择默认为大堆;

堆的作用挺大,比如优先级队列,top K问题 ,或者选择排序都用到堆的结构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: