堆排序(本例是小顶堆,排出结果是逆序)

时间复杂度为O(nlogn)

将数组堆化,改成小顶堆(本例)

void minheap(int ar[]) {
    int length = sizeof(ar) / sizeof(int);
    //从右往左,自下而上
    //一半的位置是合法的最小堆
    for (int i = length / 2 - 1; i >= 0; i--) {
        mintree(ar, i, length-1);
    }
}

//下面的递归是从小向大,自上而下
void mintree(int ar[],int i, int b) {
    //左右孩子
    int left = i * 2 + 1;
    int right = i * 2 + 2;

    //探讨下标越界的情况,并把min赋给可能的左右孩子
    //如果左孩子越界,那么i就是叶子节点
    if (left >= b) {
        return;//左孩子下标越界,那么右边肯定也越界了,所以不用调整了
    }
    int min = left;//把min初始化为left,方便
    //如果右孩子越界,那么就剩左孩子,所以左孩子就是叶子节点
    if (right >= b) {
        min = left;//于是就把left赋给min,即left直接与i比较
    }
    //如果左右孩子都没越界,
    else {
        //比较左右孩子即可
        if (ar[right] < ar[left]) {
            min = right;
        }
    }
    
    //将上面获得的min与i位置的数比较
    //如果i比小孩子小,就不用换
    if (ar[i] < ar[min]) {
        return;
    }
    int temp = ar[i];
    ar[i] = ar[min];
    ar[min] = temp;

    //进行递归解决由于刚才弄i所造成的损失
    //小孩子那个位置(被换的那面)的值发生了变化,所以i变为小孩子
    mintree(ar, min, b);


}
//进行排序
void sort(int ar[],int b) {

    //先把数组堆化
    minheap(ar,b);

    //对第一个元素与最后一个元素值调换
    for (int i =b; i >= 0;i--) {
        swap(&ar[0], &ar[b]);//进行调换

        //缩小堆的范围,对堆顶元素向下调整
        mintree(ar, 0, b);//从0号开始向下修正
    }
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~失之东隅,收之桑榆~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值