//二叉堆可以 用(1)Insert构建 (2)可以先建完全二叉树 后调整
// 后者的 时间小一些
#include<stdio.h>
#include<stdlib.h>
#define MaxData 1000001
#define MaxS 100
typedef int Tree;
typedef int ElementType;
typedef struct HeapNode *Heap;
struct HeapNode{
ElementType *Array;
int Size;
};
Heap Initialize(int MaxSize)
{
Heap H;
H = (Heap)malloc(sizeof(struct HeapNode));
if(H == NULL){
printf("Error");
return NULL;
}
H->Array = (ElementType*)malloc((MaxSize+1)*sizeof(ElementType));
if(H->Array == NULL){
printf("Error");
return NULL;
}
H->Array[0] = MaxData;
H->Size = 0;
}
void Insert(ElementType X, Heap H) // 插入操作为 上滤 例程
{
int i;
for(i = ++H->Size; H->Array[i/2] < X; i /= 2){ //利用哨兵
H->Array[i] = H->Array[i/2];
}
H->Array[i] = X;
}
void PreTrv(Heap H)// 遍历
{
int i;
for( i = 1; i <= H->Size; i++ ){
printf("%d ",H->Array[i]);
}
}
// 自顶向下先找到最后一个非叶节点开始逐个递减的构建小堆
// 并且在每个非叶节点出采用采用下滤法 找到合适的位置
// 复杂度为O(NlongN)
void MaxHeap(Heap H, int Size)
{
int i;
ElementType Temp;
int Parent;
int Child;
int j;
for(Parent = Size/2; Parent >= 1; Parent--){
Temp = H->Array[Parent];
for(j = Parent; j*2 <= H->Size; j = Child ){
Child = j*2;
//找到最大儿子
if(Child != H->Size && H->Array[Child] < H->Array[Child+1]){
Child++;
}
//与当前根节点比较
//如果不满足最大堆 则下滤
if(Temp < H->Array[Child])
H->Array[j] = H->Array[Child];
else{
break;
}
}
H->Array[j] = Temp;//找到合适的节点 替换
}
}
void Adjust(Heap H, int i, int Size) //把上面的 下滤写成 函数模块形式
{
int Child;
ElementType Temp;
for(; 2*i <= Size; i = Child){
Child = i*2;
if(Child != Size && H->Array[Child] < H->Array[Child+1]){
Child++;
}
if(H->Array[Child] > H->Array[i]){
Temp = H->Array[Child];
H->Array[Child] = H->Array[i];
H->Array[i] = Temp;
}
else
break;
}
}
void MaxHeap2(Heap H, int Size)
{
int i;
for(i = Size/2; i >= 1; i--){
Adjust(H, i, Size);
}
ElementType Temp;
}
void CreateHeap(Heap H)
{
int X;
scanf("%d",&X);
while(X != -1){
H->Array[++H->Size] = X;
scanf("%d",&X);
}
// 开始设置返回Heap 又忘记return 了 。。。。 干脆不设返回值
}
ElementType DeleteMin(Heap H)
{
int Parent, Child;
ElementType MinVal, LastVal;
MinVal = H->Array[1];//记录下来 等下返回
LastVal = H->Array[H->Size--];
for(Parent = 1; Parent * 2 <= H->Size; Parent = Child){ // 这 就是个 下滤过程
Child = Parent*2;
if(Child != H->Size && H->Array[Child] < H->Array[Child+1]){
Child++;
}
if(LastVal < H->Array[Child]){
H->Array[Parent] = H->Array[Child];
}
else{
break;
}
}
H->Array[Parent] = LastVal; //为 最后多出那个数找合适节点
return MinVal;
}
int main()
{
Heap H, H1;
H = Initialize(MaxS);
CreateHeap(H); //
//MaxHeap2(H, H->Size);
MaxHeap2(H, H->Size);
PreTrv(H);
printf("\n");
printf("Minimum = %d\n",DeleteMin(H));
PreTrv(H);
return 0;
}