二叉堆是完全二叉树或者是近似完全二叉树。
二叉堆满足二个特性:
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。用最大堆实现堆排序的代码如下。
/************************************************
*** heapSort.c
*** 堆排序的实现(大顶堆)
*************************************************/
#include <stdio.h>
#define leftChild( i ) ( 2 * ( i ) + 1)
void percolateDown( int A[], int i, int n )
{
int nTmp = 0;
int nChild = 0;
for (nTmp=A[i]; leftChild(i)<n; i=nChild)
{
nChild = leftChild( i ); /** 左孩子 **/
if ( nChild != n - 1 && A[nChild] < A[nChild+1] ) /** 若满足大顶堆条件 **/
{
nChild++;
}
if ( nTmp < A[nChild] ) /** 若父节点小于左孩子 **/
{
A[i] = A[nChild];
}
else
{
break;
}
}
A[i] = nTmp;
}
void swap( int *x, int *y )
{
int nTmp = 0;
nTmp = *x;
*x = *y;
*y = nTmp;
}
void heapSort( int A[], int n )
{
int i = 0;
/**
*** 建立大顶堆
**/
for (i=n/2; i>=0; i--)
{
percolateDown( A, i, n );
}
/**
*** 堆排序
**/
for (i=n-1; i>0; i--)
{
swap( &A[0], &A[i] );
percolateDown( A, 0, i );
}
}
int main()
{
int i = 0;
int n = 13;
int nArray[13] = {81, 94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15};
printf("The arrry before heapSort is: \n");
for (i=0; i<n; i++)
{
printf("%d ", nArray[i]);
}
printf("\n\n");
heapSort( nArray, n ); /** 调用堆排序 **/
printf("The arrry after heapSort is: \n");
for (i=0; i<n; i++)
{
printf("%d ", nArray[i]);
}
printf("\n");
return 0;
}