二叉堆 操作

//二叉堆可以 用(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;
	} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值