使用Merge Sort在Java中计算反转时递归的问题

时间:2017-09-13 00:36:20

标签: java recursion

此代码适用于存在100000个整数的文件的问题,每个整数在一行上,应该是数组中的100000个有序整数。目标是计算反转次数(当数组右侧的数字大于左侧的数字时)。该实现应该使用合并排序。合并左右子阵列时,如果右子阵列中的值用于合并时左子阵列中仍有剩余值,则左子阵列中剩余的值的数量将递增为总反转计数。

对于简单的情况,我的代码没有返回正确的反转次数,所以我认为我的代码中的问题是在递归中,或者是三行

mergeSort(left);
mergeSort(right);
merge(ii, left, right);

我无法弄清楚我没有得到正确的反转次数的原因。最有可能的原因是,当合并左右子阵列时,我应该更多地增加反转,但我还没有弄清楚错误。

import java.io.*;
import java.util.*;

public class Inversion {

    public static int inversions = 0;
    public static void main(String[] args) throws FileNotFoundException{
        // TODO Auto-generated method stub

        int[] list = new int[100000];
        Scanner sc = new Scanner(new File("src/inversion.txt"));
        for(int i = 0; i < 100000; i++)
        {
            list[i]=sc.nextInt();
        }

        System.out.println(inversions);

        sc.close();
    }
    public static void mergeSort(int[] ii)
    {
        if (ii.length > 1)
        {
        int[]left = Arrays.copyOfRange(ii,  0,  ii.length/2);
        int[]right = Arrays.copyOfRange(ii, ii.length/2, ii.length);

        mergeSort(left);
        mergeSort(right);
        merge(ii, left, right);
        }

    }
    public static void merge(int[]result, int[]left, int[]right)
    {
        int ileft=0;
        int iright=0;
        for (int i = 0; i < result.length; i++)
        {
            if (iright>=right.length || (ileft < left.length && left[ileft] <= right[iright]))
            {
                result[i]=left[ileft++];
            }
            else
            {
                result[i]=right[iright++];
                inversions += left.length-ileft;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

public static void mergeSort(int[] ii)中的if (ii.length > 1)方法中,您应该检查ii.length >= 2是否因为合并排序算法将数组分成两半,这就是Arrays.copyOfRange中除以2的原因。当分成两半时,1不能分成整数。

在合并中尝试left[ileft] < right[iright]而不是left[ileft] <= right[iright]