免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
關(guān)于堆排序、歸并排序、快速排序的比較

時間復(fù)雜度:


            堆排序      歸并排序        快速排序
最壞時間   O(nlogn)     O(nlogn)        O(n^2)
最好時間   O(nlogn)     O(nlogn)        O(nlogn)
平均時間   O(nlogn)     O(nlogn)        O(nlogn)

輔助空間     O(1)         O(n)        O(logn)~O(n)

從時間復(fù)雜度看堆排序最好


有人說代碼實現(xiàn)后,數(shù)據(jù)量足夠大的時候,快速排序的時間確實是比堆排序短


解釋是,對于數(shù)組,快速排序每下一次尋址都是緊挨當(dāng)前地址的,而堆排序的下一次尋址和當(dāng)前地址的距離比較長。


網(wǎng)友解答:


1#


4種非平方級的排序:
希爾排序,堆排序,歸并排序,快速排序

我測試的平均排序時間:數(shù)據(jù)是隨機整數(shù),時間單位是秒
數(shù)據(jù)規(guī)模    快速排序    歸并排序    希爾排序    堆排序
1000萬       0.75           1.22          1.77          3.57
5000萬       3.78           6.29          9.48         26.54  
1億             7.65          13.06        18.79        61.31

堆排序是最差的。
這是算法硬傷,沒辦法的。因為每次取一個最大值和堆底部的數(shù)據(jù)(記為X)交換,重新篩選堆,把堆頂?shù)腦調(diào)整到位,有很大可能是依舊調(diào)整到堆的底部(堆的底部X顯然是比較小的數(shù),才會在底部),然后再次和堆頂最大值交換,再調(diào)整下來。
從上面看出,堆排序做了許多無用功。

至于快速排序為啥比歸并排序快,我說不清楚。


 


2#


算法復(fù)雜度一樣只是說明隨著數(shù)據(jù)量的增加,算法時間代價增長的趨勢相同,并不是執(zhí)行的時間就一樣,這里面有很多常量參數(shù)的差別,即使是同樣的算法,不同的人寫的代碼,不同的應(yīng)用場景下執(zhí)行時間也可能差別很大。

快排的最壞時間雖然復(fù)雜度高,但是在統(tǒng)計意義上,這種數(shù)據(jù)出現(xiàn)的概率極小,而堆排序過程里的交換跟快排過程里的交換雖然都是常量時間,但是常量時間差很多。


 


3#


請問你的快快速排序是怎么寫的,我寫的快速排序,當(dāng)測試數(shù)組大于5000的時候就棧溢出了。
其他的幾個排序都對著,不過他們呢沒有用棧。
這是快速排序的代碼,win7 32位,vs2010.



 1 int FindPos(double *p,int low,int high) 2 { 3     double val = p[low]; 4     while (low<high) 5     { 6         while(low<high&&p[high]>=val) 7             high--; 8         p[low]=p[high]; 9         while(low<high&&p[low]<val)10             low++;11         p[high]=p[low];12     }13     p[low]=val;14     return low;15 }16 void QuickSort(double *a,int low,int high)17 {18     if (!a||high<low)19         return;20 21     if (low<high)22     {23         int pos=FindPos(a,low,high);24         QuickSort(a,low,pos-1);25         QuickSort(a,pos+1,high);26     }27 }



……


7#


誰說的快排好?。课乙话愣加枚训?,我認(rèn)為堆好。

這個哪有譜啊,考察使用環(huán)境啊。不是只有時間代價一種衡量標(biāo)準(zhǔn)的,還有空間代價,LZ也有過棧溢出的經(jīng)歷,那不就是空間代價過高了嘛。改成別的辦法還是避免不了空間代價。LZ自己不是也已經(jīng)把空間待見列出來了嘛。


 


……


11#


我自己按照堆排序的算法思想實現(xiàn)了堆排序,寫完后對照網(wǎng)上的代碼,代碼幾乎是差不多的。
至于為何堆排序效率比希爾排序慢很多,我在上面帖子已經(jīng)說了,是堆排序的算法缺陷造成無用功太多。(我把堆排序看成是高級排序中的冒泡排序,冒泡也是兩兩交換做了太多無用功所以最慢。)
貼下我實現(xiàn)的希爾排序和堆排序,你可以自己去運行比較。



 1 template <typename T> 2 void ShellSort(T arr[], int n)          //希爾排序就是增量逐步縮小的直接插入排序 3 {                                       //這里采用黃金分割的比例逐次減小增量 4     int gap = n * 0.382 + 0.5;          //所以代碼和直接插入排序非常像。區(qū)別就是把增量1換成gap 5     int i, j; 6     T temp; 7     while (gap > 0) 8     { 9         for (i = gap; i < n; i++)10         {11             temp = arr[i];12             for (j = i - gap; j >= 0; j -= gap)13             {14                 if (temp < arr[j])15                     arr[j + gap] = arr[j];16                 else17                     break;18             }19             arr[j + gap] = temp;20         }21         gap = gap * 0.382 + 0.5;22     }23 }



 



 1 template <typename T> 2 void HeapSort(T arr[], int n) 3 { 4     for (int i = n / 2 - 1; i >= 0; i--)    //建立最大堆,從最后一個非葉節(jié)點開始 5         MaxHeapify(arr, n, i);              //對于N規(guī)模的堆(0,n-1), n/2-1是最后一個非葉節(jié)點 6  7     T temp; 8     for (int i = n - 1; i > 0; i--)    9     {10         temp = arr[i];               //每次取堆頂數(shù)據(jù)和堆底部數(shù)據(jù)交換11         arr[i] = arr[0];             //并逐步縮小堆的大小12         arr[0] = temp;13         MaxHeapify(arr, i, 0);       //重新篩選堆14     }15 }16 17 18 template <typename T>19 void MaxHeapify(T arr[], int n, int i)20 {21     T temp, max_data;22     int pos = i;23     int left = pos * 2 + 1;24     int right = left + 1;25     int max_pos;26     temp = arr[pos];27 28     while (left < n)     //至少有左子樹29     {30         //取左右子樹的最大值31         max_data = arr[left];32         max_pos = left;33         if (right < n)   //左右子樹均有34             if (arr[right] > arr[left])35             {36                 max_data = arr[right];37                 max_pos = right;38             }39 40         if (temp < max_data)         //節(jié)點比左右子樹最大值小,繼續(xù)向下調(diào)整41         {42             arr[pos] = max_data;43             pos = max_pos;44             left = pos * 2 + 1;45             right = left + 1;46         }47         else48             break;49     }50     arr[pos] = temp;   //回填51 }


 


12#


Mark一下, 有時間好好做一些實驗,給出具體結(jié)果。

這里先說說的我的看法,希望實驗?zāi)苤С治业念A(yù)測。
我認(rèn)為,
1. 快排的時間復(fù)雜度是不穩(wěn)定的,在最快情況下比歸并排序慢的多。
2. 當(dāng)數(shù)據(jù)量大時,充分優(yōu)化的歸并排序可比快速排序更快。其原因有
  1). 歸并排序?qū)?nèi)存的訪問是嚴(yán)格的順序方式(3個2個源數(shù)組,1個目標(biāo)數(shù)組,都是順序放分),故cache的命中率比快排更高,從這點上,相同的內(nèi)存讀寫操作,歸并優(yōu)于快排,當(dāng)數(shù)組占用的空間大大超過cache的大小,則這一優(yōu)勢將更加明顯。
  2)普通寫法的歸并排序有2個缺點,如果改進(jìn),則可以提速。如果你的實驗是基于最普通的版本,得到的結(jié)果是快排優(yōu)于歸并,而優(yōu)化的歸并排序的版本,其性能則可能反超快排。
  2.1) 歸并排序不是In place.需要將結(jié)果存儲到臨時緩沖區(qū),然后在復(fù)制回來,這個過程可以優(yōu)化掉。使用乒乓做法,在第i級歸并過程,從buff1 歸并到buff2,在i+1級歸并過程,從buff2復(fù)制到buff1。
  2.2) 2路歸并排序的核心動作是比較2個對列的頭元素那個更大,其比較結(jié)果是隨機的,2個分支機會均等,CPU的分支預(yù)測算法不起作用,當(dāng)預(yù)測失敗,可大大降低程序性能,如果消除這個分支,可明顯提高程序性能。


 


13#


樓主知道標(biāo)準(zhǔn)庫的sort是怎么實現(xiàn)的么? 先快排,遞歸深度超過一個閥值就改成堆排,然后對最后的幾個進(jìn)行插入排序。    //233系統(tǒng)真機智


 


14#


1.快排的時間復(fù)雜度確實不穩(wěn)定,極端情況是O(n^2),但是平攤下來是T(n*lg(n)),而歸并是嚴(yán)格的O(n*log(n))。
2.快速排序比歸并排序快。其原因有
  1)快排對內(nèi)存的訪問是順序方式(包括逆序),只有兩個目標(biāo)而且是同一個數(shù)組,故cache的命中率不會比歸并低。特別是數(shù)組空間接近于cache大小時,這一優(yōu)勢將更加明顯。
  2)快排的內(nèi)存寫操作次數(shù)平攤下來是T(n*lg(n)/2),而歸并的內(nèi)存寫操作次數(shù)是嚴(yán)格的O(n*log(n)),由于內(nèi)存寫操作開銷比較大,所以對于隨機數(shù)據(jù)快排優(yōu)于歸并。


 


……


16#


同學(xué)們,這些算法都有標(biāo)準(zhǔn)的開源程序。
自己寫程序?qū)斫馑惴ǖ拇_有好處。
但是如果用于得到一般性的比較結(jié)果,那是靠不住的。


 


原帖到此終結(jié);


 


文自:http://bbs.csdn.net/topics/390554511


 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
??全面圖解快速排序,詳細(xì)圖文并茂解析!??
七大排序算法總結(jié)
8大經(jīng)典排序算法
知識點總結(jié)之排序算法
排序算法(三)之堆排序
排序算法總結(jié)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服