歸併排序中「歸併」的含義是將兩個或兩個以上的有序表組合成乙個新的有序表。實現歸併的的方法很簡單。我這裡實現的是2-路歸併,多路歸併的道理是一樣的。**如下:
public static void merge(int a, int start, int mid, int end) else
} while (i <= mid)
while (j <= end)
for (int u = 0; u < temp.length; ++u)
}
歸併排序的思想是遞迴分治,具體來說就是將乙個規模比較大的問題(通常來說這個規模較大的問題我們沒辦法直接解決)通過多次劃分成為若干個規模很小的問題,而這些規模較小的問題我們又能夠直接解決它,並且解決若干個小規模問題的方法和解決規模較大問題的方法又是一樣的。可能我這樣說比較繞、不直接明了,就拿歸併排序來說吧來說吧:
原待排序列我們沒辦法直接一下得到它的有序序列,我們可以通過一次次劃分,直到將原序列劃分成若干個長度為1的序列,長度為1的序列自然是有序的序列。之後使用二路歸併merge()方法就可以將有序的子串行兩兩歸併成為有序的,這樣多次merge之後,原序列就自然有序啦!實現劃分和歸併的遞迴形式的**也很簡潔明瞭,聰明的你一看便懂:
public static void mergesort(int a, int start, int end)
對於陣列a來說,其中兩個元素a[i]和a[j]若滿足ia[j],那麼這兩個元素就是乙個逆序對。
還是拿陣列a來說,在上面的**要執行merge()方法的時候,a[start, (start + end) / 2]和a[ (start + end) / 2+1,end]兩段序列都是分別有序的,且前段的下標i和後段下標j必然滿足ia[j]有多少對就可以了,請看**:
public static int num = 0;// 靜態變數
/** * left[start1,end1],right[start2,end2]
* left的下標必然是小於right的下標,所以求逆序對就是統計left>rigt的個數
*/public static void count(int left, int right, int start1, int end1,
int start2, int end2)
}} }
我們定義了乙個靜態的全域性變數,對於每次count()函式的執行,只要有滿足條件的逆序對,num就會自加1。最後執行結束得到的num自然就是逆序對的個數了。這裡還有疑問的話可以對照著前面的那張看一看你就會恍然大悟了。
到這裡差不多這個演算法就已經實現的差不多了,還差一步就是什麼時候統計逆序對。上一步提到統計逆序對是在得到兩個子有序列的時候,也就是在對兩個有序列進行merge()之前。顯然只需用對mergesort()新增一行**即可:
public static void mergesort(int a, int start, int end)
}
下面就來測試一下上面的**,寫個主函式:
public static void main(string args) ;
mergesort(a, 0, a.length - 1);
system.out.print("2-路歸併結果:");
for (int i = 0; i < a.length; ++i)
system.out.println();// 換行
system.out.print("原序列中逆序對的個數:");
system.out.print(num);
}
執行得到:
為了便於驗證,我將原序列設定為逆序的。理論上講n個逆序的序列有序對有n(n-1)/2個(很容易推導出來的),那麼10個元素的逆序序列的逆序對就是45個。所以該演算法經過驗證是正確的。
就這樣了吧,還請大佬們多多指教!
歸併排序應用之陣列中的逆序對數
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。輸入 7,5,6,4 輸出 5 class solution def init self self.count 0def reversepairs self,nums list...
歸併排序應用之求陣列中的逆序數
一,問題描述 給定乙個陣列,求解該陣列中有多少組逆序對。比如 7,5,6,4 一共有五對逆序對。分別是 7,6 7,5 7,4 6,4 5,4 二,演算法分析 有兩種方法來求解逆序對 的數目。一種是,對陣列中的每個元素,都與它後面的元素進行比較,若後面的元素比它小,則找到乙個逆序對。這樣,第乙個元素...
陣列中的逆序對(歸併排序)
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。在歸併排序的一次merge中,r j 1 法一 統計i的逆序數 int merge int a,int p,int q,int r int n1 q p 1,n2 r q in...