有意思的排序算法-合並排序


  合並排序也可以用打牌的過程來說明,假設桌面上朝上放着兩摞已經排好序的牌,現在要將這兩摞已排好序的牌合成一摞,首先,取兩摞中位於最上面的兩張中最小的一張並將其加入到新的一摞中,然后接着從兩摞中再取一張最小的加入到新的一摞中,因為第二張,肯定比第一張要大,因此要加入到第一張的后面才行。

  從上面可以看出,合並排序是利用分治法進行排序的算法,直觀地操作如下:

  分解:將n個元素分成各含n/2個元素的子序列;

  解決:用合並排序法對兩個子序列進行遞歸地排序;

  合並:合並兩個已排序的子序列以得到排序結果。

  我就不寫偽代碼了,直接用Java將其實現的代碼如下:

 1 /**
 2      * 合並兩個排好的序列
 3      * @param A
 4      *            int數組
 5      * @param p
 6      *            起始位置
 7      * @param q
 8      *            中間位置
 9      * @param r
10      *            終止位置
11      * @param isInc
12      *            isInc 是否升序,true為升序,false為降序
13      */
14     private void merge(int[] A, int p, int q, int r, boolean isInc) {
15         int nLeft = q - p + 1;
16         int nRight = r - q;
17         int[] left = new int[nLeft];
18         int[] right = new int[nRight];
19         int i = 0, j = 0, k = 0;
20         for (i = 0; i < nLeft; i++) {
21             left[i] = A[p + i];
22         }
23         for (j = 0; j < nRight; j++) {
24             right[j] = A[q + j + 1];
25         }
26         i = 0;
27         j = 0;
28         for (k = p; k <= r; k++) {
29             if (isInc ^ (left[i] <= right[j])) {
30                 A[k] = right[j];
31                 j++;
32             } else {
33                 A[k] = left[i];
34                 i++;
35             }
36 
37             if (i == nLeft) {
38                 k++;
39                 for (; j < nRight; j++) {
40                     A[k] = right[j];
41                     k++;
42                 }
43             }
44             if (j == nRight) {
45                 k++;
46                 for (; i < nLeft; i++) {
47                     A[k] = left[i];
48                     k++;
49                 }
50             }
51         }
52     }
 1 /**
 2      * 合並排序
 3      * @param A
 4      *            int數組
 5      * @param p
 6      *            起始位置
 7      * @param r
 8      *            終止位置
 9      * @param isInc
10      *            是否升序,true為升序,false為降序
11      */
12     private void mergeSort(int[] A, int p, int r, boolean isInc) {
13         int q = 0;
14         if (p < r) {
15             q = (p + r) / 2;
16             mergeSort(A, p, q, isInc);
17             mergeSort(A, q + 1, r, isInc);
18             merge(A, p, q, r, isInc);
19         }
20     }

  合並排序不是原地進行排序的,時間復雜度為O(nlgn)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM