堆排序

/*----------------------------------------------------------------------------------------------------------------------------------------
                                                                 堆排序
排序原理:以数组堆排序法为例.首先将数组堆化,即满足堆的性质,(Ri>=R(2*i+1)&&Ri>=R(2*i+2)或者
               Ri<=R(2*i+1)&&Ri<=R(2*i+2)).具体算法是:从最后一个子节点开始,逐个检查每个子节点和
               父节点的大小关系,将最大的子节点和其父节点交换位置.直到比较到根节点为止.堆化之后
               开始对数组排序,从最后一个子节点倒序分别同根节点交换,每次交换后再对堆进行调整,只是
               调整的过程中将被交换的子节点及其后的所有节点"隐形"掉,就是传递参数的时候,每次将对
               的元素个数减1即可.

               以数组32  15  47  61  9  90据为例简,下面为输出结果(本来画了半天的图,准备逐步上传,结果

               太麻烦了,直接上结果了):

 

------------------------------------------------------------------------------------------------------------------------------------------*/

#include<stdio.h>
#define PR() for(j=0;j<=len;j++)printf(" %3d ",ar[j]);putchar('\n') //宏定义,打印各元素
void Heap_Adjust(int ar[],int i,int len);
void Heap_Sort(int ar[],int len);
int main(void)
{
	int i,n;	
	puts("Input the number of elements to the array:");
		scanf("%d",&n);
	int ar[n];                      //变长数组,编译器应支持C99标准
	printf("Input %d elements of the array:\n",n);
	for(i=0;i<n;i++)                //读取数组元素
		scanf("%d",&ar[i]);
	Heap_Sort(ar,n-1);               
	printf("\nFinal ruslt : ar[%d] = ",n);
	for(i=0;i<n;i++)                //逐个打印数组元素             
		printf("%d  ",ar[i]);        
	putchar('\n');getchar();getchar();
	return 0;
}
void Heap_Adjust(int ar[],int father,int len)// 堆调整,满足堆的性质
{
	int child,temp;	
	temp=ar[father];
	while(2*father+1<=len)
	{
		child=2*father+1;		
		if(child+1<=len && ar[child]<ar[child+1]) //找到子节点中最大的一个,如果只有一个(child=len-1),那么跳过此步
			child++;
		if(temp>ar[child])                        //父节点和最大的子节点比较,满足(Rk>=R(2k+1)&&Rk>=R(2k+2))
			break;                      
		ar[father]=ar[child];                               		
		father=child;                             //让当前子节点成为父节点
	}
	ar[father]=temp;                             //把最大的一个元素给当前看作父节点的那个节点
}
void Heap_Sort(int ar[],int len)//堆排序,从最后一个子节点倒序分别同根节点交换
{
	int i,j,temp;
	for(i=len/2;i>=0;i--)                     //堆调整,需要从底部-顶部的顺序调整
		Heap_Adjust(ar,i,len);
	printf("Array to heap: ar[%d] = ",len+1);
	PR();
	putchar('\n');
	for(i=len;i>0;i--)                       //元素交换                     
	{
		temp=ar[0];
		ar[0]=ar[i];
		ar[i]=temp;
		Heap_Adjust(ar,0,i-1);		        //交换一次对堆调整一次,注意,每次调整时不能管和根节点交换的那个节点,所以传递参数为i-1
		printf("Change %d : ar[%d] = ",len-i+1,len+1);
		PR();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值