读书人

算法 之 分治 - 合并排序-归拢两个已排

发布时间: 2012-10-26 10:30:59 作者: rapoo

算法 之 分治 - 合并排序-合并两个已排序的表

假定有一个数组 A[1...n],low, middle, high 为它的三个索引,并有 1?≤ low?≤ middle < high?≤?n,使得两个子数组 A[low...middle],A[middle+1...high] 各自按升序排列。

我们要重新排列A中元素的位置,使得 A[low...high] 中的元素也按升序排列。这就是合并 A[low...middle] 和 A[middle+1...high] 的过程。

?

举个例子,就是我们有个数组 A = { 0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9 }; 这里 low=0, middle=5, high=10

我们要对它进行排序使 A = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

?

我们可以使用这样的方法来合并这两个子数组:

首先使用两个索引 s 和 t,初始化时各自指向 A[low] 和 A[middle+1],再用一个空数组 B[low...high] 做暂存器。每一次比较元素 A[s] 和 A[t],将小的元素添加到辅助数组 B,如果相同就把 A[s] 添加进去。

然后更新索引,如果 A[s] ≤ A[t],则 s 加 1,否则 t 加 1,当条件 s=middle+1 或 t=high+1 成立时过程结束。

s=middle+1 时,我们把数组 A[t...high] 中剩余的元素添加到 B,

t=high+1 时,把数组 A[s...middle] 中剩余的元素添加到 B。

最后,把数组 B[low...high] 复制回 A[low...high]。

?

过程 ?Merge

输入 ?数组 A[1...n] 和它的三个索引 low, middle, high, 1 ≤ low?≤ middle < high?≤ n,

?? ? ? ? ?两个子数组 A[low...middle] 和 A[middle+1...high] 各自按升序排列

输出 ?合并两个子数组 A[low...middle] 和 A[middle+1...high] 的数组 A[low...high]

?

算法描述

comment: B[low...high] 是个辅助数组

s ← low; t ← middle+1; index ← low

while s?≤ middle and t?≤ high

?? ?if A[s]?≤ A[t] then

?? ? ? ?B[k] ← A[s]

?? ? ? ?s ← s + 1

?? ?else

?? ? ? ?B[k] ← A[t]

?? ? ? ?t ← t + 1

?? ?end if

?? ?index ← index + 1

end while

if s = middle+1 then B[k...high] ← A[t...high]

else B[k...high] ← A[s...middle]

end if

A[low...high] ← B[low...high]

?

以下是此算法的 Java 实现:

private static void merge(int[] array, int low, int middle, int high){int length = high - low + 1;int indexLowToMiddle = low;// 从 low 位置开始的索引int indexMiddleToHigh = middle + 1;// 从 middle+1 位置开始的索引int[] tempArray = new int[length];int tempIndex = 0;while (indexLowToMiddle <= middle && indexMiddleToHigh <= high){if (array[indexLowToMiddle] <= array[indexMiddleToHigh]){tempArray[tempIndex] = array[indexLowToMiddle];indexLowToMiddle += 1;}else{tempArray[tempIndex] = array[indexMiddleToHigh];indexMiddleToHigh += 1;}tempIndex += 1;}if (indexLowToMiddle == middle + 1){System.arraycopy(array, indexMiddleToHigh, tempArray, tempIndex, length - tempIndex);}else{System.arraycopy(array, indexLowToMiddle, tempArray, tempIndex, length - tempIndex);}System.arraycopy(tempArray, 0, array, low, length);}
?

读书人网 >编程

热点推荐