合并排序算法不起作用

时间:2017-11-09 08:42:27

标签: java algorithm mergesort

这是我在java中的mergesort的代码:

public class MergeSort {

    public static void mergesort(int[] input) {

        int inputSize = input.length;
        if(inputSize < 2) {
            return;
        }
        int[] left = new int[inputSize/2];
        int[] right = new int[inputSize/2];
        int count = 0;
        for(int i=0; i < inputSize/2; i++) {
            left[i] = input[i];
        }
        for(int i=inputSize/2; i<inputSize; i++) {
            right[count] = input[i];
            count++;
        }

        mergesort(left);
        mergesort(right);
        merge(left, right, input);

    }

    public static int[] merge(int[] returnArr, int[] left, int[] right) {
        int leftSize = left.length;
        int rightSize = right.length;
        int i = 0;
        int j =0;
        int k = 0;
        int count = 0;
        while(i < leftSize && j < rightSize) {
            if(left[i] <= right[j]) {
                returnArr[k] = left[i];
                i++;
            }
            else {
                returnArr[k] = right[j];
                j++;
            }
            k++;
        }

        while(i<leftSize) {
            returnArr[k] = left[i];
            i++;
            k++;
        }
        while(j < rightSize) {
            returnArr[k] = right[j];
            j++;
            k++;
        }

        for(int x=0; x<returnArr.length; x++) {
            System.out.print(returnArr[x]);
        }

        return returnArr;
    }
    public static void main(String[] args) {
        int[] array = {3,4,6,2,7,1,8,6};
        mergesort(array);

    }

}

我的问题是我遇到了越界异常。 我使用调试器并发现在mergesort(左)和mergesort(右)完成递归运行之后。

进入合并函数的左右数组分别具有值[3]和[4],这是正确的。

但是当调试器跳转到merge函数时,left有值[3]和right,因为某种原因是长度为2并且值为[3,4]。

这是我的越界异常的来源,虽然我不确定为什么当合并函数第一次运行时,它会改变&#34;右&#34;的值。

3 个答案:

答案 0 :(得分:0)

一个容易看到的问题是,您不应该制作2个大小为inputSize/2的数组。制作两个inputSize/2inputsize-inputSize/2数组。否则算法会因奇数长度数组而失败。

也可以使用正确的参数顺序调用函数。 merge( input, left, right);

答案 1 :(得分:0)

我修复了您的代码并将它们合并为1个方法,left.lengthright.lengthinput.length限制,因此您只需要按input.length循环:

public static void mergeSort(int[] input)
{
    if (input.length < 2)
    {
        return;
    }

    int[] left = new int[input.length / 2];
    int[] right = new int[input.length - input.length / 2];

    for (int i = 0; i < input.length; i++)
    {
        if (i < input.length / 2)
            left[i] = input[i];
        else
            right[i - input.length / 2] = input[i];
    }

    mergeSort(left);
    mergeSort(right);

    for (int i = 0, l = 0, r = 0; i < input.length; i++)
    {
        if (l >= left.length)
        {
            input[i] = right[r];
            r++;
        }
        else if (r >= right.length)
        {
            input[i] = left[l];
            l++;
        }
        else
        {
            if (left[l] >= right[r])
            {
                input[i] = right[r];
                r++;
            }
            else
            {
                input[i] = left[l];
                l++;
            }
        }
    }
}

答案 2 :(得分:0)

您的代码存在两个问题:

1- as @coderredoc说:你的左右数组大小错误:

例子:如果你有一个包含7个元素的数组,你的左右数组的大小将是7/2 = 3,所以你在左右数组中总共有6个元素,而不是7个。

2-您正在使用错误的参数顺序调用mergeSort函数中的merge函数: 它应该是returnArr,left,right而不是left,right,returnArr。

说明:

如果将左数组作为第一个参数传递,它将合并右数组和左数组中的returnArr。但是你的左数组的大小为3,其他数组的大小总和为7 + 3 = 10,这就是你得到OutOfBoundsException的原因。

你需要调用merge(输入,左,右);

这是最终版本:

public class MergeSort {

    public static void mergesort(int[] input) {

        int inputSize = input.length;
        if(inputSize < 2) {
            return;
        }
        int[] left = new int[inputSize/2];
        int[] right = new int[inputSize-inputSize/2];
        int count = 0;
        for(int i=0; i < inputSize/2; i++) {
            left[i] = input[i];
        }
        for(int i=inputSize/2; i<inputSize; i++) {
            right[count] = input[i];
            count++;
        }

        mergesort(left);
        mergesort(right);
        merge(input,left, right);

    }

    public static int[] merge(int[] returnArr, int[] left, int[] right) {
        int leftSize = left.length;
        int rightSize = right.length;
        int i = 0;
        int j =0;
        int k = 0;
        int count = 0;
        while(i < leftSize && j < rightSize) {
            if(left[i] <= right[j]) {
                returnArr[k] = left[i];
                i++;
            }
            else {
                returnArr[k] = right[j];
                j++;
            }
            k++;
        }

        while(i<leftSize) {
            returnArr[k] = left[i];
            i++;
            k++;
        }
        while(j < rightSize) {
            returnArr[k] = right[j];
            j++;
            k++;
        }

        for(int x=0; x<returnArr.length; x++) {
            System.out.print(returnArr[x]);
        }

        return returnArr;
    }
    public static void main(String[] args) {
        int[] array = {3,4,6,2,7,1,8,6};
        mergesort(array);

    }

}