再看数据结构书的时候,发现堆排序以前根本不懂,以前理解的不是很深刻,对算法也是一知半解,
万一找工作碰到这样的笔试题或者面试题,岂不是over了!
先梳理一下堆排序的知识吧:
堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。
1、堆是完全二叉树,但不一定是满二叉树;
2、因为堆不满足根节点比左节结点大,比右结点小的性质,所以不是二叉排序树,更不可能是平衡二叉树(因为平衡二叉树首先是二叉排序树)。
堆分大根堆和小根堆,一个无序序列第一个非终端结点是第
n/2(取整数)。
对于一个从0开始的数组来说,第一个非终端结点其对应的数组下标是n/2 - 1,其中n是数组长度。
下面看一下从小到大的堆排序代码:
#include <stdio.h>
void swap(int *a,int *b)
{
int t;
t = *a;
*a = *b;
*b = t;
}
//调节第i个元素,建立大根堆
void HeapAdjust(int array[], int i, int length)
{
int nTmp;
int nChild;//用来保存最大的孩子位置
for(nTmp = array[i]; 2*i+1 < length; i = nChild)
{
nChild = 2*i+1;//左孩子
if((nChild < length -1) &&(array[nChild] <array[nChild+1]))
nChild++;
if(array[nChild] > nTmp)//孩子结点最大的与父节点进行比较
array[i] = array[nChild];
else
break;//如果不需要调整,说明已经满足条件了。
array[nChild] = nTmp;//把需要调整的元素
}
}
void HeapSort(int array[], int length)
{
int n1;
n1 = length/2 -1;//最后一个非叶结点
int i;
for( i =n1 ; i>=0; i--)
HeapAdjust(array,i,length);
printf("输出调整后的顺序:\n");
for(i = 0; i < length; i ++)
printf("%d\t",array[i]);
printf("\n");
//需要再进一步才能将数据元素排序好
for( i = length -1; i >= 0; i --)
{
swap(&array[0],&array[i]);//将最大的值交换到最后
HeapAdjust(array,0,i);//调整前面的元素继续构成大根堆
}
//输出从小到大的顺序
printf("输出最终的堆排序结果\n");
for(i = 0; i < length; i ++)
printf("%d\t",array[i]);
printf("\n");
}
int main()
{
int array[] = {2,4,1,5,8,7,9,6,3};
HeapSort(array,9);
return 0;
}
调整堆的时候用的是大根堆,那么输出结果就是从小到大的排序结果。