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

  合并排序也可以用打牌的过程来说明,假设桌面上朝上放着两摞已经排好序的牌,现在要将这两摞已排好序的牌合成一摞,首先,取两摞中位于最上面的两张中最小的一张并将其加入到新的一摞中,然后接着从两摞中再取一张最小的加入到新的一摞中,因为第二张,肯定比第一张要大,因此要加入到第一张的后面才行。

  从上面可以看出,合并排序是利用分治法进行排序的算法,直观地操作如下:

  分解:将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)。

 

posted @ 2012-04-29 09:18  Mr. Coding  阅读(3027)  评论(1编辑  收藏  举报