此代码适用于存在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;
}
}
}
}
答案 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]