• (12)选择排序之三 堆排序


          堆排序(Heap Sort),只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。堆的定义如下:n个元素的序列{k1, k2, … , kn}当且仅当满足下关系时,称之为堆。

    Ki <= K2i && Ki <= K2i+1 或 Ki >= K2i && Ki >= K2i+1,(i = 1, 2, … , n/2」)。若将和此序列对应的一维数组看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。理解:若在输出堆顶的最小值之后,使得剩余的n – 1个元素的序列重又建成一个堆,则得到n个元素中的次小值。如此反复执行,便能得到一个有序序列,这个过程称之为堆排序。时间复杂度为O(nlogn)

          由此,实现堆排序需要解决两个问题:(1)如何由一个无序序列建成一个堆?(2)如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?

    // 堆排序
    void CSelectionSort::HeapSort(void)
    {
    const int count = 9, length = count -1;
    int L[count] = {0, 49, 38, 65, 97, 76, 13, 27, 49};
    int i = 0;
    for (i = length / 2; i > 0; -- i)
    HeapAdjust(L, i, length);
    for (i = length; i > 1; -- i)
    {
    int temp = L[1];
    L[
    1] = L[i];
    L[i]
    = temp;
    HeapAdjust(L,
    1, i - 1);
    }
    //打印排序结果。
    for (int i = 0; i < count; ++ i)
    {
    cout
    << L[i] << "\t";
    }
    cout
    << endl;
    }


    // 堆排序之堆调整
    void CSelectionSort::HeapAdjust(int H[], int s, int m)
    {
    int rc = H[s];
    for (int j = 2 * s; j <= m; j *= 2)
    {
    if (j < m && H[j] < H[j + 1])
    ++ j;
    if (rc >= H[j])
    break;
    H[s]
    = H[j];
    s
    = j;
    }
    H[s]
    = rc;
    }

  • 相关阅读:
    检查LigthGBM&XGBoost&Catboost是否支持GPU
    conda 与 pip 混用的问题
    notable禁用更新
    内存管理
    密码学的安全性浅析3
    一次苦逼的SQL注入
    CVE20220847漏洞复现及修复建议
    Kernel pwn 基础教程之 ret2usr 与 bypass_smep
    密码学的安全性浅析2
    SQLMAPTamper之较为通用的双写绕过
  • 原文地址:https://www.cnblogs.com/wanggary/p/2036946.html
Copyright © 2020-2023  润新知