堆排序的概念
若在输出堆顶的最小值(最大值)后,使待剩余n-1个元素的序列又重建成一个堆,则得到n个元素的次小值(次大值),如此反复,便能得到一个有序序列,这个过程称之为堆排序。
要想实现堆排序,主要需实现以下两点
----由无序堆建成一个堆
----输出堆顶元素后,调整剩余元素为一个新的堆
在这里主要实现第二点即可,学会了堆调整,建堆也就水到渠成了。
堆调整算法范例(C语言) --大根堆
void HeapAdjust(int R[], int s, int m)//调整为大根堆
{
int rc = R[s];
int j;
for (j = 2 * s; j <= m; j *= 2)
{
if ((R[j] < R[j+1]) && j<m)
{
++j;
}//较大key的孩子节点
if (rc >= R[j]) break; //已经大于孩子节点,跳出循环
R[s] = R[j];
//printf("R[%d]: %d\n", j, R[j]);
s = j; //rc应该赋值给位置s上面
printf("j: %d\n", j);
printf("s: %d\n", s);
}
R[s] = rc;
printf("R[%d]: %d\n", s, rc);
}
建堆的过程只需要对完全二叉树的最后一个非叶子节点开始操作即可。
因为单节点树必定是一个堆,完全二叉树的叶子节点也是一个堆。
建堆范例(C语言)
for (i = n / 2; i >= 1; i--)
{
HeapAdjust(R, i, n);
//for (j = 0; j <= 8; j++)
//{
// printf("%d,", R[j]);
//}
//printf("\n");
}
VS2015编译测试结果如下图: