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


    小根堆。

    堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。

    建堆时,从除去叶子节点的n/2开始,调整堆的时间复杂度为O(logN)。

    n-1次把堆顶元素与当前最后一个交换,然后调整堆。

    总时间还是O(N*logN)

    堆排序的最坏时间复杂度为O(N*logN)。堆排序的平均性能较接近于最坏性能。
    由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。
    堆排序是就地排序,辅助空间为O(1),
    它是不稳定的排序方法。

    来源:

    http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu8.4.2.3.htm


    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <climits>
    #include <cstdio>
    
    using namespace std;
    int N, a[100];
    //从i节点开始调整,n为节点总数, 从0开始计算, i节点子节点为2*i+1, 2*i+2
    //小根堆
    void Heapify(int* a, int i, int n) {
        int j = 2*i+1, tmp = a[i];
        while(j < n) { 
            if(j+1<n && a[j+1]<a[j])//找左右孩子中最小的
                ++j; 
            if(a[j] >= tmp)
                break; 
                
            a[i] = a[j];
            i = j; 
            j = 2*i+1;
        }   
        a[i] = tmp;
    }   
    void BuildHeap(int* a, int n) {
        for(int i = n/2-1; i >= 0; --i) {
            Heapify(a, i, n);
        }   
    }   
    void HeapSort(int* a, int n) {
      BuildHeap(a, n);
      for(int i = n-1; i >= 1; --i) {
          swap(a[i], a[0]);
          Heapify(a, 0, i);
      }
    }
    int main()
    {
      int a[100];
      scanf("%d", &N);
      for(int i = 0; i < N; ++i) scanf("%d", a+i);
      HeapSort(a, N);
      for(int i = 0; i < N; ++i) printf("%d ", a[i]); puts("");
      return 0;
    }

    下面是大根堆呢~

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    
    using namespace std;
    int a[100], N;
    void Debug() {
      for(int i = 0; i < N; ++i) printf("%d ", a[i]); puts("");
    }
    void Heapify(int* a, int i, int n) {
      int j = 2*i+1, tmp = a[i];
      while(j < n) {
        if(j+1<n && a[j+1]>a[j]) ++j;
        if(a[j] < tmp) break;
        a[i] = a[j];
        i = j;
        j = 2*i+1;
      }
      a[i] = tmp;
    }
    void BuildHeap(int* a, int n) {
      for(int i = n/2-1; i >= 0; --i) {
        Heapify(a, i, n); 
        //printf("i=%d:", i);
        //Debug();
      }
    }
    void HeapSort(int* a, int n) {
      BuildHeap(a, n);
      for(int i = n-1; i > 0; --i) {
        swap(a[0], a[i]);
        Heapify(a, 0, i);
      }
    }
    int main()
    {
      scanf("%d", &N);
      for(int i = 0; i < N; ++i) scanf("%d", a+i);
      Debug();
      HeapSort(a, N);
      Debug();
      return 0;
    }

  • 相关阅读:
    黑客书架上的书籍(转)
    vc 得到文件后缀名(转)
    配置IIS7(转)
    vs2008 目标框架 发布遇到的问题(转)
    CListCtrl用法(转)
    T400 折腾
    VS2008和.NET Framework3.5新功能(转)
    sql 2008 ctp 安装
    关于定位lsass内存中的明文密码(转)
    NT系统下木马进程的隐藏与检测(转)
  • 原文地址:https://www.cnblogs.com/Accoral/p/3303796.html
Copyright © 2011-2022 走看看