• 堆排序(数据结构)


    在这里插入图片描述

    堆排序

    在这里插入图片描述

    建立大根堆

    在这里插入图片描述
    在这里插入图片描述

    大根堆代码实现
    /**
     * 大根堆:根 >= 左、右
     * 注意:基于【大根堆】的排序得到的序列是【递增序列】
     * @file HeapSort_Max.cpp
     */
    
    #include 
    
    using namespace std;
    
    // 建立大根堆
    void BuildMaxHeap(int arr[], int len);
    
    // 将元素k为根的子树进行调整
    void MaxHeapAdjust(int arr[], int k, int len);
    
    // 堆排序
    void HeapSort_Max(int arr[], int len);
    
    // 交换元素
    void Swap1(int &a, int &b);
    
    
    
    void BuildMaxHeap(int arr[], int len) {
        // 检查所有的非叶子结点,看是否满足大根堆的要求,反复调整堆
        for(int i = len/2;i > 0;i--) {
            MaxHeapAdjust(arr, i, len);
        }
    }
    
    void MaxHeapAdjust(int arr[], int k, int len) {
        arr[0] = arr[k]; // arr[0]暂存子树的根节点
        for(int i = 2*k;i <= len;i *= 2) {
            // 左孩子 < 右孩子
            if(i < len && arr[i] < arr[i+1]) {
                i++;
            }
            if(arr[0] > arr[i]) { // 双亲结点大,筛选结束
                break;
            } else {
                arr[k] = arr[i]; // 将较大的孩子结点调整到双亲结点
                k = i;
            }
        }
        arr[k] = arr[0];
    }
    
    void HeapSort_Max(int arr[], int len) {
        BuildMaxHeap(arr, len); // 初始建立大根堆
        for(int i = len;i > 1;i--) {
            // arr[0]不存元素,arr[1]是堆顶元素,每交换一次都相当于把大的元素放到数组后面
            Swap1(arr[i],arr[1]);
            // 交换后,把剩余i-1个元素整理成堆
            MaxHeapAdjust(arr, 1, i-1);
        }
    }
    
    void Swap1(int &a, int &b) {
        int temp = a;
        a = b;
        b = temp;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    小根堆代码实现
    /**
     * 小根堆:根 <= 左、右
     * 注意:基于【小根堆】的排序得到的序列是【递减序列】
     * @file HeapSort_Min.cpp
     */
    
    #include 
    
    using namespace std;
    
    // 建立小根堆
    void BuildMinHeap(int arr[], int len);
    
    // 将元素k为根的子树进行调整
    void MinHeapAdjust(int arr[], int k, int len);
    
    // 堆排序
    void HeapSort_Min(int arr[], int len);
    
    // 交换元素
    void Swap2(int &a, int &b);
    
    
    
    void BuildMinHeap(int arr[], int len) {
        // 检查所有的非叶子结点,调整为小根堆
        for(int i = len/2;i > 0;i--) {
            MinHeapAdjust(arr, i, len);
        }
    }
    
    void MinHeapAdjust(int arr[], int k, int len) {
        // 将以k为根节点的子树调整为小根堆
        arr[0] = arr[k];
        for(int i = 2*k; i <= len; i*=2) {
            // 寻找左、右孩子中较小的结点
            if(i < len && arr[i] > arr[i+1]) {
                i++;
            }
            if(arr[0] <= arr[i]) {
                break; // 不用调整,结束
            } else {
                arr[k] = arr[i];
                k = i;
            }
        }
        arr[k] = arr[0];// 将被筛选的结点放入最终位置
    }
    
    void HeapSort_Min(int arr[], int len) {
        BuildMinHeap(arr, len);// 初始建立小根堆
        for(int i = len; i > 1;i--) {
            Swap2(arr[i], arr[1]);
            MinHeapAdjust(arr, 1, i-1);
        }
    }
    
    void Swap2(int &a, int &b) {
        int temp = a;
        a = b;
        b = temp;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    main函数
    #include 
    #include 
    #include 
    #include "HeapSort_Max.cpp"
    #include "HeapSort_Min.cpp"
    
    using namespace std;
    
    /**
     * 使用当前时钟作为随机数种子:
     * rand() 产生的随机数在每次运行的时候都是与上一次相同的。若要不同, 
     * 用函数 srand() 初始化它。可以利用 srand((unsigned int)(time(NULL)) 的方法,
     * 产生不同的随机数种子,因为每一次运行程序的时间是不同的。
     */
    int main() {
        // 要取得 [a,b] 的随机整数,使用 (rand() % (b-a+1))+ a;
        int arr[10];
        int a = 1,b = 200;
        srand((unsigned)time(NULL)); 
        for(int i = 1;i <= 10;i++) {
            arr[i] = (rand() % (b-a+1))+ a;
        }
        cout << "原序列:";
        for(int i = 1;i <= 10;i++) {
            cout << arr[i] << " ";
        }
        cout << endl;
    
        // HeapSort_Max(arr, 10);
        HeapSort_Min(arr, 10);
        cout << "排序后:";
        for(int i = 1;i <= 10;i++) {
            cout << arr[i] << " ";
        }
        cout << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    堆排序的效率分析

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    堆的插入和删除

    在这里插入图片描述

    注:以上图片来自B站王道数据结构截图

  • 相关阅读:
    Node.js 使用 officecrypto-tool 读取加密的 Excel (xls, xlsx) 和 Word( docx)文档
    达梦管理工具报错“结果集不可更新,请确认查询列是否出自同一张表,并且包含值唯一的列。”
    算法笔记:点四叉树
    mmap使用测试
    C++ 字符串编码转换封装函数,UTF-8编码与本地编码互转
    C#写一个UDP程序判断延迟并运行在Centos上
    气象数据库分析
    3297:【例50.3】 平衡数《信息学奥赛一本通编程启蒙(C++版)》
    基于jsp+mysql+Spring+mybatis+VUE的SpringBoot电影院会员积分管理系统
    Numpy 实现全连接神经网络
  • 原文地址:https://blog.csdn.net/weixin_45410366/article/details/127823263