日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

堆排序的时间复杂度分析

發(fā)布時間:2024/4/18 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆排序的时间复杂度分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

堆排序包括兩個階段,初始化建堆和重建堆。所以堆排序的時間復(fù)雜度由這兩方面組成,下面分別進(jìn)行分析。先post一個實現(xiàn)代碼,便于分析。

#include <stdio.h>void swap(int *a, int *b); void adjustHeap(int param1,int j, int inNums[]); void HeapSort(int nums, int inNums[]); //大根堆進(jìn)行調(diào)整 void adjustHeap(int param1, int j, int inNums[]) {int temp=inNums[param1];for (int k=param1*2+1;k<j;k=k*2+1){//如果右邊值大于左邊值,指向右邊if (k+1<j && inNums[k]< inNums[k+1]){k++;}//如果子節(jié)點大于父節(jié)點,將子節(jié)點值賦給父節(jié)點,并以新的子節(jié)點作為父節(jié)點(不用進(jìn)行交換)if (inNums[k]>temp){inNums[param1]=inNums[k];param1=k;}elsebreak;}//put the value in the final positioninNums[param1]=temp; } //堆排序主要算法 void HeapSort(int nums,int inNums[]) {//1.構(gòu)建大頂堆for (int i=nums/2-1;i>=0;i--){//put the value in the final positionadjustHeap(i,nums,inNums);}//2.調(diào)整堆結(jié)構(gòu)+交換堆頂元素與末尾元素for (int j=nums-1;j>0;j--){//堆頂元素和末尾元素進(jìn)行交換int temp=inNums[0];inNums[0]=inNums[j];inNums[j]=temp;adjustHeap(0,j,inNums);//重新對堆進(jìn)行調(diào)整} } int main() {int data[] = {6,5,8,4,7,9,1,3,2};int len = sizeof(data) / sizeof(int);HeapSort(len,data);return 0; }

一.初始化建堆

  初始化建堆只需要對二叉樹的非葉子節(jié)點調(diào)用adjusthead()函數(shù),由下至上,由右至左選取非葉子節(jié)點來調(diào)用adjusthead()函數(shù)。那么倒數(shù)第二層的最右邊的非葉子節(jié)點就是最后一個非葉子結(jié)點。
  假設(shè)高度為k,則從倒數(shù)第二層右邊的節(jié)點開始,這一層的節(jié)點都要執(zhí)行子節(jié)點比較然后交換(如果順序是對的就不用交換);倒數(shù)第三層呢,則會選擇其子節(jié)點進(jìn)行比較和交換,如果沒交換就可以不用再執(zhí)行下去了。如果交換了,那么又要選擇一支子樹進(jìn)行比較和交換;高層也是這樣逐漸遞歸。
  那么總的時間計算為:s = 2^( i - 1 ) * ( k - i );其中 i 表示第幾層,2^( i - 1) 表示該層上有多少個元素,( k - i) 表示子樹上要下調(diào)比較的次數(shù)。
  S = 2^(k-2) * 1 + 2^(k-3)2…..+2(k-2)+2^(0)*(k-1) ===> 因為葉子層不用交換,所以i從 k-1 開始到 1;
  S = 2^k -k -1;又因為k為完全二叉樹的深度,而log(n) =k,把此式帶入;
  得到:S = n - log(n) -1,所以時間復(fù)雜度為:O(n)

二.排序重建堆

  在取出堆頂點放到對應(yīng)位置并把原堆的最后一個節(jié)點填充到堆頂點之后,需要對堆進(jìn)行重建,只需要對堆的頂點調(diào)用adjustheap()函數(shù)。
  每次重建意味著有一個節(jié)點出堆,所以需要將堆的容量減一。adjustheap()函數(shù)的時間復(fù)雜度k=log(n),k為堆的層數(shù)。所以在每次重建時,隨著堆的容量的減小,層數(shù)會下降,函數(shù)時間復(fù)雜度會變化。重建堆一共需要n-1次循環(huán),每次循環(huán)的比較次數(shù)為log(i),則相加為:log2+log3+…+log(n-1)+log(n)≈log(n!)。可以證明log(n!)和nlog(n)是同階函數(shù):
  ∵(n/2)n/2≤n!≤nn,∵(n/2)n/2≤n!≤nn,
  ∴n/4log(n)=n/2log(n1/2)≤n/2log(n/2)≤log(n!)≤nlog(n)∴n/4log?(n)=n/2log?(n1/2)≤n/2log?(n/2)≤log?(n!)≤nlog?(n)
  所以時間復(fù)雜度為O(nlogn)

三.總結(jié)

  初始化建堆的時間復(fù)雜度為O(n),排序重建堆的時間復(fù)雜度為nlog(n),所以總的時間復(fù)雜度為O(n+nlogn)=O(nlogn)。另外堆排序的比較次數(shù)和序列的初始狀態(tài)有關(guān),但只是在序列初始狀態(tài)為堆的情況下比較次數(shù)顯著減少,在序列有序或逆序的情況下比較次數(shù)不會發(fā)生明顯變化。

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的堆排序的时间复杂度分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。