堆排序其实就是借助于数据结构中二叉树的思想来进行排序,将需要排序的数据看成一个从上往下,从左到右排列的完全二叉树。从最后带有子节点的节点开始进行筛选,将最大或最小的数据移到根节点的位置,将这个根节点拿出来,重新在剩下的数据中寻找另一个根节点。
堆排序在比较使具有记忆功能,所以可以减少数据的比较次数。对数据量比较的排序比较有效,但对于数据比较小的排序不提倡。
/************************************************************************/
/* Function:堆排序 */
/* Parameter:array[]将要被排序的数组,len:array数组的长度 */
/* return:void */
/************************************************************************/
void HeapSort(int array[], int len)
{
for (int i = len/2 - 1; i >= 0; --i)
{
HeapAdjust(array, i, len); //从最后一个有孩子节点的元素开始排序,这个节点的下表即为len/2 - 1
}
for (int j = len - 1; j > 0; --j)
{
int temp = array[0]; //此时根节点为筛选数据中的最大值,或最小值,把这个值取出来,与数组最后位置上需要筛选的节点进行交换
array[0] = array[j];
array[j] = temp;
HeapAdjust(array, 0, j); //原来根节点以下的节点都经过筛选,所以只需根节点筛选
}
return;
}
/************************************************************************/
/* Function:节点筛选与移动,将数据较小的节点往根节点移动 */
/* Parmeter:array[]:将要被排序的数组,s:筛选节点在数组中的位置,m:筛选 */
/* 的数组的长度 */
/* Return: void */
/************************************************************************/
void HeapAdjust(int array[], int s, int m)
{
int temp = array[s]; //标记筛选节点的值
for (int j = 2 * s + 1; j < m; j = 2 * j + 1) //循环将筛选节点与子节点,孙节点比较
{
if ((j < m - 1) && (array[j] > array[j + 1])) //判断节点的两个子节点的大小,找出根节点中数据较小的节点为比较节点
{
j++;
}
if (temp <= array[j]) //若筛选节点比较小的子节点的数据还小,则退出循环,不需要与子节点交换位置
{
break;
}
array[s] = array[j]; //若当前节点比较小的子节点的数据要大,则将数据较小的子节点往上移
s = j; //空出来的位置,暂时想象用来存放筛选节点,将来或许存放比当前筛选节点更小的孙节点
}
array[s] = temp; //最后空出来的位置存放筛选节点
return;
}