堆是具有特殊性质的完全二叉树,如果每个子节点的值都小于父节点的话,我们称之为最大堆;如果每个子节点的值都大于父节点的话,我们称之为最小堆。我们完全可以根据堆的性质来对数组进行排序。
堆排序的c代码如下:
# include <stdio.h>
void maxHeap(int *arr,int i,int n);
void createMaxHeap(int *arr,int i,int n);
void sortMaxHeap(int *arr,int n);
int main(void){
int i;
intarr[10] = {5,1,8,13,17,4,15,22,12,19};
createMaxHeap(arr,0,10);//构建一个最大堆
sortMaxHeap(arr,10); //最大堆排序
for(i=0;i<10;i++){
printf("%d",arr[i]);
}
return 0;
}
void maxHeap(int *arr,int i,int n){
intj,temp;
temp =arr[i];
j =2*i+1;
while(j<n){
if(j+1< n && arr[j] < arr[j+1]){ //在子节点中找比当前的temp更大的值
j++;
}
if(arr[j]< temp){
break; //如果最大值都比temp小的话,就退出
}
//这3行就是一个替换值的过程,有点类似于插入排序
arr[i]= arr[j];
i =j;
j =i*2+1;
}
arr[i] =temp;
}
void createMaxHeap(int *arr,int i,int n){
int j;
for(j =n/2-1;j>=0;j--){ //选取有子节点的父节点
maxHeap(arr,j,n);
}
}
void sortMaxHeap(int *arr,int n){
int i,t;
for(i =n-1;i>=1;i--){
t =arr[i];
arr[i]= arr[0];
arr[0]= t; //交换两个数字后面,可以得到arr[i]必定是余下堆中的最大元素
maxHeap(arr,0,i);//重新排列堆,但是要去除上面已经是最大的元素了
}
}
可以看到,堆由于用到了完全二叉树的性质,所以堆的排序效率也是很高的一种排序操作。其时间复杂度为o(nlogn)。堆排序不适合在数据量小的时候使用,因为构建堆的时候所需的比较次数很多,在小数据量时候,完全体现不出优势,所有只有当数据量较大的时候比较适合堆排序