堆在实际应用中非常广泛,尤其是堆排序中,堆分为最小堆和最大堆排序,对应的二叉树也是很好理解,在这里简单介绍下最小堆的数据结构及实现代码(c++编译器中的实现)
1.堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左孩子和右孩子节点的值。
最大堆和最小堆是
二叉堆的两种形式。
最大堆:根结点的键值是所有堆结点键值中最大者。
最小堆:根结点的键值是所有堆结点键值中最小者。
而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。
最大-最小堆是最大层和最小层交替出现的
二叉树,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。
以最大(小)层结点为根结点的子树保有最大(小)堆性质:根结点的键值为该子树结点键值中最大(小)项。
2.堆的实现c++代码
#include <iostream>
using namespace std;
template<class T>//类模板
class MinHeap
{
private:
T *heap; //元素数组,0号位置也储存元素
int CurrentSize; //目前元素个数
int MaxSize; //可容纳的最多元素个数
void FilterDown(const int start, const int end); //自上往下调整,使关键字小的节点在上
void FilterUp(int start); //自下往上调整
public:
MinHeap(int n = 1000);
~MinHeap();
bool Insert(const T &x); //插入元素
T RemoveMin(); //删除最小元素
T GetMin(); //取最小元素
bool IsEmpty() const;
void IsFull() const;
void Clear();
};
template<class T>
MinHeap<T>::MinHeap(int n)//构造函数
{
MaxSize = n;
heap = new T[MaxSize];//堆分配内存一维数组
CurrentSize = 0;
}
template<class T>
MinHeap<T>::~MinHeap()
{
delete[]heap;//删除分配的堆内存
}
template<class T>
void MinHeap<T>::FilterUp(int start) //自下往上调整
{
int j = start, i = (j - 1) / 2; //i指向j的双亲节点
T temp = heap[j];
while (j > 0)
{
if (heap[i] <= temp)
break;//双亲结点值小于子节点值返回
else
{
heap[j] = heap[i];
j = i;
i = (i - 1) / 2;
}
}
heap[j] = temp;
}
template<class T>
void MinHeap<T>::FilterDown(const int start, const int end) //自上往下调整,使关键字小的节点在上
{
int i = start, j = 2 * i + 1;
T temp = heap[i];
while (j <= end)
{
if ((j<end) && (heap[j]>heap[j + 1]))
j++;
if (temp <= heap[j])
break;
else
{
heap[i] = heap[j];
i = j;
j = 2 * j + 1;
}
}
heap[i] = temp;
}
template<class T>
bool MinHeap<T>::Insert(const T &x)
{
if (CurrentSize == MaxSize)
return false;
heap[CurrentSize] = x;
FilterUp(CurrentSize);
CurrentSize++;
return true;
}
template<class T>
T MinHeap<T>::RemoveMin()
{
T x = heap[0];
heap[0] = heap[CurrentSize - 1];
CurrentSize--;
FilterDown(0, CurrentSize - 1); //调整新的根节点
return x;
}
template<class T>
T MinHeap<T>::GetMin()
{
return heap[0];
}
template<class T>
bool MinHeap<T>::IsEmpty() const
{
return CurrentSize == 0;
}
template<class T>
void MinHeap<T>::IsFull() const
{
if (CurrentSize > MaxSize)
{
cout << "堆溢出" << endl;
}
else
{
cout << "堆正常,未溢出,堆大小:" <<CurrentSize<< endl;
}
}
template<class T>
void MinHeap<T>::Clear()
{
CurrentSize = 0;
}
//最小堆:根结点的键值是所有堆结点键值中最小者。
int main()
{
int k, n = 11, a[11] = { 0, 5, 2, 4, 9, 7, 3, 1, 10, 8, 6 };
MinHeap<int> test(11);
for (k = 0; k < n; k++)
test.Insert(a[k]);
test.IsFull();//判断是否溢出
for (k = 0; k < n; k++)
cout << test.RemoveMin() << ends;
cout << endl;
system("pause");
return 0;
}
截图: