為什麼建堆的時間複雜度是O n ?

2021-09-14 04:44:32 字數 1304 閱讀 6292

原文: 

先看下堆排序與快速排序的實現**:

#includeusing namespace std;

const int maxn=111;

int a[maxn];

void quicksort(int a,int l,int r)

else

break;

}} void buildheap(int num,int len)}

void heapsort(int num,int len)}

int main()

{ int n,i;

scanf("%d",&n);

//for(i=1;i<=n;i++)

//scanf("%d",&a[i]);

//quicksort(a,1,n);

for(i=0;i如果僅從**上直觀觀察,會得出構造二叉堆的時間複雜度為o(n㏒n)的結果,這個結果是錯的,雖然該演算法外層套乙個n次迴圈,而內層套乙個分治策略下的㏒n複雜度的迴圈,該思考方法犯了乙個原則性錯誤,那就是構建二叉堆是自下而上的構建,每一層的最大縱深總是小於等於樹的深度的,因此,該問題是疊加問題,而非遞迴問題。那麼換個方式,假如我們自上而下建立二叉堆,那麼插入每個節點都和樹的深度有關,並且都是不斷的把樹折半來實現插入,因此是典型的遞迴,而非疊加。

在做證明之前,我們的前提是,建立堆的順序是bottom-top的。 

正確的證明方法應當如下:

具有n個元素的平衡二叉樹,樹高為㏒n,我們設這個變數為h。

最下層非葉節點的元素,只需做一次線性運算便可以確定大根,而這一層具有2^(h-1)個元素,我們假定o(1)=1,那麼這一層元素所需時間為2^(h-1) × 1。

由於是bottom-top建立堆,因此在調整上層元素的時候,並不需要同下層所有元素做比較,只需要同其中之一分支作比較,而作比較次數則是樹的高度減去當前節點的高度。因此,第x層元素的計算量為2^(x) × (h-x)。

又以上通項公式可得知,構造樹高為h的二叉堆的精確時間複雜度為: 

s = 2^(h-1) × 1 + 2^(h-2) × 2 + …… +1 × (h-1) ①

通過觀察第四步得出的公式可知,該求和公式為等差數列和等比數列的乘積,因此用錯位想減發求解,給公式左右兩側同時乘以2,可知: 

2s = 2^h × 1 + 2^(h-1) × 2+ …… +2 × (h-1) ②

用②減去①可知: s =2^h × 1 - h +1 ③

將h = ㏒n 帶入③,得出如下結論:

s = n - ㏒n +1 = o(n)

結論:構造二叉堆的時間複雜度為線性得證。

原文: 

建堆O n 時間複雜度證明

建堆複雜度先考慮滿二叉樹,計算完全二叉樹建堆複雜度基本相同。對滿二叉樹而言,第i層 根為第0層 有2 i個節點。由於建堆過程自底向上,以交換作為主要操作,因此第i層任意節點在最不利情況下,需要經過 n i 次交換操作才能完成以該節點為堆根節點的建堆過程。因此,時間複雜度計算如下 t n 2 0 n ...

建堆的時間複雜度計算

現在常有兩種建堆的方法,而這兩種方法又有著不同的時間複雜度。下面分別陳述 1 自頂向下的建堆方式 這種建堆的方法具有o n log2n 的時間複雜度。從根結點開始,然後乙個乙個的把結點插入堆中。當把乙個新的結點插入堆中時,需要對結點進行調整,以保證插入結點後的堆依然是大根堆。如下圖所示,是採用自頂向...

什麼是時間複雜度

什麼是時間複雜度 作為乙個處在學習之路的渣渣,被乙個時間複雜度的題給難倒了,然後我就思考了一下什麼是時間複雜度。雖然在學校學習了了演算法的課程,但是仔細一想,對於時間複雜度還真是不怎麼懂。於是重新學習,記下自己的一些理解。1.時間複雜度 提到時間複雜度,第一時間想到的是演算法,簡單說,演算法就是你解...