结构定义
#include <iostream>
#include <algorithm>
using namespace std;
const int MaxV = 100;
const int MaxData = 1000; //大于最大堆中所有元素可能的值
typedef struct HNode{
int *Data; //储存元素的数组
int Size; //堆中当前元素个数
int Capacity; //堆的最大容量
} * Heap;
typedef Heap MaxHeap; //最大堆
typedef Heap MinHeap; //最小堆
最大堆的初始化
/*创建最大容量为MaxSize的空的最大堆*/
MaxHeap CreateHeap(int MaxSize)
{
MaxHeap H = new HNode;
H->Data = new int[MaxSize + 1]();
H->Size = 0;
H->Capacity = MaxSize;
H->Data[0] = MaxData; //定义"哨兵"为大于堆中所有可能元素的值
return H;
}
最大堆的插入
/*最大堆的插入
1. 先将元素插入堆的末尾
2. 从末尾元素开始向上遍历,如果x大于x的父节点,交换父子的值
3. 直到x不大于x的父亲
*/
void InsertMaxHeap(MaxHeap H, int x)
{
if(H->Size == H->Capacity)
return;
int i;
for (i = ++H->Size; H->Data[i / 2] < x; i/=2) //退出循坏条件是,x的父亲 >= x
H->Data[i] = H->Data[i / 2]; //满足条件,进入循环交换元素(上滤x)
H->Data[i] = x; //类似于插入排序的交换
}
最大堆的删除
/*最大堆的删除
1. 最大值为树根,取出最大值然后将堆末尾元素插入树根
2. 调整堆,从作为调整的子树的根判断,选出最大的孩子与根比较
3. 若孩子大于根,交换
4. 以交换后的孩子作为新的调整的子树的根,重复2,3
5. 若发现两个孩子都 <= 根,退出循环
*/
int DeleteMaxHeap(MaxHeap H)
{
if(H->Size == 0) //如果堆为空,返回MaxData表示删除失败
return MaxData;
int MaxItem = H->Data[1];
int x = H->Data[H->Size--]; //需要插入的堆末尾元素
int i, child;
//如何确定循环次数? //最大循环次数是: 当以x为根的孩子是最后一个元素时,即 i*2 = H->Size
for (i = 1; i * 2 <= H->Size ; i = child) //i为父亲,父亲从上往下(下滤x)
{
child = i * 2; //根的左孩子 //child != H->Size 是为了保证x有两个孩子
if((H->Data[child] < H->Data[child + 1]) && child != H->Size) //H->Size == child 则child + 1会数组溢出
child++; //孩子更新为最大孩子
/*下面是比较*/
if(x >= H->Data[child])
break;
else
H->Data[i] = H->Data[child]; //注意是哪两个比较
}
H->Data[i] = x;
return MaxItem;
}
最大堆的建立
/*最大堆的建立
1. 由上述最大堆的删除可知,在一个排好序的堆中,改变根的值,然后下滤,能调整为堆
2. 根据堆的子树也是堆的性质,从H->Size/2开始,向上遍历依次下滤
*/
void PercDown(MaxHeap H, int k) //以下标为k进行类似堆的删除的下滤!!!
{
int x = H->Data[k];
int i, child;
for (i = k; i * 2 <= H->Size; i = child)
{
child = i * 2;
if((H->Data[child] < H->Data[child + 1]) && child != H->Size)
child++;
if(x >= H->Data[child])
break;
else
H->Data[i] = H->Data[child];
}
H->Data[i] = x;
}
void BuildHeap(MaxHeap H)
{
for (int i = H->Size / 2; i > 0; i--)
PercDown(H, i); //从H->Size/2开始向上
}
int main()
{
MaxHeap H = CreateHeap(MaxV);
int n;
cin >> n;
int *Array = new int[n];
// for (int i = 0; i < n; i++)
// {
// cin >> Array[i];
// InsertMaxHeap(H, Array[i]);
// }
for (int i = 1; i <= n; i++)
cin >> H->Data[i];
H->Size = n;
BuildHeap(H);
for (int i = 0; i <= n; i++)
cout << H->Data[i] << " ";
cout << endl;
delete[] Array;
delete[] H->Data;
delete H;
system("pause");
return 0;
}
input:
10
10 26 56 98 48 74 12 32 65 22
output:
1000 98 65 74 32 48 56 12 10 26 22
堆排序常用于快速找最值,如Prim算法的找最小边