基本排序排序演算法

來源:互聯網
上載者:User

時空複雜度:

冒泡排序:時間O(n^2),額外空間O(1)

插入排序:時間O(n^2),額外空間O(1)

選擇排序:時間O(n^2),額外空間O(1)

基數排序:時間O(k*n)(k=logN_max),額外空間O(n)(臨時儲存)+O(B)(記數,B為基的大小)

記數排序:時間O(n+k),額外空間O(k)

希爾排序:時間O(n*logn^2),額外空間O(1)

快速排序:時間O(n*log(n)),額外空間O(logn)(遞迴棧)

歸併排序:時間O(n*log(n)),額外空間O(n)(臨時數組)+O(logn)(遞迴棧)

堆排序:  時間O(n*log(n)) 

使快速排序退化的例子:

n, n-1, n-2, n-3.......3,2,1,快速排序具有O(n^2)的複雜度。

最佳化方法:隨機播放劃分元素,而不是固定選擇最左面的元素。

對歸併來說,一個很不理想的例子:

1,2,3,…… , n

對有序序列還是需要O(nlogn)的時間複雜度。

最佳化方法:找到序列的連續自增段,把這樣的自增段進行合并。

穩定排序和不穩定排序

穩定的排序演算法:冒泡排序、插入排序、基數排序、記數排序、歸併排序

非穩定排序演算法:希爾排序、選擇排序、快速排序、堆排序

實際上穩定排序可以實現成非穩定的,看具體的實現過程。有些同學誤以為自己寫了一個冒泡排序就是穩定的,注意比較的時候是">=" 還是">"。

內部排序與外部排序

http://zh.wikipedia.org/zh/%E5%A4%96%E6%8E%92%E5%BA%8F

內部排序:內部排序是指待排序列完全存放在記憶體中所進行的排序過程,適合不太大的元素序列。

外部排序:外部排序指的是大檔案的排序,即待排序的記錄儲存在外儲存空間上,待排序的檔案無法一次裝入記憶體,需要在記憶體和外部儲存空間之間進行多次資料交換,以達到排序整個檔案的目的。最常用的外部排序是多路歸併排序。對於外部排序,影響速度的最主要因素為訪問磁碟的次數,所以設計外部排序演算法時,儘可能減少訪問磁碟的次數。

對於外部排序多路歸併演算法的時間複雜度進行簡要分析。

設有n個數,分成k段,之後利用m路歸併 。

t1 = n*log(n/k) 每段分別排序  n*log(n/k)。

t2 = n*logk    每趟對n個數合并(每個數每趟只操作一次),一共logk趟,

t3 = n * (T_read + T_write) * logk 從檔案中讀取和寫入數字花費的時間,

設每讀取一個數的耗時為T_read,每次寫一個數耗時為T_write,

T(n) = t1 + t2+t3 = n*log(n/k) + n*logk + n*(T_read+T_write)*logk ,其中logk是以m為底的。

所以,為了減少訪問磁碟的次數,必須增大基m,但是m並不是越大越好,如果越大,則在m個數中選擇最大值會越慢,所以一般都選m=9。

逆序數問題

對於序列 x1,x2,x3.......xn

若存在i>j,且滿足x[i] < x[j],則稱(x[i],x[j])構成一個逆序對, 一個序列所有的逆序對的數目叫做這個序列的逆序數。

例如序列 :5 4 3 2 1

逆序數為 1+2+3+4 = 10

利用歸併排序可以快速的求得一個序列的逆序數。

尋找第K大數演算法

問題1:給出一個序列,求這個序列第K大的數(離線)

比較通用的演算法:

(1) 利用快速排序的劃分。每次可以省去一部分的數進行尋找。

設下一次的尋找百分比為q<1,

時間 T(n) = n + T(n*q)

                     = n + n*q + T(n*q^2)

                     = n + n*q + n*q^2 + T(n*q^3)

                     ......

                     = n(1 + q + q^2 + q^3 + ......)

                     = n(1*(1-q^k)/(1-q))

當q=1/2時, T(n) = 2n = O(n)。

這種方法最壞情況下的時間複雜度是O(n^2)。

那麼有沒有能夠保證最壞時間複雜度是O(n)的演算法嗎?有

(2) 最壞時間下是O(n)複雜度的演算法

http://en.wikipedia.org/wiki/Selection_algorithm 或參見<<演算法導論>> P190-P191

針對普通的劃分和隨機化劃分的缺點,對選擇劃分數進行改進:選擇中位元的中位元進行劃分。

假設函數Find(A, k, n)返回的是A數組中第k大的元素,新的尋找演算法如下:

1:將輸入數組的n個元素劃分為n/5組,每組5個元素,至多有一個組的元素數目小於5。

2:尋找n/5個組的每個組的中位元。對每個組的5個元素利用插入排序,之後選擇中位元。

3: 對第2步找到的n/5個中位元遞迴調用Find函數,找出其中位元x。

4:利用中位元x對輸入數組進行劃分。並得出x的排位。

5:如果第四步得到的x的排位為k,則返回x。如果x的排位大於k,則在低區進行遞迴尋找,否則在高區進行尋找。

因為x是中位元,除去x本身所在的組和那個元素數目小於5的組不算,大於x的元素數目至少為3*(1/2)*(n/5 - 2) = 3*n/10 - 6。

同理小於x的元素數目至少為3*n/10 - 6。那麼第4步最多有n-(3*n/10-6) = 7*n/10+6個元素參加下次的遞迴尋找。

設Find(A, k, n)花費時間為T(n)。

則T(n) = t1 + t2 + t3 + t4 + t5。

t1 = O(n)    (分成n/5組)

t2 = O(n)    (每組進行選擇可以看做O(1)時間花費)

t3 = T(n/5)   (對n/5個中位元遞迴選擇)

t4 = O(n)     (根據x進行劃分)

t5 = T(7*n/10 + 6)  (下一次遞迴選擇)

T(n) = T(n/5) + T(7*n/10 + 6) + O(n)

最後可推算出T(n)=O(n),但是個人認為常數比較大。

K非常小時情況下的選擇第K大元素演算法:

利用冒泡或者選擇排序,時間複雜度O(K*n)。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.