堆排序相對穩定,最優和最差複雜度都是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; }