ACM:歸併排序,以及利用歸併排序思想求解逆序對數!

來源:互聯網
上載者:User

標籤:style   color   os   問題   代碼   for   

(一)歸併排序

分析:

(1)劃分問題:把序列分成元素個數盡量相等的兩半。

(2)遞迴求解:把兩半元素分別排序。

(3)合并問題:把兩個有序表合并成一個。(每次只需要把兩個序列的最小元素加以比較,刪除其中的較小元素並加入合并後的新表)

#include <iostream>using namespace std;const int MAXN = 1000;int A[MAXN], T[MAXN];void merge_sort(int *A, int x, int y, int *T) {if(y - x > 1) {int m = x + (y - x) / 2;     //劃分int p = x, q = m, i = x;merge_sort(A, x, m, T);      //遞迴求解merge_sort(A, m, y, T);      //遞迴求解while(p < m || q < y) {if(q >= y || (p < m && A[p] <= A[q])) T[i++] = A[p++];   //從左半數組複製到臨時空間else T[i++] = A[q++];    //從右半數組複製到臨時空間}for(i = x; i < y; ++i) A[i] = T[i];   //從輔助空間複製回A數組}}int main() {int n;cin >> n;for(int i = 0; i < n; ++i) cin >> A[i];merge_sort(A, 0, n, T);for(int i = 0; i < n; ++i) cout << A[i] << endl;return 0;}
上述代碼中的兩個條件是關鍵!

首先,只要有一個序列非空,就要繼續合并while(p < m || q < y)。

其次對於:if(q >= y || (p < m && A[p] <= A[q]))。

(1)如果第二個序列為空白,這個時候第一個序列肯定非空,不然就不能進入while迴圈,這個時候覆制A[p]。

(2)否則(第二個序列非空),若且唯若第一個序列也非空,且A[p] <= A[q]時,才複製A[p]。

            

                    

(二)利用歸併排序思想求解逆序對數

題目:給一列數,求它的逆序對數!

分析,由於n可能很大,所以O(n2)的枚舉方法肯定逾時。所以要用分治的方法!

(1)劃分問題:把序列分成元素個數盡量相等的兩半。

(2)遞迴求解:統計i和j均在左邊或者均在右邊的逆序對個數。

(3)合并問題:統計i在左邊,j在右邊的逆序對個數。

劃分以後,對於右邊的每個j,統計左邊比它大的元素個數f(j),則所有f(j)之和便是答案。

所以由於我們的歸併排序操作是從小到大進行的,當右邊的A[j]複製到T中時,左邊還沒有來得及複製到T的那些數就是左邊所有比A[j]大的數。

所以此時在累加器中加上左邊元素個數m-p就可以了!


#include <iostream>using namespace std;const int MAXN = 1000;int A[MAXN], T[MAXN];void inverse_pair(int *A, int x, int y, int* cnt, int *T) {if(y - x > 1) {int m = x + (y - x) / 2;     //劃分int p = x, q = m, i = x;inverse_pair(A, x, m, cnt, T);      //遞迴求解inverse_pair(A, m, y, cnt, T);      //遞迴求解while(p < m || q < y) {if(q >= y || (p < m && A[p] <= A[q])) T[i++] = A[p++];   //從左半數組複製到臨時空間else {T[i++] = A[q++];    //從右半數組複製到臨時空間*cnt += m-p;  //更新累加器}}for(i = x; i < y; ++i) A[i] = T[i];   //從輔助空間複製回A數組}}int main() {int n;cin >> n;for(int i = 0; i < n; ++i) cin >> A[i];int cnt = 0;inverse_pair(A, 0, n, &cnt, T);cout << cnt << endl;return 0;}






聯繫我們

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