• 算法导论学习笔记(三):堆排序


    堆排序是一种利用堆的性质进行的排序算法。所以学习堆排序之前先来简单介绍下堆。

    堆数据结构是一种数组对象,如图一所示,它可以被视为一颗完全二叉树。

       

         图一

    树中的每个结点与数组中存放该结点值的那个元素对应。树的每一层都是填满的,最后一层可能除外。如果树的结点

    和数组的下标都从0开始,那么给定了某个结点的下标i,其父节点PARENT(i)、左儿子LEFT(i)和右儿子RIGHT(i)的下

    标可以简单的计算出来:

    PARENT(i) = (i - 1) / 2;注:右边的结果取整数部分

    LEFT(i) = 2 * i + 1;

    RIGHT(i) = 2 * (i + 1);

    最大堆和最小堆

    这是堆排序中要用到的两种堆,它们的结点内的数值都要满足堆特性,其细节则由堆的种类而定。在最大堆中,最大

    堆特性是指除了根意外的每个结点i,有a[PARENT(i)] >= a[i],即某个结点的值至多是和其父节点的值一样大。这样,

    堆中的最大元素就存放在根结点中;并且,在以某一个结点为根的子树中,各结点的值都不大于该子树根节点的值。

    最小堆的组织方式则刚好相反。在堆排序算法中,我们一般使用的是最大堆。

    堆排序思想

    1.将输入的数组构造出一个最大堆,并求出堆的大小heap_size = n

    2.将堆顶元素a[0]和最后一个元素a[heap_size - 1]交换

    3.堆的大小减小1,即heap_size = heap_size - 1

    4.因为调整了堆的大小和交换了元素,所以新的堆可能不满足最大堆的特性,所以对新的堆进行调整,使其再次满足

       最大堆的特性。实现这个调整的函数为:max_heapify

    5.重复步骤2、3、4,直到堆只剩下最后一个元素

    实现代码

    [cpp] view plaincopyprint?

    #include<iostream> 

    using namespace std; 

       

    int heap_size; 

       

    inline int LEFT (int i) 

        return 2 * i + 1; 

       

    inline int RIGHT (int i) 

        return 2 * (i + 1); 

       

    void display (int a[], int n); 

    void swap (int& n, int& m); 

    void max_heapify (int a[], int i); 

    void bulid_max_heap (int a[], int n); 

    void heap_sort (int a[], int n); 

       

    int main() 

        int a[100]; 

        int n; 

        while (cin >> n) 

        { 

            for (int i = 0; i < n; i++) 

                cin >> a[i]; 

            heap_sort (a, n); 

            display (a, n); 

        } 

        return 0; 

       

    void display (int a[], int n) 

        for (int i = 0; i < n; i++) 

            cout << a[i] << " "; 

        cout << endl; 

       

    void swap (int& n, int& m) 

        int temp; 

        temp = n; 

        n = m; 

        m = temp; 

       

    void max_heapify (int a[], int i) 

        int l = LEFT (i); 

        int r = RIGHT (i); 

        int largest; 

       

        if ((l < heap_size) && a[l] > a[i]) 

            largest = l; 

        else 

            largest = i; 

       

        if ((r < heap_size) && a[r] > a[largest]) 

            largest = r; 

       

        if (largest != i) 

        { 

            swap (a[largest], a[i]); 

            max_heapify (a, largest); 

        } 

       

    void build_max_heap (int a[], int n) 

        heap_size = n; 

        for (int i = (n - 1) / 2; i >= 0; i--) 

            max_heapify (a, i); 

       

    void heap_sort (int a[], int n) 

        build_max_heap (a, n); 

        for (int i = n - 1; i >= 1; i--) 

        { 

            swap (a[i], a[0]); 

            heap_size--; 

            max_heapify (a, 0); 

        } 

  • 相关阅读:
    在Qt中使用sleep
    Qt深入:不能不知道的Type、Attribute和Flags
    浅析mysql 共享表空间与独享表空间以及他们之间的转化
    taobao月报 ---mysql汇总
    slave_net_timeout
    LINUX 内核算杂 七杂 八
    Hadoop可视化与交互式工具:Zeppelin和Hue
    看开源代码利器—用Graphviz + CodeViz生成C/C++函数调用图(call graph)
    python 学习笔记十四 jQuery案例详解(进阶篇)
    MySQL如何选择float, double, decimal
  • 原文地址:https://www.cnblogs.com/fuyou/p/3233279.html
Copyright © 2020-2023  润新知