堆排序的實現

堆排序是利用了一種數據結構叫做二叉堆,二叉堆是這樣定義的:

二叉堆是一種特殊的堆,二叉堆是完全二元樹或者是近似完全二元樹,有最小堆和最大堆

特點:

1.父結點的鍵值總是大於或等於(小於或等於)任何一個子節點的鍵值。

2.每個結點的左子樹和右子樹都是一個二叉堆(都是最大堆或最小堆)。

利用堆排序數據的存儲方式如下:


以下是我的代碼實現:

/***************the min_heap_sort.c made by cfmlovers**************/
#include <stdio.h>
#define ARRAYSIZE 4
void swap(int *m, int *n)
{
    int temp = *m;
    *m = *n;
    *n = temp;
}
void min_heap_shift(int a[], int i, int n)
{
    int temp = i;
    int l = 2*i+1,  r = 2*i+2;
    if(l < n && a[l] < a[temp])
        temp = l;
    if(r < n && a[r] < a[temp])
        temp = r;

    if(temp == i)
        return ;
    else
       swap(&a[temp], &a[i]);
       min_heap_shift(a, temp, n);
}
void min_heapsize(int a[], int n)
{
    int i;
    for(i = n/2-1; i >= 0; i--)//n/2-1個非葉子節點
        min_heap_shift(a, i, n);
}

void min_heap_sort(int a[], int n)
{
    int i;
    for(i = n; i > 1; i--)//只需要n-1趟即可
    {
        swap(&a[i-1], &a[0]);
        min_heap_shift(a, 0, i-1);
    }
}

void main()
{
    int a[ARRAYSIZE], i;
    printf("please input 4 numbers:\n");
    for(i = 0; i < ARRAYSIZE; i++)
        scanf("%d",&a[i]);

    /*first step: heapsize the array*/
    min_heapsize(a, ARRAYSIZE);
    /*second step:heap sort*/
    min_heap_sort(a, ARRAYSIZE);

    for(i = 0; i < ARRAYSIZE; i++)
        printf("%d\n",a[i]);
}
其中min_heap_shift的非遞歸實現如下:

void min_heap_shift(int a[], int i, int n)
{
    int j = 2*i+1, temp;//非遞歸的實現
    temp = a[i];
    while(j < n)
    {
        if(a[j+1] < a[j] && j+1 < n)
            j = 2*i+2;
        if(temp < a[j])  break;

        a[i] = a[j];
        i = j;
        j = 2*i+1;
    }
    a[i] = temp;
}


如果在面試中需要我們去寫堆排序,就記住兩點三函數:

1.堆化一個數組  min_heapsize

2.堆排序 min_heap_sort

其中每次發生交換數據的時候我們讀需要保持堆的特性,即min_heap_shift 函數


自己曾經寫過的錯的地方:

1.while(j < n)寫成了while(j +1 < n),這個以爲左右孩子必須都小於n,其實錯了,右孩子可以沒有
2.把最後的a[i] = temp寫成了a[j] = temp;
這個地方用a[i]有以下幾層含義:
當j> n時,就是第一次沒有交換的時候,a[i] == temp;
當發生了交換,a[i] = a[j]; i = j;此時a[j]的值被賦予了a[i],而j = 2*i+1; 我們賦予a[j] = temp是錯的,賦予a[i] = temp纔是對的


另外堆排序和快速排序,歸併排序的複雜度一樣都是O(N*logN),具體怎麼來的,可以去看《算法導論》



發佈了39 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章