zoukankan      html  css  js  c++  java
  • 堆排序(C语言实现)

    一、堆的概念

             所谓堆,它是一个数组,也能够被看成一个近似的全然二叉树。树上每一个结点相应数组的一个元素。二叉堆分为二种:最大堆和最小堆。本文主要介绍最大堆,最小堆类似。最大堆的特点:对于随意某个结点,该结点的值大于左孩子、右孩子的值,可是左右孩子的值没有要求。

    二、堆排序算法

         首先,按堆的定义将数组R[0..n]调整为堆(这个过程称为创建初始堆),交换R[0]R[n]

    然后,将R[0..n-1]调整为堆,交换R[0]R[n-1]

    如此反复,直到交换了R[0]R[1]为止。

    以上思想可归纳为两个操作:

    1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。

    这里可以利用完全二叉树的结构,从最后一个非终端节点开始对子元素进行排序筛选。

    2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。

    当输出完最后一个元素后,这个数组已经是按照从小到大的顺序排列了。

      具体图片我就不找了,网上很多。

    三、算法比较

    堆排序算法的时间复杂度是O(nlgn),比插入排序要好,跟归并排序相同,但是与归并排序不一样的地方在于,堆排序不需要额外的存储空间,或者说,只需要常数个额外的存储空间,属于内排序算法。

    #include <stdio.h>
    #define N 1000
    #define INF 999999999
    int h[N];
    //调整堆(迭代法)
    //n:规模 i:二叉子堆的堆顶
    void
    heapAdjust(int n, int par)
    {
        int tmp, pos, lc, rc;
    
        while (par <= n/2) {
            tmp = h[par]; //记录父母结点键值
            lc = par<<1;
            rc = lc+1;
            pos = par;
            //父母结点至多更新2次
            if (h[par] < h[lc]) {
                h[par] = h[lc];
                pos = lc;
            }
            if (rc <= n && h[par] < h[rc]) {
                h[par] = h[rc];
                pos = rc;
            }
            if (pos == par) //无更新即无需调整
                break;
            else
                h[pos] = tmp;
            par = pos; //假设这个位置的结点是“父母结点”
        }
    }
    
    //创建堆
    //规模为n的堆,对其父母结点,自底向上自右向左地调整堆
    void
    createHeap(int n)
    {
        int i;
    
        for (i = n/2; i != 0; i--) {
            heapAdjust(n, i);
        }
    }
    
    void
    heapSort(int n)
    {
        int ntimes = n;
    
        while (ntimes--) {
            printf("%d
    ", h[1]);
            h[1] = h[n];
            h[n--] = 0; //堆清零
            heapAdjust(n, 1);
        }
    }
    
    int
    main(void)
    {    
        int n, i;
        
        scanf("%d", &n);
        h[0] = INF;
        for (i = 1; i != n+1; i++) {
            scanf("%d", &h[i]);
        }
        createHeap(n);
        heapSort(n);
        return 0;
    }
    
    /*
      参考测试数据
    6
    342 31 52 626 12 124
    10
    43 525 14 21 52 3 52 45 319 15155
    */
  • 相关阅读:
    使用axi_datamover完成ZYNQ片内PS与PL间的数据传输
    ZYNQ 的PS GEM DMA存在缺陷
    异构数据源离线同步工具
    58同城2015校招笔试、一面、二面经历
    深圳科陆集团2015校招软件开发笔试题
    华为2015校园招聘研发面试总结(获得offer)
    2015校园招聘360失败的惨痛经历
    数码视讯2015校园招聘JAVA笔试题及答案
    百度2015校园招聘一、二、三面面试经历(软件研发岗)
    2014美团网校园招聘研发类笔试(哈尔滨站)
  • 原文地址:https://www.cnblogs.com/qixinbo/p/7954084.html
Copyright © 2011-2022 走看看