您的位置:首页 > 其它

堆排序

2018-04-11 19:47 337 查看
/*----------------------------------------------------------------------------------------------------------------------------------------

                                                                 堆排序

排序原理:以数组堆排序法为例.首先将数组堆化,即满足堆的性质,(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
; //变长数组,编译器应支持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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  input 编译器 ini 算法 c