C 实现建堆(heap)的两种方式

#include<stdio.h>
#include<stdlib.h>
#define mindata				-10001
#define maxsize				1000
typedef int ElemType; 
typedef struct	{						//堆的存储结构表示?
	ElemType	*Elems;
	int			 size;
	int			 capacity;	
}HeapStruct,*MinHeap;

void MinHeapCreate (int Maxsize,MinHeap &H)
{
	H->Elems =(ElemType *) malloc((maxsize+1)*sizeof(ElemType));
	H->size=0;
	H->capacity=maxsize;
	H->Elems[0]=mindata;
} 

void swap(MinHeap &H,int a,int b)
{
	int temp;
	temp = H->Elems[a];
	H->Elems[a] = H->Elems[b];
	 H->Elems[b]=temp;
}

void shiftdown(MinHeap &H,int i)
{
    int t,flag=0;//flag用以标记是否需要继续向下调整 
    while(i*2<=H->size&&flag==0)
    {	//首先判断它和左儿子的关系,保用t记录值较小的节点下标 
    	if(H->Elems[i]>H->Elems[2*i]){
    		t=i*2;
    	}else{
    		t=i;
    	}
		//假如他有右儿子,再对右儿子进行讨论
		if(i*2 + 1 <= H->size)
		{
			//如果他的右儿子值更小,更新较小节点的下标给t
			if(H->Elems[t]>H->Elems[i*2+1])
			 	t=i*2+1;
		}
		//如果发现最小编号不是自己,说明子结点中有比父结点更小的
		if(t!=i)
		{
			swap(H,t,i);
			i=t;
		}else{
			flag=1;
		} 
    }
}

void BulidMinHeap(MinHeap &H) 
{
	int i;
	for(i=H->size/2;i>0;i--)
		shiftdown(H,i);
}

int compare(MinHeap &H1,int child,int parent )
{
	int flag=0;
		if(H1->Elems[child]<H1->Elems[parent])
			flag=1;	
	return flag;		
}

void MinHeapinsert(MinHeap &H1,int N)
{
	scanf("%d",&H1->Elems[1]);
	H1->size++;
	int i;
		for(i=2;i<N+1;i++)
		{
		scanf("%d",&H1->Elems[i]);
		H1->size++;
		int j=i;
		while(j/2>0&&j!=1){
		if(compare(H1,j,j/2)==1)
			swap(H1,j,j/2);
			j=j/2;	
		}
		}		
}
void print(MinHeap &H,int M,int *xb)
{
	for(int i=0;i<M;i++)
	{
		scanf("%d",&xb[i]);
	}
	for(int i=0;i<M;i++)
	{
		int a=xb[i];
		while(a>1)
		{
			printf("%d ",H->Elems[a]);
			a=a/2;
		}
		printf("%d\n",H->Elems[1]);	
	}
}
void gettop(MinHeap &H)
{
	int top = H->Elems[1];
	H->Elems[1]=H->Elems[H->size];
	H->size--;
	BulidMinHeap(H);
	printf("%d\n",top);
	for(int i=1;i<=H->size;i++)
	printf("%d ",H->Elems[i]);
}
main()
{
	printf("调整法建堆\n");
	int N,M;
	MinHeap H =(MinHeap) malloc (sizeof(HeapStruct));
	MinHeapCreate (maxsize,H);
	scanf("%d %d",&N,&M);
	getchar();
	for(int i=1;i<N+1;i++){
		scanf("%d",&H->Elems[i]);
		H->size++;
	}		
	BulidMinHeap(H); 
	for(int i=1;i<=H->size;i++)
	printf("%d ",H->Elems[i]);
	putchar(10);
	int xb[maxsize];
	print(H,M,xb);
	
	printf("插入法建堆\n"); 
	MinHeap H1 =(MinHeap) malloc (sizeof(HeapStruct));
	MinHeapCreate (maxsize,H1);
	scanf("%d %d",&N,&M);
	MinHeapinsert(H1,N);
	for(int i=1;i<=H1->size;i++)
	printf("%d ",H1->Elems[i]);
	putchar(10);
	print(H1,M,xb);
	//取顶元素函数,已知堆栈是去一堆数中的最小值或者最大值,则取得就是堆中最大值或者最小值 
	gettop(H);
	
	return 0;	
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值