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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

堆排序时间复杂度的计算过程

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆排序时间复杂度的计算过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、代碼實現

關于具體實現過程請點 https://blog.csdn.net/weixin_44324174/article/details/104183349
本片文章只講堆排序時間復雜度的計算過程。

package com.westmo1.demo2; import java.util.Arrays; import java.util.Scanner; public class MyDemo3 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("輸入數據");int[] ints = new int[7];for (int i = 0; i < ints.length; i++) {int i1 = scanner.nextInt();ints[i]=i1;}int length=ints.length-1;int root=ints.length/2-1;for (int i = root; i >=0; i--) {BuildHeap(ints, length, i);}//取值,把根結點元素和最后一個元素交換for (int i = 0; i <ints.length; i++) {swap(ints,0,length);length--;BuildHeap(ints,length,0);}System.out.println(Arrays.toString(ints));}//建立大根堆public static void BuildHeap(int arr[],int length,int root){int leftcode=root*2+1;int rightcode=root*2+2;int max=root;if(leftcode<length&&arr[leftcode]>=arr[max]){max=leftcode;}if(rightcode<length&&arr[rightcode]>=arr[max]){max=rightcode;}if (max!=root) {swap(arr,max,root);//調整完之后,可能會影響到下面的子樹,需再次調整BuildHeap(arr,length,max);}}private static void swap(int[] arr, int i, int j) {int t=arr[i];arr[i]=arr[j];arr[j]=t;} }

二、時間復雜度的計算

注意:這里計算都是以完滿二叉樹進行計算的。

1、建堆

建堆的過程都是從倒數第二層最右邊的節點開始,每個節點調整位置花費的時間復雜度是O(1),為了方便后面的計算,統計就說是執行1次;然后是倒數第三層,這一層每個節點也需要執行1次,但是因為調整后會影響到它的后面的節點,所以每個節點還需執行1次(這個次數取決于你的代碼怎么寫,非常關鍵),這里非常關鍵。

int max=root; if(leftcode<length&&arr[leftcode]>=arr[max]){max=leftcode; }if(rightcode<length&&arr[rightcode]>=arr[max]){max=rightcode; } if (max!=root) {swap(arr,max,root)//調整完之后,可能會影響到下面的子樹,需再次調整BuildHeap(arr,length,max); }

上面的代碼是調整節點位置的過程,我們發現,這種代碼調整之后的結果是:**父節點最后只和它的左孩子節點或右孩子節點的其中一個發生了交換,**所以倒數第三層每個節點的在調整位置的時候,每個節點只會影響到它的右子樹或者左子樹的結構中的一個,所以執行1次。如果這里的代碼采用的是父節點先和左孩子結點比較交換然后再和右孩子節點比較交換的寫法,那它最后時間復雜度計算出來的結果就是nlogn;我們是以最優的算法來計算的。
我們以三層結構的完滿二叉樹舉例來推導一下計算公式

所以最后推導出來的公式就是:

S=[2^(k-1)+2^(k-1)*0]+[2^(k-2)+2^(k-2)*1]+[2^(k-3)+2^(k-3)*2]+......+[2^0+2^0*(k-1)] 化簡后得:S=2^(k-1)*1+2^(k-2)*2+2^(k-3)*3+.......+2^0*k;S=2^0*k+2^1*(k-1)+......+2^(k-2)*2+2^(k-1)*1; (1) 使用等比數列求和中的錯位相減法,兩邊同乘以2,得:2S=2^1*k+2^2*(k-1)+......+2^(k-1)*2+2^k*1; (2) (2)-(1)式可得:S=-2^0*k+2^1+2^2+2^3+.......+2^(k-1)+2^k; 使用等比數列求和公式可得:S=2^(k+1)-k-2;

所以建堆的總執行次數就是:S=2^(k+1)-k-2
完滿二叉樹的節點個數是2的整次冪減1,所以2^k-1=節點個數n,所以高度k=log(n+1);
把k帶入S中可得:S=2^(log(n+1)+1)-log(n+1)-2,化簡得S=2n-log(n+1);
所以建堆的時間復雜度為O(n);

2、取值后重新調整堆

取值每次取的都是堆頂元素,取完重新調整的次數都是k次,時間復雜度就是也就是logn,而循環要執行n次,所以取值后重新調整堆得時間復雜度就是O(nlogn);

綜上所述,堆排序的時間復雜度就是O(n(logn+1))就是O(nlogn);

完全都是個人理解,網上搜了好多,自己都沒看的太懂,后來自己摸索著搞了搞,哪里有問題還請指正。

總結

以上是生活随笔為你收集整理的堆排序时间复杂度的计算过程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。