合并排序实现以计算数组的反转

时间:2012-06-22 23:48:47

标签: java mergesort

下面是我对数组反转的实现。对于某些输入,它会产生所需的结果。例如:

1:0,1,2,3,4,5,6,7,8,9 - > 0反转(正确)

2:1000,999,998,997,....... 3,2,1 - > 499500倒置(正确)

3:1,3,5,2,4,6 - > 3倒置(正确)

但是

4:9,10,8,1,4,7,6,2,5,3 - > 41倒置(不正确)。正确答案是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]);
    }  
    }
}

2 个答案:

答案 0 :(得分:1)

您的解决方案不正确,因为它未将已排序的数组传递到征服 功能

以下是我使用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]));
            }
        }
    }
}

答案 1 :(得分:0)

你的答案中的问题(我认为是正确的)如下:

countMerge = conquer(leftArr, rightArr, result);

你只是在未排序的数组(leftArr,rightArr)上征服了部分,这就是反转次数不同的原因。我将此代码更改为如下所示:

Arrays.sort(leftArr);
Arrays.sort(rightArr);
countMerge = conquer(leftArr, rightArr, result);