《演算法導論》CLRS演算法C++實現(九)P109 選擇數組中第i小(大)的數 順序統計量

來源:互聯網
上載者:User

第九章 中位元和順序統計學

9.2 以期望線性時間做選擇

上一講是找出最小值,同時找出最大值最小值,以及找出次小值的問題。隨意選擇數組中第i小(大)的元素看起來要比找最小值的簡單選擇問題要複雜一些。但是令人驚奇的是,兩種問題的漸近已耗用時間卻是相同的,都是O(n)。演算法導論上介紹了一種用來解決選擇問題的分治演算法,即RANDOMIZED-SELECT演算法。本演算法以快速排序演算法的分割演算法為基礎,如同在快速排序中一樣,此演算法的思想也是對輸入數組進行遞迴劃分。但與快速排序不同的是,快速排序會遞迴處理劃分的兩邊,而RANDOMIZED-SELECT只處理劃分的某一邊。這一差異在演算法的分析中就體現出來了:快速排序的期望已耗用時間是O(nlgn)。而RANDOMIZED-SELECT的期望已耗用時間為O(n)。下面是RANDOMIZED-SELECT演算法:

RANDOMIZED-SELECT(A, p, r, i)  P109

1 if p = r2     then return A[p]3 q ← RANDOMIZED-PARTITION(A, p, r)4 k ← q - p + 15 if i = k6     then return A[q]7 elseif i < k8     then return RANDOMIZED-SELECT(A, p, q - 1, i)9 else return RANDOMIZED-SELECT(A, q + 1, r, i - k)

RANDOMIZED-SELECT利用了RANDOMIZED-PARTITION程式。所以,本演算法也是一個隨機演算法,因為它的行為部分地由隨機數產生器的輸出來決定。本演算法返回A[p..r]中的第i小的元素。

演算法第三行的RANDOMIZED-PARTITION執行之後,數組A[p..r]被劃分為兩個子數組A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每個元素都小於或等於A[q],A[q+1..r]中的每個元素都大於A[q]。

第四行計算A[p..r]的元素個數k,即處於低劃分區的元素的個數加上一個主要元素。然後第五行檢查A[q]是不是第i小的元素。如果是,就返回A[q]。否則,演算法要確定第i小的元素落在兩個子數組A[p..q-1]和A[q+1..r]中的哪一個之中。如果i<k,則在低區,如i>k,則在高區。然後遞迴選擇。

演算法的最壞已耗用時間為O(n2),即使是要選擇最小元素。

《編程之美》中的2.3 尋找發貼“水王”就可以用順序統計量來解答。

C++代碼

 1 #include <iostream> 2 #include <ctime> 3 #include <cstdlib> 4  5 using namespace std; 6  7 void swap(int* x, int* y) 8 { 9     int temp;10     temp = *x;11     *x = *y;12     *y = temp;13 }14 15 inline int random(int x, int y)16 {17     srand((unsigned)time(0));18     int ran_num = rand() % (y - x) + x;19     return ran_num;20 }21 22 int partition(int* arr, int p, int r)23 {24     int x = arr[r];25     int i = p - 1;26     for(int j = p; j < r; j++)27     {28         if (arr[j] <= x)29         {30             i++;31             swap(arr[i], arr[j]);32         }33     }34     swap(arr[i + 1], arr[r]);35     return ++i;36 }37 38 int randomizedpartition(int* arr, int p, int r)39 {40     int i = random(p, r);41     swap(arr[r], arr[i]);42     return partition(arr, p, r);43 }44 45 int randomizedSelect(int* arr, int p, int r, int i)46 {47     if(p == r)48     {49         return arr[p];50     }51     int q = randomizedpartition(arr, p, r);52     int k = q - p + 1;53     if(i == k)54     {55         return arr[q];56     }57     else if(i < k)58     {59         return randomizedSelect(arr, p, q - 1, i);60     }61     else62         return randomizedSelect(arr, q + 1, r, i - k);63 }64 65 int main()66 {67     int arr[] = {1, 3, 5, 23, 64, 7, 23, 6, 34, 98, 100, 9};68     int i = randomizedSelect(arr, 0, 11, 4);69     cout << i << endl;70     return 0;71 }
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.