有人可以帮助您了解合并排序算法吗?

时间:2019-04-23 00:22:53

标签: mergesort

我的问题是:在mergeSort方法中,我们通过使用递归将数组分成越来越小的数组,但是我无法弄清楚它们的存储位置以及如何将所有这些数组输入方法排序什么时候不递归?例如,假设我们将数字2, 1, 5, 8, 9放入数组中。之后,我们将有5个数组,每个数组中包含一个元素。因此,现在我们必须合并其中的全部,但是如何执行这些步骤,如何输入以得到两个排序后的数组:1, 25, 8, 9,它们将合并得到1, 2, 5, 8, 9

public class main {

    // Helper method to print out the integer array.
    private static void printArray(int[] array) {
        for (int i: array) {
            System.out.print(i + " ");
        }
        System.out.println();
    }

    // Breaks down the array to single or null elements in array.
    private static int [] mergeSort(int[] array) {
        // Recursive control 'if' statement.
        if (array.length <= 1) {
            return array;
        }
        int midpoint = array.length / 2;
        // Declare and initialize left and right arrays.
        int[] left = new int[midpoint];
        int[] right;
        if (array.length % 2 == 0) { // if array.length is an even number.
            right = new int[midpoint];
        } else {
            right = new int[midpoint + 1];
        }

        // Populate the left and right arrays.
        for (int i = 0; i < midpoint; i++) {
            left[i] = array[i];
        }

        for (int j = 0; j < right.length; j++) {
            right[j] = array[midpoint+j];
        }

        int[] result = new int[array.length];

        // Recursive call for left and right arrays.
        left = mergeSort(left);
        right = mergeSort(right);

        // Get the merged left and right arrays.
        result = merge(left, right);

        // Return the sorted merged array.
        return result;
    }

    // Merges the left and right array in ascending order.

    private static int[] merge(int[] left, int[] right) {
        // Merged result array.

        int[] result = new int[left.length + right.length];

        // Declare and initialize pointers for all arrays.
        int leftPointer, rightPointer, resultPointer;
        leftPointer = rightPointer = resultPointer = 0;

        // While there are items in either array...

        while(leftPointer < left.length || rightPointer < right.length) {

            // If there are items in BOTH arrays...

            if (leftPointer < left.length && rightPointer < right.length) {

                // If left item is less than right item...

                if (left[leftPointer] < right[rightPointer]) {

                    result[resultPointer++] = left[leftPointer++];

                } else {

                    result[resultPointer++] = right[rightPointer++];
                }
            }

            // If there are only items in the left array...

            else if (leftPointer < left.length) {

                result[resultPointer++] = left[leftPointer++];
            }
            // If there are only items in the right array...

            else if (rightPointer < right.length) {
                result[resultPointer++] = right[rightPointer++];
            }
        }
        return result;
    }

    public static void main(String args[]) {
        // Initial array with print out.

        int[] array = { 2, 1, 5, 8, 9 };

        System.out.println("Initial Array: ");

        printArray(array);

        // Sorted and merged array with print out.

        array = mergeSort(array);

        System.out.println("Sorted Array: ");

        printArray(array);
    }
}

1 个答案:

答案 0 :(得分:0)

编写的示例代码存在内存泄漏,它使用mergeSort的结果向左和向右重新分配,从而在递归调用mergeSort之前丢失分配给左右的内容。

该问题提到了非递归排序,这将是自下而上的合并排序。稳定排序的大多数库实现都是自底向上合并排序的一些变体,例如插入排序和自底向上合并排序的混合。链接至Wiki文章,了解自底向上合并排序的基本逻辑:

https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation

为解释自下而上的合并排序,将n个元素组成的数组视为大小为1的n个游程,其中大小为1的游程可以视为已排序。然后合并大小为1的运行对以创建大小为2的排序运行。合并大小为2的对运行以创建大小为4的排序运行,依此类推,直到合并产生单个排序的运行。自上而下的方法类似,不同之处在于它递归地拆分一个数组(通常通过为运行的开始和结束生成索引对),直到生成两个大小为1的运行,然后合并过程才开始,然后进行合并堆栈有点像一棵树,深度优先,然后是左侧。

使用示例数组,但将其重新排序,2 1 9 8 5,自下而上看起来像这样

|2 1 9 8 5|
|2|1|9|8|5|       split
|1 2|             merge
    |8 9|         merge
        |5|       copy
|1 2 8 9|         merge
        |5|       copy
|1 2 5 8 9|       merge

对于自上而下:

|2 1 9 8 5|
|2 1 9|8 5|       split
|2 1|9|           split
|2|1|             split
|1 2|             merge
|1 2 9|           merge
      |8|5|       split
      |5 8|       merge
|1 2 5 8 9|       merge