#include<stdio.h>
#include<stdlib.h>
#define parent(i) (i/2)//返回父节点的下标,此程序中未用到
#define left(i) (i*2)//返回左子节点的下标
#define right(i) (i*2+1)//返回右子节点的下标
/*ToBeLargest函数是比较每个父节点和两个
子节点,使父节点的值大于两个子节点*/
void ToBeLargest(int a[],int pos,int length)
{
int largest = pos;
if(left(pos)<=length && a[pos]<a[left(pos)])
largest = left(pos);
if(right(pos)<=length && a[largest]<a[right(pos)])
largest = right(pos);
if(pos != largest)
{
int temp = a[pos];
a[pos] = a[largest];
a[largest] = temp;
ToBeLargest(a,left(pos),length);
ToBeLargest(a,right(pos),length);
}
}
/*makeHeap函数通过对每个节点调用
ToBeLargest函数建立一棵完全二叉树*/
void makeHeap(int a[],int length)
{
int i=length;
for(;i>0;i--)
ToBeLargest(a,i,length);
}
/*SortHeap是堆排序的最后部分,需要一个额外的存储空间来存放结果
堆排序放弃数组下标0,从1开始用下标(因0不能得到子节点节点号)
每一次调用makeHeap能得到一个最大堆,此时的根节点是最大的,取出
放到额外存储空间,然后递减堆深度在重复makeHeap再次得到剩余元素
的最大值,以此得到一个有序序列存储到额外数组空间,该数组就是排序结果*/
void SortHeap(int a[],int length)
{
int savelen = length;
int *afterSort = (int *)malloc(sizeof(int)*length);//申请额外空间
int len = length;
int i = 0;
while(len>=1)
{
makeHeap(a,length);
afterSort[i++] = a[1];
for(int j=0;j<length+1;j++)
a[j] = a[j+1];
length--;
len--;
}
length = savelen;
for(int k=0;k<length;k++)
printf("%d ",afterSort[k]);
}
//test below
int main()
{
int a[12] = {0,2,1,62,12,23,33,44,35,23,20,11};//第一个元素不参与排序
SortHeap(a,11);
return 0;
}
|