C++ 堆排序

01 思路

以从小到大排列为例。

代码用到以下几个模块

  • swap模块
    • 完成一个数组中的两个位置的元素交换
  • heapify模块
    • 完成将一个子树构建为根节点最大的形式。
    • 如果根节点不是最大值,那么交换后将对传入最大位置的序号进行递归。
  • build_heap模块
    • 从倒数第二层开始反向依次调用heepify模块,直到0节点。
  • sort模块
    • 首先调用build_heap建堆,再从最后一个位置依次与0位置交换,并且每次交换后对0位置进行heapify。

02 Show me the code

#include <iostream>

using namespace std;


// 堆排序======================================================
void swap(float ar[], const int dex_a, const int dex_b) {
    if (dex_a == dex_b) {
        return;
    }

    float temp = ar[dex_a];
    ar[dex_a] = ar[dex_b];
    ar[dex_b] = temp;
}

void heapify(float ar[], const int len, const int dex_of_now) {
    // 计算其左孩子、右孩子的序号
    const int left_c = 2 * dex_of_now + 1;
    const int right_c = 2 * dex_of_now + 2;

    if (dex_of_now >= len) {
        return;
    }

    int max = dex_of_now;

    if (left_c < len && ar[left_c] > ar[max]) {
        max = left_c;
    }

    if (right_c < len && ar[right_c] > ar[max]) {
        max = right_c;
    }

    if (max != dex_of_now) {
        swap(ar, max, dex_of_now);
        heapify(ar, len, max);
    }
}

void build_heap(float ar[], const int len) {
    int i = 0;
    for (i = (len - 2) / 2; i >= 0; --i) {
        heapify(ar, len, i);
    }
}

void sort(float origin[], const int size) {
    // 建堆
    build_heap(origin, size);

    // 倒序遍历调换
    int i = 0;
    for (i = size - 1; i >= 0; --i) {
        swap(origin, 0, i);
        // 交换后0节点heapify
        heapify(origin, i, 0);
    }
}
// =======================================================


void show(float ar[], const int LEN) {
    for (int i = 0; i < LEN; ++i) {
        cout << ar[i] << " ";
    }
    cout << endl;
}


int main() {
    const int N = 15;
    float* origin = new float[N];

    for (int i = 0; i < N; ++i) {
        origin[i] = rand() % 100;
    }

    cout << "原始数组:" << endl;
    show(origin, N);
    cout << endl;

    // 排序
    sort(origin, N);

    cout << "堆排序后:" << endl;
    show(origin, N);

    return 0;
}

03 结果

原始数组:
7 49 73 58 30 72 44 78 23 9 40 65 92 42 87

堆排序后:
7 9 23 30 40 42 44 49 58 65 72 73 78 87 92

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值