Reputation: 2725
Below is my implementation for Inversion of an array. For some inputs it produces the required result. For eg :
1 : 0,1,2,3,4,5,6,7,8,9 -> 0 inversion (Correct)
2 : 1000,999,998,997,.......3,2,1 -> 499500 inversion (Correct)
3 : 1,3,5,2,4,6 -> 3 inversion (Correct)
But for
4 : 9,10,8,1,4,7,6,2,5,3 -> 41 inversion (Incorrect). The correct answer is 33.
public class Assignment1 {
static int[] result = new int[10];
public static long divideW (int Arr[]) {
long countLeft ;
long countRight ;
long countMerge ;
int mid = (Arr.length)/2;
if (Arr.length <= 1)
return 0;
else
{
int leftArr[] = new int [mid];
int rightArr[] = new int [Arr.length - mid];
for (int i = 0; i < mid; i++){
leftArr[i] = Arr[i];
}
for (int j = 0; j < rightArr.length ; j++){
rightArr[j] = Arr[mid + j];
}
countLeft = divideW (leftArr);
countRight = divideW (rightArr);
//int[] result = new int[Arr.length];
countMerge = conquer(leftArr, rightArr, result);
return (countLeft + countRight + countMerge);
}
}
public static long conquer (int []l, int[]r, int[] result) {
int i = 0;
int j = 0;
int k = 0;
long count = 0;
while ((i < l.length) && (j < r.length)) {
if (l[i] <= r [j]) {
result[k] = l[i++];
}
else if (l[i] > r[j]) {
result[k] = r[j++];
count += l.length - i;
}
++k;
}
while ( i < l.length) {
result[k++] = l[i++];
}
while ( j < r.length) {
result[k++] = r[j++];
}
return count;
}
public static void main(String[] args) {
Assignment1 rs = new Assignment1();
int anArr[] = {9,10,8,1,4,7,6,2,5,3};
System.out.println (rs.divideW(anArr));
for (int i = 0 ; i < result.length; ++i) {
System.out.println (result[i]);
}
}
}
Upvotes: 0
Views: 2682
Reputation: 1343
Your solution is not correct because it does not pass the sorted array into the conquer function
Below is the code I have implemented using C#.
using System;
namespace SortingAlgos
{
public class InversionCountUsingMergeSort
{
public static long InversionCount { get; set; }
public static void Main(string[] args)
{
//Load an array
int[] arrayInts = { 9, 10, 8, 1, 4, 7, 6, 2, 5, 3 };// { 10, 4, 7, 8, 6, 2, 3, 5 };//{1,3,5,2,4,6}--->3;//{ 9, 10, 8, 1, 4, 7, 6, 2, 5, 3 }-->41;//{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }--->0;//{ 10, 4, 7, 8, 6, 2, 3, 5 }; //LoadInts();
Console.WriteLine("========= UnSorted Array Items ==========");
//Print an unsorted array
PrintInts(arrayInts);
Console.WriteLine("========== Inversion Count =========");
//Sort the array
arrayInts = MergeSort(arrayInts);
//Print Sorted array
PrintInts(arrayInts);
Console.WriteLine(InversionCount);
Console.ReadKey();
}
private static int[] MergeSort(int[] arrayInts)
{
if (arrayInts.Length <= 1)
{
return arrayInts;
}
else
{
int[] result = new int[arrayInts.Length];
int midPoint = arrayInts.Length / 2;
int[] leftArray = new int[midPoint];
int[] rightArray;
if (arrayInts.Length % 2 == 0)
{
rightArray = new int[midPoint];
}
else
{
rightArray = new int[midPoint + 1];
}
for (int indexLeft = 0; indexLeft < midPoint; indexLeft++)
{
leftArray[indexLeft] = arrayInts[indexLeft];
}
int indexRight = 0;
for (int indexOnArryInts = midPoint; indexOnArryInts < arrayInts.Length; indexOnArryInts++)
{
if (indexRight < rightArray.Length)
{
rightArray[indexRight] = arrayInts[indexOnArryInts];
indexRight++;
}
}
leftArray = MergeSort(leftArray);
rightArray = MergeSort(rightArray);
return MergeArrays(leftArray, rightArray);
}
}
private static int[] MergeArrays(int[] leftArray, int[] rightArray)
{
int arraySize = leftArray.Length + rightArray.Length;
int[] arrayFinal = new int[arraySize];
int leftIndex = 0, rightIndex = 0;
for (int index = 0; index < arraySize; index++)
{
if (leftIndex < leftArray.Length && rightIndex < rightArray.Length)
{
if (leftArray[leftIndex] <= rightArray[rightIndex])
{
arrayFinal[index] = leftArray[leftIndex];
leftIndex++;
}
else if (leftArray[leftIndex] > rightArray[rightIndex])
{
arrayFinal[index] = rightArray[rightIndex];
rightIndex++;
InversionCount += leftArray.Length - leftIndex;
}
}
else if (leftIndex < leftArray.Length)
{
arrayFinal[index] = leftArray[leftIndex];
leftIndex++;
}
else if (rightIndex < rightArray.Length)
{
arrayFinal[index] = rightArray[rightIndex];
rightIndex++;
}
}
return arrayFinal;
}
private static void PrintInts(int[] arrayInts)
{
for (int index = 0; index < arrayInts.Length; index++)
{
Console.WriteLine(string.Format("{0}", arrayInts[index]));
}
}
}
}
Upvotes: 1
Reputation: 10789
The problem in your answer (I assume it is correct) the following:
countMerge = conquer(leftArr, rightArr, result);
You just do conquer part on unsorted arrays (leftArr, rightArr) that's why the number of inversions different. I changed this code as below and it works:
Arrays.sort(leftArr);
Arrays.sort(rightArr);
countMerge = conquer(leftArr, rightArr, result);
Upvotes: 0