1. 程式人生 > >排序演算法之堆排序及其C語言程式碼實現

排序演算法之堆排序及其C語言程式碼實現

概述:堆排,實際上是一種選擇排序,只不過採用了堆這種資料結構,利用這種資料結構,使得在每次查詢最大元素時,直接選取堆頂元素,從而時間大大縮短,相對簡單選擇排序演算法來說,比較高效。
堆排序演算法可描述如下:
1.將待排元素依次存入陣列,該陣列即為一顆完全二叉樹;
2.從最後一個非葉節點開始遞減,逐次將每個相應的二叉樹調整成最大堆,最後,整個二叉樹即為最大堆;
3.交換堆頂元素與堆尾元素,調整新的堆為最大堆,陣列分為兩部分:堆與已排序列,直至最後一個堆元素。
從上面可以看出,堆排序大致可以分為三個步驟:
1.存入資料(完全二叉樹)
2.將前n個元素調整為最大堆
3.交換堆頂和堆尾元素,n=n-1,轉2
注:本文元素從陣列下標1開始儲存,所以parent訪問二叉樹左右兒子分別為2*parent 和 2*parent+1;


兩個核心函式

void HeapAdjust(int H[],int start,int end)//堆調整,將start和end之間的元素調整為最大堆
void HeapSort(int H[],int L,int R)//堆排序

核心程式碼實現:

void HeapAdjust(int H[],int start,int end)//堆調整,將start和end之間的元素調整為最大堆
{
    int temp=H[start];
    int parent=start,child;
    while(2*parent<=end)
    {
        child=2
*parent; if(child!=end&&H[child]<H[child+1])++child; if(temp>H[child])break; else H[parent]=H[child]; parent=child; } H[parent]=temp; } void HeapSort(int H[],int L,int R) { for(int i=(R-L+1)/2;i>=L;--i)//調整整個二叉樹為最大堆 HeapAdjust(H,i,R); for
(int i=R;i>=L;--i) { swap(&H[L],&H[i]); HeapAdjust(H,L,i-1); } }

測試樣例:

#include <stdio.h>
#define NA -1
void swap(int *a,int *b)//該函式用於交換兩個變數的值
{
    int temp=*a;
    *a=*b;
    *b=temp;
}
void HeapAdjust(int H[],int start,int end)//堆調整,將start和end之間的元素調整為最大堆
{
    int temp=H[start];
    int parent=start,child;
    while(2*parent<=end)
    {
        child=2*parent;
        if(child!=end&&H[child]<H[child+1])++child;
        if(temp>H[child])break;
        else H[parent]=H[child];
        parent=child;
    }
    H[parent]=temp;
}
void HeapSort(int H[],int L,int R)
{
    for(int i=(R-L+1)/2;i>=L;--i)//調整整個二叉樹為最大堆
        HeapAdjust(H,i,R);
    for(int i=R;i>=L;--i)
    {
        swap(&H[L],&H[i]);
        HeapAdjust(H,L,i-1);
    }
}

int main(){
    int A[]={NA,1,3,63,5,78,9,12,52,8};//1開始存入資料
    printf("Previous Arrary:");
    for(int i=1;i<=9;++i)
        printf(" %d",A[i]);
    HeapSort(A,1,9);
    printf("\nSorted Arrary:");
    for(int i=1;i<=9;++i)
        printf(" %d",A[i]);
    printf("\n");
    return 0;
}

執行結果:

Previous Arrary: 1 3 63 5 78 9 12 52 8
Sorted Arrary: 1 3 5 8 9 12 52 63 78
請按任意鍵繼續. . .

另:推薦一篇比較詳細的文章,讀者可以參看堆排序 Heap Sort