麻烦理解合并排序合并部分算法

时间:2015-04-25 09:41:29

标签: java algorithm sorting merge

我在理解合并排序算法的'merge'部分时遇到了一些麻烦,因为我试图在上下文中理解算法的某些部分,并且某些变量/循环没有意义我。我理解递归除法过程和合并的排序方面,但在这个特定的合并算法中:

    public static void merge(int data[], int temp[], int low, int middle, int high){
    int ri=0; //result index
    int ti=low;//temp index
    int di=middle;//data index
    int[] result = new int[high-low+1];

    while (ti<middle && di<=high){
      if (data[di]<temp[ti]){
        result[ri++] = data[di++];//smaller is in data
       } 
       else{
            result[ri++] = temp[ti++];//smaller is in temp
            }
    } 

while(ti<middle) result[ri++]=temp[ti++];
while(di<=high) result[ri++]=data[di++];
for(int i=0;i<high;i++) data[low+i]=result[i];

我不明白最后3个循环:

while(ti<middle) result[ri++]=temp[ti++];
while(di<=high) result[ri++]=data[di++];
for(int i=0;i<high;i++) data[low+i]=result[i];

你能解释一下这三个循环在合并的上下文中是什么,还有什么进一步的建议可以更好地理解合并排序算法的合并部分?

1 个答案:

答案 0 :(得分:1)

此循环while (ti<middle && di<=high)的条件意味着一旦在两半中的至少一半中没有更多元素,它就会终止。但是在另一个元素中仍然可以存在一些元素。这就是为什么我们需要这两行:

while(ti<middle) result[ri++]=temp[ti++]; // Remaining elements from the first half.
while(di<=high) result[ri++]=data[di++]; // Remaining elements from the second half.

现在我们需要将合​​并的结果复制到原始数组。这正是最后一行所做的。

关于合并阶段的理解:您是否了解算法本身(在数学意义上,没有引用任何具体的编程语言)?如果你没有,那么首先要完全理解它,而不是查看任何代码。如果您确实理解算法但不了解此代码,那很好,因为这段代码非常糟糕。

您可以看一下更清晰的实现:

mergeSort [] = []
mergeSort [x] = [x]
mergeSort xs = 
    let (firstHalf, secondHalf) = splitAt (length xs `div` 2) xs
    in merge (mergeSort firstHalf) (mergeSort secondHalf)  

merge xs [] = xs
merge [] ys = ys
merge xs@(x:xt) ys@(y:yt) 
    | x <= y = x : merge xt ys
    | otherwise = y : merge xs yt