經典演算法學習——堆排序_PHP教程

來源:互聯網
上載者:User

經典演算法學習——堆排序


堆排序是相對其他排序稍微麻煩的排序,是一種利用堆的性質進行的選擇排序。堆其實是一棵完全二叉樹,只要任何一個非分葉節點的關鍵字不大於或者不小於其左右孩子節點,就可以形成堆。堆分為大頂堆和小頂堆。由上述性質可知大頂堆的堆頂的關鍵字是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的。堆排序同快速排序一樣都是不穩定排序。範例程式碼上傳至:https://github.com/chenyufeng1991/HeapSort

堆排序的思想:利用大頂堆(小頂堆) 堆頂記錄的是最大關鍵字(最小關鍵字)這一特性,使得每次從無序中選擇最大記錄(最小記錄)變得簡單。注意:大頂堆構造的是遞增序列,小頂堆構造的是遞減序列。

(1)將初始待排序關鍵字序列(R0,R1....Rn-1),構建成大頂堆,此堆為初始的無序區;

(2)將堆頂元素R[0]與最後一個元素R[n-1]交換,此時得到新的無序區(R0,R1....Rn-2)和新的有序區(Rn-1),且滿足R[0,1...n-2]<=R[n-1];

(3)由於交換後新的堆頂R[0]可能違反堆的性質,因此需要對當前無序區(R0,R1...Rn-2)調整為新堆,然後再次將R[0]與無序區最後一個元素交換,得到新的無序區(R0,R1...Rn-3)和新的有序區(Rn-2,Rn-1).不斷重複此過程知道有序區的元素個數為n-1,則整個排序過程完成。

操作過程如下:

(1)初始化堆:將[0...n-1]構造為堆;

(2)將當前無序區的堆頂元素R[0]同該區間的最後一個記錄交換,然後將新的無序區調整為新的堆;

因此對於堆排序,最重要的兩個操作就是構造初始堆和調整堆,其實構造初始堆也是調整堆的過程,只不過構造初始堆是對所有的非分葉節點都進行調整。

執行個體代碼如下:

////  main.c//  Train////  Created by chenyufeng on 16/1/30.//  Copyright © 2016年 chenyufengweb. All rights reserved.//#include void BuildHeap(int *a,int size);void swap(int *a,int *b);void HeapSort(int *a,int size);void HeapAdjust(int *a,int i,int size);int main(int argc,const char *argv[]){    int a[] = {3,25,9,30,2};    HeapSort(a, 5);    for (int i = 0; i < 5; i++) {        printf("%d ",a[i]);    }    return 0;}//建立堆void BuildHeap(int *a,int size){    for (int i = size - 1; i >= 0; i--) {        HeapAdjust(a, i, size);    }}//交換兩個數void swap(int *a,int *b){    int temp;    temp = *a;    *a = *b;    *b = temp;}//堆排序void HeapSort(int *a,int size){    BuildHeap(a, size);    for (int i = size - 1; i >= 0; i--) {        //交換堆頂和最後一個元素,即每次將剩餘元素中的最大者放到後面;        swap(&a[0], &a[i+1]);        //重新調整堆為大頂堆;        HeapAdjust(a, 0, i );    }}//調整堆void HeapAdjust(int *a,int i,int size){    int lchild = 2 * i;//左孩子節點;    int rchild = 2 * i + 1;//右孩子節點;    int max = i;    if (i <= size) {        if (lchild <= size && a[lchild] > a[max]) {            max = lchild;        }        if (rchild <= size && a[rchild] > a[max]) {            max = rchild;        }        if (i != max) {            swap(&a[i], &a[max]);            //避免調整之後以max為父節點的子樹不是堆;            HeapAdjust(a, max, size);        }    }}

http://www.bkjia.com/PHPjc/1121830.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1121830.htmlTechArticle經典演算法學習——堆排序 堆排序是相對其他排序稍微麻煩的排序,是一種利用堆的性質進行的選擇排序。堆其實是一棵完全二叉樹,只要任...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.