本文代码出自:http://blog.youkuaiyun.com/taizhoufox/article/details/5938616
我对代码进行了一些注释
/************************************************
* 测试从数组0号位开始的堆排序
*
* 与上面根元素,则左孩子为2i+1,右孩子为2(i+1);
* 2.孩子不同的知识点
* 1.0号是为i,则父亲为i-1/2
*
*/
/**
* a: 待排序数组
* len: 数组长度
*/
#include <stdio.h>
#include <time.h>
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void show_array( int a[], int n )
{
int i;
for( i = 0; i < n; i++ )
printf( "%d ", a[i] );
printf("\n");
}
void maxHeapAdjust(int a[], int rootIndex,int maxHeapIndex);
void heapSort2(int a[],int len)
{
int i;
int maxHeapIndex = len-1;
//首先建堆
for(i=(maxHeapIndex-1)/2;i>=0;i--) //从最低到上,完全二叉树的最后一个含有子节点的根
{
maxHeapAdjust(a,i,maxHeapIndex);
}
show_array(a,len);
for(i=maxHeapIndex;i>=1;i--)
{
swap(&a[0],&a[i]); // 交换首尾元素,此时尾元素即为当前(0 ~ a[i-1]中最大的元素),调整后要继续堆化时,堆数组最大索引要减1
maxHeapAdjust(a,0,i-1); //从上(a[0])到下调整堆的结构
}
show_array(a,len);
}
/***
* a 待排数组
* rootIndex 本次堆化的根
* maxHeapIndex 本次堆化所达到的堆数组最大索引
* 以a[rootIndex]为根节点的子树之间最大的数,把这个最大数放在根节点a[rootIndex],
* a[rootIndex]上的数替换为a[largest],那么再检查以largest为根节点的子树是否满足最大堆的要求,依次类推
*/
void maxHeapAdjust(int a[], int rootIndex,int maxHeapIndex)//
{
int lChild = rootIndex*2+1;
int rChild = (rootIndex+1)*2;
int largest = rootIndex;
if(lChild <= maxHeapIndex && a[lChild] > a[rootIndex]) //
largest = lChild; //
if(rChild <= maxHeapIndex && a[rChild] > a[largest])
largest = rChild;
if(largest != rootIndex)
{
swap(&a[largest],&a[rootIndex]); //若根节点经过了调整,就要将最大的那个数放在根节点,
maxHeapAdjust(a,largest,maxHeapIndex); //再看看以调整后的以a[largest]为根节点的子树是否还是满足最大堆
}
}
int main()
{
int a[] = {8,6,2,5,7,9,4,6,10,1,3};
int len = sizeof(a)/sizeof(int);
show_array(a,len);
heapSort2(a,len);
show_array(a,len);
return 0;
}