简体   繁体   中英

I need help troubleshooting my code for MergeSort and Merge

So I've been working on MergeSort for an Algorithm project, but I've ran into various problems when it comes to getting the code to sort the arrays. Whenever I generate a string and put it into MergeSort, it seems to just come out exactly the same. I want some help in finding where the mistake in my code is, why is it giving me this, and a solution with a simple, but good explanation.

Here's what I've tried in the past:

  1. I've tried to use return arr[0] instead of arr , but it throws me an error with it being unable to convert from int to int[] .
  2. I've looked in my merge class and everything seems to be ok there.
  3. I've discussed the issue with my teacher and he says that everything looks fine, but I know that there must be something wrong somewhere.
  4. I've tried to remove return merge(arr1, arr2) but the system throws an error telling me I have to return something.
  5. I've tried to print out the arrays individually, but it still shows no changes and is the exact same as the original string.

Merge method:

private static int[] merge(int[] a, int[] b)
{
    int[] c = new int[a.length + b.length];
    int counterA = 0;
    int counterB = 0;
    int counterC = 0;

    while (counterA != a.length && counterB != b.length)
    {
      if (a[counterA] < b[counterB])
      {
        c[counterC] = a[counterA];
        counterA++;
        counterC++;
      }
      else
      {
        c[counterC] = b[counterB];
        counterB++;
        counterC++;
      }
    }

    while (counterB == b.length && counterA != a.length)
    {
      c[counterC] = a[counterA];
      counterA++;
      counterC++;
    }

    while (counterA == a.length && counterB != b.length)
    {
      c[counterC] = b[counterB];
      counterB++;
      counterC++;
    }

    return c;
}

MergeSort method:

public static int[] mergeSort(int[] arr)
{ 
    if (arr.length == 1)
    {
      return arr[0];
    }

    int[] arr1 = new int[arr.length / 2];
    int[] arr2 = new int[arr.length - arr1.length];

    for (int i = 0; i < arr1.length; i++)
    {
      arr1[i] = arr[i];
    }

    for (int i = 0; i < arr2.length; i++)
    {
      arr2[i] = arr[i + arr1.length];
    }

    arr1 = mergeSort(arr1);
    arr2 = mergeSort(arr2);

    return merge(arr1, arr2);
}

Because the array is randomly generated, an example would be this:

9, 1, 7, 5, 7, 2, 2, 9, 8, 9

The intended result should be this:

1, 2, 2, 5, 7, 7, 8, 9, 9, 9

However, this is what the output is instead (The array comes out unchanged):

9, 1, 7, 5, 7, 2, 2, 9, 8, 9 

Your code doesn't compile as written. In mergeSort , if the array length is equal to 1, it should return arr . After this change, your code works fine.

We can, however, make a few small changes to your code to make it cleaner. Notice that for your last while loop in merge , the check counterA == a.length will always be true. Therefore, we can remove it. Also, incrementing counters can be done while accessing the array. Combining these suggestions results in the following code for your merge method:

private static int[] merge(int[] a, int[] b)
{
    int[] c = new int[a.length + b.length];
    int counterA = 0;
    int counterB = 0;
    int counterC = 0;

    while(counterA != a.length && counterB != b.length)
    {
        if(a[counterA] < b[counterB])
            c[counterC++] = a[counterA++];
        else
            c[counterC++] = b[counterB++];
    }

    while(counterB == b.length && counterA != a.length)
        c[counterC++] = a[counterA++];

    while(counterB != b.length)
        c[counterC++] = b[counterB++];

    return c;
}

The only problem I see in the code is the return arr[0]; instead of return arr; or return new int[]{arr[0]}; in mergeSort.

Aside from that the code works as expected.

If you are not seeing the correct output, you probably aren't using the output correctly.

Here is an example of how I tested it.

    public static void main(String[] args) {

        int[] input = new int[]{9, 1, 7, 5, 7, 2, 2, 9, 8, 9};
        int[] output = mergeSort(input);
    }

There are 2 problems in your code:

  • you return an array element arr[0] instead of the array itself arr
  • you do not handle the case of arr.length == 0 . It should return arr as well.

Note that the code can be simplified:

  • you can use the ++ operator on index values when copying the values,
  • you should remove the redundant tests on the second and third while loops.

Here is an improved version:

private static int[] merge(int[] a, int[] b)
{
    int[] c = new int[a.length + b.length];
    int counterA = 0;
    int counterB = 0;
    int counterC = 0;

    while (counterA != a.length && counterB != b.length)
    {
        if (a[counterA] <= b[counterB])
            c[counterC++] = a[counterA++];
        else
            c[counterC++] = b[counterB++];
    }

    while (counterA != a.length)
        c[counterC++] = a[counterA++];

    while (counterB != b.length)
        c[counterC++] = b[counterB++];

    return c;
}

public static int[] mergeSort(int[] arr)
{ 
    if (arr.length < 2)
        return arr;

    int[] arr1 = new int[arr.length / 2];
    int[] arr2 = new int[arr.length - arr1.length];

    for (int i = 0; i < arr1.length; i++)
        arr1[i] = arr[i];

    for (int i = 0; i < arr2.length; i++)
        arr2[i] = arr[i + arr1.length];

    arr1 = mergeSort(arr1);
    arr2 = mergeSort(arr2);

    return merge(arr1, arr2);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM