Мне нужна помощь в устранении неполадок моего кода для MergeSort и Merge - PullRequest
2 голосов
/ 30 марта 2019

Итак, я работал над MergeSort для проекта Algorithm, но столкнулся с различными проблемами, когда речь шла о получении кода для сортировки массивов.Всякий раз, когда я генерирую строку и помещаю ее в MergeSort, кажется, что она получается одинаковой.Мне нужна помощь в поиске, где ошибка в моем коде, почему он дает мне это, и решение с простым, но хорошим объяснением.

Вот что я пробовал в прошлом:

  1. Я пытался использовать return arr[0] вместо arr, но выдает ошибку из-за невозможности конвертировать из int в int[].
  2. Я посмотрел в своем классе слияния, и там, кажется, все в порядке.
  3. Я обсуждал эту проблему с моим учителем, и он говорит, что все выглядит хорошо, но я знаю, что где-то что-то не так.
  4. Я пытался удалить return merge(arr1, arr2), но система выдает ошибку, сообщающую, что я должен что-то вернуть.
  5. Я пытался распечатать массивы по отдельности, но все равно показываетбез изменений и является точно такой же, как и исходная строка.

Метод слияния:

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:

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);
}

Поскольку массив случайныйсгенерированный, пример будет следующим:

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

ЦельРезультат должен выглядеть следующим образом:

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

Однако, это то, что вместо этого выводится (массив получается без изменений):

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

Ответы [ 3 ]

0 голосов
/ 30 марта 2019

Единственная проблема, которую я вижу в коде, это return arr[0]; вместо return arr; или return new int[]{arr[0]}; в mergeSort.

Кроме того, код работает, как и ожидалось.

Если вы не видите правильный вывод, вы, вероятно, неправильно используете вывод.

Вот пример того, как я его протестировал.

    public static void main(String[] args) {

        int[] input = new int[]{9, 1, 7, 5, 7, 2, 2, 9, 8, 9};
        int[] output = mergeSort(input);
    }
0 голосов
/ 06 апреля 2019

В вашем коде 2 проблемы:

  • вы возвращаете элемент массива arr[0] вместо самого массива arr
  • вы не обрабатываете случай arr.length == 0. Он также должен вернуть arr.

Обратите внимание, что код можно упростить:

  • Вы можете использовать оператор ++ для значений индекса при копировании значений,
  • Вы должны удалить лишние тесты во втором и третьем циклах while.

Вот улучшенная версия:

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);
}
0 голосов
/ 30 марта 2019

Ваш код не компилируется как написано.В mergeSort, если длина массива равна 1, она должна return arr.После этого изменения ваш код работает нормально.

Однако мы можем внести несколько небольших изменений в ваш код, чтобы он стал чище.Обратите внимание, что для вашего последнего цикла while в merge проверка counterA == a.length всегда будет истинной.Поэтому мы можем удалить это.Кроме того, увеличивающиеся счетчики могут быть сделаны, обращаясь к массиву.Объединение этих предложений приводит к следующему коду для вашего merge метода:

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;
}
...