堆排序

图解堆排序:https://www.cnblogs.com/chengxiao/p/6129630.html

//06堆排序

//https://www.cnblogs.com/chengxiao/p/6129630.html
//堆排序不开辟额外的内存,将数组的索引与堆对应起来,将数组看成一个逻辑结构上的堆,由于是完全二叉树,所以有几个特性,索引为s的节点的左子节点为2*s+1,
//叶节点的数量和与非叶节点数量相等或多1个,记数组总长度为lenth,则非叶节点有lenth/2个。
//第一步是构造大顶堆,总体思路是从下往上、从右往左去对非叶节点及其子树进行调整,每次调整保证该节点及其子树成为大顶堆,
//对于1次调整过程,具体的做法是将该节点与子节点中大的值进行交换,直到访问到叶节点。
void heap_adj(int*input, int rootind, int maxind)
{
while (1)
{
int nextind = rootind * 2 + 1;//计算源节点的左子节点
if (nextind > maxind)break;//若左子节点超出范围,退出
if (nextind + 1 <= maxind&&input[nextind + 1] > input[nextind])//nexind指向较大的子节点
nextind++;
if (input[rootind] >= input[nextind])break;//若源节点大于子节点则退出,因为是从下往上、从右往左去对非叶节点及其子树进行调整,所以子树已经是大顶堆。
swap(input[rootind], input[nextind]);//源节点大于子节点则交换
rootind = nextind;
}
}
void heap_sort(int*input, int st, int ed)
{
int lenth = ed - st + 1;
for (int i = lenth / 2 - 1; i >= st; i--)//此循环负责构造大顶堆
{
heap_adj(input, i, lenth-1);
}
for (int i = lenth - 1; i >=st; i--)//依次确定从lenth-1到st的值
{
swap(input[0],input[i]);//把堆顶值与当前待定节点值互换
heap_adj(input, 0, i-1);//调整子堆为大顶堆,大于i的节点(已确定值的节点)不参与调整
}
}


你可能感兴趣的:(C\C++,数据结构与算法分析)