2

我在这里脱发,试图在 Java 中的合并排序实现中找到错误:

 Input: 10 9 8 7 6 5 4 3 2 1   
Output: 5 4 3 2 1 10 9 8 7 6   

我在合并函数中打印了数组之间的中间值,它给了我这个:

10 9 8 7 6 5 4 3 2 1 
9 10 
6 7 
7 6 8 
8 7 6 10 9 
4 5 
1 2 
2 1 3 
3 2 1 5 4 
5 4 3 2 1 10 9 8 7 6 

我很确定错误一定出在我的合并功能中。但我很难找到它。

这是我的代码:

class merge1 
{
//the array which will get sorted
static int N = 10;
static int[] A = new int[N];

static int[] cropArray(int[] a)
{
    int[] b = new int[a.length-1];
    System.arraycopy(a, 1, b, 0, b.length);
    return b;

}


static int[] merge(int[] left, int[] right)
{
    int[] merged = new int[left.length + right.length];
    int i = 0;

    //loop must go on until both arrays are emptied into merged
    while(left.length > 0 || right.length > 0) 
    {
        //first case: both arrays are still filled with elements to compare
        if(left.length > 0 && right.length > 0) 
        {
            if(left[0] <= right[0]) //check for the bigger one
            {
                merged[i] = left[0];
                left = cropArray(left);
            }
            else
            {
                merged[i] = right[0];
                right = cropArray(right);
            }

        } 
        else //second case: one of the arrays is empty
        {
            if(left.length > 0)
            {
                merged[i] = left[0];
                left = cropArray(left);

            }
            else if(right.length > 0)
            {
                merged[i] = right[0];
                right = cropArray(right);
            }
        }

        i++;
    } //while

    printA(merged, merged.length);
    return merged;
} //merge()

//merg sort recursivly splits the array in half until only one element is left and then merges each half back together in sorted order
static int[] mergeSort(int[] a)
{

    //STEP 1
    //exit case if only one element to sort return this element
    if(a.length <= 1) return a;


    //STEP 2
    // split array into half
    int len = a.length/2;
    int[] left, right;

    //check if length is even, if not even integer division will cause loss of data
    if(a.length % 2 == 0)
    {
        //devide into two even halfs
        left = new int[len];
        right = new int[len];
    } 
    else 
    {
        //devide into two uneven halfs
        left = new int[len];
        right = new int[len+1];
    }

    //cycle through a and save out each half
    //could also use System.arraycopy here as in the merge function
    for(int i = 0; i < left.length; i++)
    {
        left[i] = a[i];
    }

    for(int i = 0; i < right.length; i++)
    {
        right[i] = a[i+len];
    }

    //split each half recursivley until only one element is left
    mergeSort(left);
    mergeSort(right);

    //STEP 3
    //merge sorted halfs and return
    return merge(right, left);

} //mergeSort()


//initalizes the array for the worst case
//the worst case for merge sort is an array sorted in reverse
static void init()
{
    int k = N;

    for(int i = 0; i < A.length; i++)
    {
        A[i] = k;
        k--;
    }

}//init()

//prints the array, used to check if mergeSort is working
static void printA(int[] a, int n)
{
    for(int i = 0; i < n; i++)
    {
        System.out.print(a[i] + " ");
    }
    System.out.println(); //break

} //printA

public static void main(String[] args)
{

    //test code
    init();
    printA(A,A.length);
    int [] sorted = mergeSort(A);
    //printA(sorted, sorted.length);

    /*//does 2000 sorts with arrays going from 0 to 1999 elements
    for(int i = 0; i < 2000; i++)
    {
        init();
        long x = System.nanoTime();
        mergeSort(A, i);
        System.out.println(i + " " + (System.nanoTime() - x));
    }*/

} //main()

}//merge1
4

2 回答 2

0

我将在这里为 merge() 函数编写一些伪代码

merge(int[] left, int[] right)
{
    int l = 0;
    int r = 0;

    int[] merged = new int[left.lentgh+right.length];

    for(int i=0; i<merged.length; i++)
    {
        // this condition is dependant of the fact that merged.length is equal to the sum of left.length and right.length
        if(r >= right[r].length || (l < left.length && left[l] < right[r]))
        {
            merged[i] = left[l];
            l++;
        }
        else
        {
            merged[r] = right[r];
            r++;
        }
    }   
    return merged
}
于 2012-10-16T21:01:41.803 回答
0

你没有重新分配rightleft在你的电话中mergeSort(),所以实际的“排序”并没有携带链条:

代替

mergeSort(left);
mergeSort(right);

你要

left = mergeSort(left);
right = mergeSort(right);
于 2012-10-16T21:19:35.247 回答