建堆復雜度O(n)證明
阿新 • • 發佈:2018-02-01
nlogn 需要 它的 小根堆 () 簡單的 這不 調用 inline 比較次數最多為
...
= \({1*2^1+2*2^2+3*2^3}+\cdots + {k*2^k}\)
=
堆排序中首先需要做的就是建堆,廣為人知的是建堆復雜度才O(n),不過很少有人去了解過這個復雜度的證明過程,因為不是那麽直觀地可以一眼就看出來。本文不講堆排序,只單純講建堆過程。
建堆代碼
欲了解復雜度的計算過程,必先看懂建堆代碼。先看這個建堆過程
// 將arr[n]向上調整至合適位置 void AdjustHeap(vector<int> &arr, int n) { if(n<=0) return ; if(arr[(n-1)/2] > arr[n]) { //與父結點比較 swap(arr[(n-1)/2], arr[n]); AdjustHeap(arr, (n-1)/2); //遞歸調整 } } // 小根堆 void BuildHeap(vector<int> &arr) { for(int i=1; i<arr.size(); i++) { AdjustHeap(arr, i); } }
因為不講堆排序,所以這裏用的是向上調整即可,更加直觀易懂。相信這麽簡單的代碼你應該能看懂它的原理。
復雜度計算
從直觀上看,AdjustHeap()
的調用深度最多為logn層,故復雜度上限為O(logn)。而BuildHead()
中的循環為n-1
次,故它的復雜度為O(nlogn),但這不是它的實際平均復雜度,而是一個估算的上界,它很可能永遠達不到這個上界。下面來分析一下。
AdjustHeap(arr, 1)
比較次數最多為1
次,最少為1次。
AdjustHeap(arr, 2)
比較次數最多為1
次,最少為1次。
AdjustHeap(arr, 3)
比較次數最多為2
次,最少為1次。
AdjustHeap(arr, 4)
2
次,最少為1次。AdjustHeap(arr, 5)
比較次數最多為2
次,最少為1次。AdjustHeap(arr, 6)
比較次數最多為2
次,最少為1次。AdjustHeap(arr, 7)
比較次數最多為3
次,最少為1次。...
AdjustHeap(arr, n-1)
比較次數最多為logn
次,最少為1次。
按最壞情況來算,將這些比較次數累加起來就是建堆的時間復雜度,顯然最佳情況是O(n)。而最壞情況的比較次數復雜一些,為了方便計算,假設n是2的k次冪,則k = logn
。
\({1 + 1 + 2 + 2 + 2 + 2 + 3 + 3 + ... + k}\)
= \({1*2^1+2*2^2+3*2^3}+\cdots + {k*2^k}\)
=
建堆復雜度O(n)證明