简体   繁体   English

MergeSort - 实施

[英]MergeSort - Implementation

After many recursive calls low becomes equal to high and the recursion breaks. 在许多递归调用之后,low变为等于high并且递归中断。 What happens after that? 之后会发生什么? Can anyone please explain. 任何人都可以解释。 Merge procedure is clear to me: when mergesort(0,5) is called, it calls itself again: mergesort(0,2) and then mergesort(0,1) . 合并过程对我来说很清楚:当mergesort(0,5) ,它再次调用自身: mergesort(0,2)然后mergesort(0,1) Finally mergesort(0,0) and then recursion breaks. 最后mergesort(0,0)然后递归中断。

What happens after that? 之后会发生什么? Where does the control go in the code? 控件在代码中的位置在哪里? Where is stack used? 堆栈在哪里使用? Please help me. 请帮我。

public class MergeSort {
private int[] numbers;
private int[] helper;

private int number;

public void sort(int[] values) {
    this.numbers = values;
    number = values.length;
    this.helper = new int[number];
    mergesort(0, number - 1);
}

private void mergesort(int low, int high) {
    // check if low is smaller than high, if not then the array is sorted
    if (low < high) {
        // Get the index of the element which is in the middle
        int middle = low + (high - low) / 2;
        // Sort the left side of the array
        mergesort(low, middle);
        // Sort the right side of the array
        mergesort(middle + 1, high);
        // Combine them both
        merge(low, middle, high);
    }
}

private void merge(int low, int middle, int high) {

    // Copy both parts into the helper array
    for (int i = low; i <= high; i++) {
        helper[i] = numbers[i];
    }

    int i = low;
    int j = middle + 1;
    int k = low;
    // Copy the smallest values from either the left or the right side back
    // to the original array
    while (i <= middle && j <= high) {
        if (helper[i] <= helper[j]) {
            numbers[k] = helper[i];
            i++;
        } else {
            numbers[k] = helper[j];
            j++;
        }
        k++;
    }
    // Copy the rest of the left side of the array into the target array
    while (i <= middle) {
        numbers[k] = helper[i];
        k++;
        i++;
    }

}

 public static void main(String[] args){
     int arr[] = {78,9,45,7,2,90};
     new MergeSort().sort(arr);
        for(int i = 0; i < arr.length;i++){
            System.out.print(arr[i] + "\t");
        }
 }

} }

You could put else statement and observe that the executions are still done after low >= high. 您可以使用else语句并观察执行仍然在低> =高之后完成。 Here, these calls are just skipped. 这里只是跳过这些调用。

        private void mergesort(int low, int high) { 
    // check if low is smaller than high, if not then the array is sorted
     if (low < high) { 
    // Get the index of the element which is in the middle 
int middle = low + (high - low) / 2; // Sort the left side of the array mergesort(low, middle); // Sort the right side of the array 
mergesort(middle + 1, high); // Combine them both 
merge(low, middle, high); }

    else 
    System.out.prinln("low is higher than high. Low is " +low+ "high is" +high);
     }

For top down merge sort, no merging occurs until two runs of size 1 are produced from the recursive splitting of an array. 对于自顶向下合并排序,在从数组的递归拆分生成两次大小为1的运行之前,不会发生合并。 This will be the first instance where the mergesort() calls merge(). 这将是mergesort()调用merge()的第一个实例。 Then that instance of mergesort() returns to the prior instance of mergesort(), eventually reaching it's call to merge() and so on. 然后mergesort()的实例返回到mergesort()的先前实例,最终到达它对merge()的调用,依此类推。 The merge order is depth first / left first. 合并顺序是先深度/左边第一个。

By contrast, a bottom up merge sort (most libraries use some variation of bottom up merge sort like timsort), skips the recursion and treats an array of n elements as n runs of size 1, and immediately starts merging the runs. 相比之下,自下而上的合并排序(大多数库使用自下而上合并排序的一些变体,如timsort),跳过递归并将n个元素的数组视为大小为1的n次运行,并立即开始合并运行。 The indices to the runs are generated iteratively (via loops). 运行的索引是迭代生成的(通过循环)。

This is an example of the order of operations for a top down merge sort, which is depth first, left first. 这是自上而下合并排序的操作顺序的示例,其首先是深度,左边是第一个。 The vertical bars represent the split between left and right halves of the current array. 垂直条表示当前数组的左半部分和右半部分之间的分割。

|4 2 8 6 0 5 1 7 3 9|
|4 2 8 6 0|5 1 7 3 9|
|4 2|8 6 0|
|4|2|
|2 4|
    |8|6 0|
      |6|0|
      |0 6|
    |0 6 8|
|0 2 4 6 8|
          |5 1|7 3 9|
          |5|1|
          |1 5|
              |7|3 9|
                |3|9|
                |3 9|
              |3 7 9|
          |1 3 5 7 9|
|0 1 2 3 4 5 6 7 8 9|

What happens is that every stacked method call is executed. 会发生什么是执行每个堆栈方法调用。 If you represent graphically the stack you have the following in every step: 如果您以图形方式表示堆栈,则每个步骤都包含以下内容:

1.- bottom/top --> mergeSort(0, 5)

2.- top    --> mergeSort(0, 2)
    bottom --> mergeSort(0, 5)

3.- top    --> mergeSort(0, 1)
               mergeSort(0, 2)
    bottom --> mergeSort(0, 5)

4.- top    --> mergeSort(0, 0) --> breaks and go back
               mergeSort(0, 1)
               mergeSort(0, 2)
    bottom --> mergeSort(0, 5)

5.- top    --> mergeSort(0, 1) --> finish and continue with next line
               mergeSort(0, 2)
    bottom --> mergeSort(0, 5)

6.- top    --> mergeSort(2, 2) --> next line after mergeSort(0, 1)
               mergeSort(0, 2)
    bottom --> mergeSort(0, 5)

7.- etc.

With this first steps represented graphically, you can figure out the rest. 通过图形表示的第一步,您可以找出其余的步骤。 Hope that helps 希望有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM