堆排序相對冒泡排序、選擇排序效率很高,再也不是O(n^2).ios
倘若將一個序列升序排序好,那麼咱們來考慮最大堆仍是最小堆來排序。倘若是最小堆的話,堆的頂端一定是堆中的最小值,這樣貌似能夠。可是,若是是它的(一邊或)子樹左子樹的節點數據值大於(一邊或)右子樹的節點數據值,直接打印確定是錯誤的,並且對於此時的堆咱們也沒法操控來調整好正確的順序了。ide
那咱們換成最大堆來實現升序想,當咱們把序列調整成爲最大堆後,最大堆頂端的數據值是最大的,而後咱們將這個最大值與堆的最後一個葉子節點值來進行交換,再將交換後的頂端值進行調整,換到合適的位置處……重複這樣的工做,注意:進行第2次交換就要將頂端元素值與倒數第2個節點元素值交換了,且調整頂端元素位置也不能一直調整到size-1處。(由於:size-1處的值已是最大)spa
代碼以下:排序
#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; #include<assert.h> void AdjustDown(int* a,int parent, int size) { int child = 2 * parent + 1; while (child < size) { if (child + 1 < size && a[child] < a[child + 1]) { ++child; } if (a[child]>a[parent]) { swap(a[child], a[parent]); parent = child; child = 2 * parent + 1; } else { break; } } } void Print(int*a, int size) { cout << "升序序列爲:"<<endl; for (int i = 0; i < size; i++) { cout << a[i] << " "; } cout << endl; } void HeapSort(int* a,int size) { assert(a); //建成最大堆 for (int i = (size - 2) / 2; i >=0; i--) { AdjustDown(a,i, size); } //交換順序 for (int i = 0; i < size; i++) { swap(a[0], a[size - i - 1]); AdjustDown(a, 0, size-i-1); } } void Test() { int arr[] = { 12, 2, 10, 4, 6, 8, 54, 67,100,34,678, 25, 178 }; int size = sizeof(arr) / sizeof(arr[0]); HeapSort(arr, size); Print(arr,size); } int main() { Test(); system("pause"); return 0; }
時間複雜度:it
(n-2)/2*lgn+n*(1+lgn)--->O(n).
io