zoukankan      html  css  js  c++  java
  • 堆排序

    堆排序是选择排序的一种,下面是堆排序的一些特征:

    • 时间复杂度,最好最坏平均都为:O(nlog2n)
    • 空间复杂度,最好最坏平均都为:O(1)
    • 是否稳定:不稳定
    • 建堆的时间复杂度为:O(n)

    堆排序的一次循环可以将最大或者最小的一个元素放在最终位置上

    tip: 你需要了解的前置知识有 二叉树相关概念,完全二叉树的连续存储方式,完全二叉树的一些数学特性

    下面是堆排序的代码,建立的堆是大顶堆,每次会把最大的一个元素放在最终位置上:

    /**
    * arr 数组首地址
    * len 数组长度
    */
    void heap_sort(int *arr, int len)
    {
        int i;
        build_max_heap(arr, len);       // 建立大顶堆
        for (i=len-1; i>0; i--) {       // 排序
            swap(arr, arr+i);           // 将最大的元素放到最后面
            adjust_down(arr, 0, i);     // 使前len-1个元素重新变成大顶堆
        }
    }
    
    /**
    * 交换两个元素的值
    */
    void swap(int *px, int *py)
    {
        int temp = *px;
        *px = *py;
        *py = temp;
    }
    
    /**
    * 建立大顶堆
    */
    void build_max_heap(int *arr, int len)
    {
        int i;
        for (i=len/2-1; i>=0; i--)
            adjust_down(arr, i, len);
    }
    
    /**
    * 将元素k向下进行调整
    */
    void adjust_down(int *arr, int k, int len)
    {
        int i;
        int temp = arr[k];
        for (i=2*k+1; i<len; i=i*2+1) {
            if (i<len-1 && arr[i]<arr[i+1])
                i++;                // 选取较大的子结点
            if (temp>=arr[i]) break;
            else {
                arr[k] = arr[i];    // 将arr[i]上调
                k = i;
            }
        }//for
        arr[k] = temp;
    }
    

    测试代码,可直接复制后编译执行:

    #include <stdio.h>
    
    void show(int arr[], int len);
    void swap(int *px, int *py);
    void heap_sort(int *arr, int len);
    void build_max_heap(int *arr, int len);
    void adjust_down(int *arr, int k, int len);
    
    int main()
    {
        int len = 7;
        int arr[] = {7, 10, 11, 9, -8, 2, 27};
        heap_sort(arr, len);
        show(arr, len);
        return 0;
    }
    
    void show(int arr[], int len)
    {
        int i;
        for (i=0; i<len; i++) {
            printf("%4d", arr[i]);
        }
        printf("
    ");
    }
    
    /**
    * 交换两个元素的值
    */
    void swap(int *px, int *py)
    {
        int temp = *px;
        *px = *py;
        *py = temp;
    }
    
    /**
    * arr 数组首地址
    * len 数组长度
    */
    void heap_sort(int *arr, int len)
    {
        int i;
        build_max_heap(arr, len);       // 建立大顶堆
        for (i=len-1; i>0; i--) {       // 排序
            swap(arr, arr+i);           // 将最大的元素放到最后面
            adjust_down(arr, 0, i);     // 使前len-1个元素重新变成大顶堆
        }
    }
    
    /**
    * 建立大顶堆
    */
    void build_max_heap(int *arr, int len)
    {
        int i;
        for (i=len/2-1; i>=0; i--)
            adjust_down(arr, i, len);
    }
    
    /**
    * 将元素k向下进行调整
    */
    void adjust_down(int *arr, int k, int len)
    {
        int i;
        int temp = arr[k];
        for (i=2*k+1; i<len; i=i*2+1) {
            if (i<len-1 && arr[i]<arr[i+1])
                i++;                // 选取较大的子结点
            if (temp>=arr[i]) break;
            else {
                arr[k] = arr[i];    // 将arr[i]上调
                k = i;
            }
        }//for
        arr[k] = temp;
    }
    
  • 相关阅读:
    比较全的屏幕信息
    使用div实现progress进度条
    选项卡效果的菜单栏
    javascript写的轮播图
    centos6.5 命令行配置无线上网
    CentOS 6.5 BCM43142 80211无线网卡驱动安装
    [数据库] windows server 2003下mysql出现10048错误的解决办法 Can't connect to MySQL server on '127.0.0.1' (10048)
    桥接模式-多台虚拟机配置(重要)
    VMware虚拟机中如何配置静态IP
    MySQL5.7 mysql.user创建用户
  • 原文地址:https://www.cnblogs.com/qijinzhi/p/heap_sort.html
Copyright © 2011-2022 走看看