【基礎算法】堆排序

堆排序相對穩定,最優和最差複雜度都是O(nlogn)[一共調整n次堆,每次複雜度爲logn]。相比之下,快速排序在最差狀況即基本逆序時,複雜度無異於冒泡排序O(n*n)[每趟排序複雜度爲n,分治失效故排n次];而冒泡排序在基本有序時,只需掃描一次,複雜度爲O(n)。因此堆排序適用於更關注最差複雜度的狀況。同時,取堆頂操做,能夠下降取無序數組最小K個元素的複雜度爲K*logn。ios

堆排序主要分兩步:調整,即建堆,從當前根起讓每一個父節點不大於子節點,調整必須是自底向上的,最後一個非葉子節點是length/2-1;輸出,即將堆頂元素與數列最後一個元素交換,再不斷調整(數列長度-1)。數組

#include <iostream>
using namespace std;
void HeapAdjust(int arr[], int i, int nLength){//調整i節點爲根的子堆
    int child;
    for (; 2 * i + 1 < nLength; i = child){ //這個循環是有必要的,自上向下調整該子樹
        if (i <= nLength / 2 - 1){            
            child = 2 * i + 1;
            if (child + 1 < nLength&&arr[child] > arr[child + 1]){
                child++;      //只和較大的交換,即只破壞了較小子樹的平衡,這樣纔有log n的複雜度
            }
            if (arr[child] < arr[i]){ 
                int temp = arr[i];
                arr[i] = arr[child];
                arr[child] = temp;
            }
            else
                break;
        }
    }
}
/*
int HeapTop(int arr[], int *nLength){ //堆必須從下往上調整
    int l = *nLength, temp;
    for (int i = l / 2 - 1; i >= 0; i--){ 
        HeapAdjust(arr, i, l);
    }
    temp = arr[0];
    arr[0] = arr[l - 1];
    arr[l-1] = temp;
    l--;
    *nLength = l;
    return arr[l];
}
void HeapSort(int arr[],int length, int b[]){ //利用HeapTop排序
    int l = length;
    for (int i = 0; i < length; i++){
        b[i] = HeapTop(arr, &l);
    }
}
*/
void HeapSort(int array[], int length) //直接排序?能夠這樣嗎,能夠
{
    int i;    
    for (i = length / 2 - 1; i >= 0; --i)
        HeapAdjust(array, i, length);    //堆頂最小
    for (i = length - 1; i>0; --i) //把堆頂和堆底交換,其實是逆調整順序輸出,依舊自底向上
    {
        int temp;
        temp = array[i];
        array[i] = array[0];
        array[0] = temp;
        HeapAdjust(array, 0, i); //從頂開始調整,HeapAdjust()中循環的意義
    }
    for (int i = 0; i < length / 2;i++){ //若是HeapAdjust()改成大在上,則無需此循環
        int temp;
        temp = array[i];
        array[i] = array[length - 1 - i];
        array[length - 1 - i] = temp;
    }
}

int main(){
    int arr[] = {49,31,22,76,32,45,61,21,13,58,49 };
    int length = sizeof(arr) / sizeof(int);
    int b[100];
    HeapSort(arr, length, b);
    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
        cout << b[i] << " ";
    cout << endl;
    HeapSort(arr, length);
    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
        cout << arr[i] << " ";
    return 0;
}
相關文章
相關標籤/搜索