我无法在合并排序中使用java获得反转次数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我无法在合并排序中使用java获得反转次数相关的知识,希望对你有一定的参考价值。
我正在设计A[0..n − 1]
是一个n个实数的数组。
如果这些数字是乱序的,即一对(A [i],A [j])被认为是反转,即,i <j但是A [i]> A [j]。 O(n log n)
算法用于计算反转次数。
我正在尝试获取反转的数量,但我不知道我的代码有什么问题,我认为sort方法存在问题。
class Q2
{
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
static int merge(int arr[], int l, int m, int r)
{
// Find sizes of two subarrays to be merged
int n1 = m - l + 1;
int n2 = r - m;
int counter =0;
/* Create temp arrays */
int L[] = new int [n1];
int R[] = new int [n2];
/*Copy data to temp arrays*/
for (int i=0; i<n1; ++i)
L[i] = arr[l + i];
for (int j=0; j<n2; ++j)
R[j] = arr[m + 1+ j];
/* Merge the temp arrays */
// Initial indexes of first and second subarrays
int i = 0, j = 0;
// Initial index of merged subarry array
int k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
counter = counter + (m - i);
}
k++;
}
/* Copy remaining elements of L[] if any */
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
/* Copy remaining elements of R[] if any */
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
return counter ;
}
// Main function that sorts arr[l..r] using
// merge()
static int sort(int arr[], int l, int r)
{
int counter=0;
if (l < r)
{
// Find the middle point
int m = (l+r)/2;
// count first and second halves
counter=sort(arr, l, m);
counter+=sort(arr , m+1, r);
// count two halves
counter+= merge(arr, l, m, r);
}
return counter;
}
// Driver method
public static void main(String args[])
{
int arr[] = {2, 4, 1, 3,5};
System.out.println("Number of inversions are " + sort(arr, 0,arr.length-1 ) );
}
}
答案
你的方法有一个根本的缺陷。该
counter = counter + (m - i)
假设m之前的所有元素都小于R中的值,这是不正确的。请记住,m之前的数组的大部分可能已经被排序。
counter = counter + (m - l - i)
可能更正确,但在这种情况下你可能仍然计算两倍。请注意,当它们不在原始数组中的原始位置时,请对它们进行计数。
另一答案
你必须更换
counter = counter + (m - i)
同
counter = counter + (n1 - i)
示意图:假设左数组L的数字为1,6,8,9,右数组为数字4,5,7。下面显示了单个递归步骤的循环迭代:
通常,您可以通过以不同顺序执行反转来对数组进行排序。但是,排序所需的最小反转次数是明确的,因此与该顺序无关。由于该算法使用这些替代序列中的一个,因此它提供了明确的最小倒数。这意味着特别是没有反转计数两次或省略。
该算法为您的数组{2,4,1,3,5}提供了最少3个反转次数:(4,1),(4,3)和(2,1)。
以上是关于我无法在合并排序中使用java获得反转次数的主要内容,如果未能解决你的问题,请参考以下文章