內部排序之堆排序

來源:互聯網
上載者:User

      堆排序(Heap Sort)只需要一個記錄大小的輔助空間,每個待排序的記錄僅佔有一個儲存空間。

   (1)基本概念
    a)堆:設有n個元素的序列:
          {k1, k2, ..., kn}

       對所有的i=1,2,...,(int)(n/2),當滿足下面關係:
                                                                  ki≤k2i,ki≤k2i+1

                                                  或            ki≥k2i,ki≥k2i+1

        這樣的序列稱為堆。
        堆的兩種類型:
                 根結點最小的堆----小根堆。
                 根結點最大的堆----大根堆。
        根結點稱為堆頂,即:在一棵完全二叉樹中,所有非葉結點的值均小於(或均大於)左、右孩子的值。
        b)堆排序:是一種樹型選擇排序,特點是,在排序過程中,把R[1..n]看成是一個完全二叉樹的儲存結構,利用完全二叉樹雙親結點和孩子結點的內在關係,在當前無序區中選擇關鍵字最大(最小)的記錄。
    (2)堆排序步驟:
     1、從k-1層的最右非葉結點開始,使關鍵字值大(或小)的記錄逐步向二叉樹的上層移動,最大(或小)關鍵字記錄成為樹的根結點,使其成為堆。
     2、逐步輸出根結點,令r[1]=r[i](i=n,,n-1,...,2),在將剩餘結點調整成堆。直到輸出所有結點。我們稱這個自堆頂到葉子的調整過程為“篩選”。
    (3)要解決的兩個問題:
      1、如何由一個無序序列建成一個堆;
      2、輸出一個根結點後,如何將剩餘元素調整成一個堆。
      將一個無序序列建成一個堆是一個反覆“篩選”的過程。若將此序列看成是一個完全二叉樹,則最後一個非終端結點是第floor(n/2)個元素,由此“篩選”只需從第floor(n/2)個元素開始。
      堆排序中需一個記錄大小的輔助空間,每個待排的記錄僅佔有一個儲存空間。堆排序方法當記錄較少時,不值得提倡。當n很大時,效率很高。堆排序是不穩定的。
      堆排序的演算法和篩選的演算法如第二節所示。為使排序結果是非遞減有序排列,我們在排序演算法中先建一個“大頂堆”,即先選得一個關鍵字為最大的記錄並與序列中最後一個記錄交換,然後對序列中前n-1個記錄進行篩選,重新將它調整為一個“大頂堆”,然後將選得的一個關鍵字為最大的記錄(也就是第一個元素)與當前最後一個記錄交換(全域看是第n-1個),如此往複,直到排序結束。由到,篩選應按關鍵字較大的孩子結點向下進行。

      堆排序的演算法描述如下:

     

 

     用C語言代碼實現如下:

#include "iostream"using namespace std;#define MAXSIZE 20typedef struct{int key;//其他資料資訊}RedType;typedef struct{RedType r[MAXSIZE+1];int length;}Sqlist;typedef Sqlist HeapType;  //堆採用順序表格儲存體表示void HeapAdjust(HeapType &H,int s,int m)   //已知H.r[s...m]中記錄的關鍵字出H.r[s].key之外均滿足堆的定義,本函數調整H.r[s]的關鍵字,使H.r[s...m]成為一個大頂堆(對其中記錄的關鍵字而言){int j;RedType rc;rc=H.r[s];for(j=2*s;j<=m;j*=2)   //沿key較大的孩子結點向下篩選{if(j<m && (H.r[j].key<H.r[j+1].key))     //j為key較大的記錄的下標++j;if(rc.key>=H.r[j].key)           //rc應插入在位置s上break;H.r[s]=H.r[j];      //將左、右孩子較大的結點與父節點進行交換,建成大頂堆s=j;}H.r[s]=rc;             //插入}void HeapSort(HeapType &H)      //對順序表H進行堆排序{int i;for(i=H.length/2;i>0;--i)   //由一個無序序列建成一個大頂堆,將序列看成是一個完全二叉樹,則最後一個非終端節點是第n/2個元素HeapAdjust(H,i,H.length);for(i=H.length;i>1;--i){H.r[0]=H.r[1];   //將堆頂記錄和當前未經排序的子序列H.r[1...i]中最後一個記錄相互交換H.r[1]=H.r[i];H.r[i]=H.r[0];HeapAdjust(H,1,i-1);    //將H.r[1...i-1]重新調整為大頂堆}}//HeapSortvoid InputL(Sqlist &L){int i;printf("Please input the length:");scanf("%d",&L.length);printf("Please input the data needed to sort:\n");for(i=1;i<=L.length;i++)    //從數組的第1個下標開始儲存,第0個下標作為一個用於交換的臨時變數scanf("%d",&L.r[i].key);}void OutputL(Sqlist &L){int i;printf("The data after sorting is:\n");for(i=1;i<=L.length;i++)printf("%d ",L.r[i].key);printf("\n");}int main(void){Sqlist H;InputL(H);HeapSort(H);OutputL(H);system("pause");return 0;}

        不使用上面的結構體的另外一種方法如下:

/**堆排序*/#include "iostream"using namespace std;#define N 10int array[N];void man_input(int *array){int i;for(i=1;i<=N;i++){printf("array[%d]=",i);scanf("%d",&array[i]);}}void mySwap(int *a,int *b)//交換{int temp;temp=*a;*a=*b;*b=temp;}void heap_adjust(int *heap,int root,int len)     //對堆進行調整,使下標從root到len的無序序列成為一個大頂堆{int i=2*root;int t=heap[root];while(i<=len){if(i<len){if(heap[i]<heap[i+1])i++;}if(t>=heap[i])break;heap[i/2]=heap[i];i=2*i;}heap[i/2]=t;}void heapSort(int *heap,int len)      //堆排序{int i;for(i=len/2;i>0;i--)    //由一個無序序列建成一個大頂堆,將序列看成是一個完全二叉樹,則最後一個非終端節點是第len/2個元素{heap_adjust(heap,i,len);}for(i=len;i>=1;i--){mySwap(heap+i,heap+1);    //將堆頂記錄與最後一個記錄相互交換heap_adjust(heap,1,i-1);   //將下標為1~i-1的記錄重新調整為大頂堆}}void print_array(int *array,int n){int k;for(k=1;k<n+1;k++){printf("%d\t",array[k]);}}int main(void){man_input(array);heapSort(array,N);printf("\nAfter sorted by the heap_sort algorithm:\n");        print_array(array,N);   //列印堆排序結果system("pause");return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.