Неправильные инверсии и повторяющиеся числа в реализации MergeSort в Java

Я создаю программу Java, в которой реализую алгоритм MergeSort. Мой код следующий (пока):

public void merge(Integer [] left, Integer[] right, Integer[] a) {

    int i = 0;                  // a[] index (A)
    int lIndex = 0;             // left[] index (B)
    int rIndex = 0;             // right[] index (C)

    // Begin main merge process
    while((lIndex < left.length) && (rIndex < right.length)) {
        if(left[lIndex] <= right[rIndex]) {
            a[i] = left[lIndex]; // Store it
            lIndex++; // Increase index of left[]
        }
        else {
            a[i] = right[rIndex]; // Store it
            rIndex++; // Increase index of right[]
        }
        i++; // Increase index of a[]
    }
    if(i == lIndex) { // If the left array is sorted
        while(rIndex < right.length) { // Copy the contents of rhe right array to a[]
            a[i] = right[rIndex];
            i++;
            rIndex++;
        }
    }
    else { // If the right array is sorted
        while(lIndex < left.length) { // Copy the contents of the left array to a[]
            a[i] = left[lIndex];
            i++;
            lIndex++;
        }
    }
}

Проблема в том, что каждый раз, когда я выполняю функцию, входной массив возвращается частично отсортированным. Я имею в виду, что большинство элементов находятся на своем правильном месте, но есть один или два, которые расположены неправильно, а также пара других, которые являются дубликатами других элементов! Поскольку я не вижу, в чем на самом деле проблема, может ли кто-нибудь помочь мне? Реализация представляет собой мини-проект для урока, и я не могу использовать int[ ] (допустим) вместо Integer[ ], чтобы скопировать содержимое массива A[ ] методом Arrays.copyOf(). Заранее спасибо и прошу простить мои синтаксические/орфографические ошибки.

Обратите внимание, что входной массив всегда является степенью 2 (2, 4, 8, 16 и т. д.), поэтому каждый раз, когда я делю на 2, чтобы найти индекс среднего элемента, я всегда получаю четное число.


person Lefteris008    schedule 31.03.2013    source источник


Ответы (2)


Насколько я могу судить, проблема в вашем методе слияния, здесь:

if (i == lIndex) { // If the left array is sorted ...

i не обязательно равно lIndex при сортировке левого массива. В результате финальная часть слияния не всегда выполняется. Повторяющиеся элементы, которые вы видите, остались от исходного массива A в позициях, которые из-за этого не были перезаписаны.

Правильное условие:

if (lIndex == left.length) { // If the left array is sorted ...
person Octahedron    schedule 31.03.2013
comment
Большое спасибо, это решило проблему! Оказалось непонимание псевдокода MergeSort, который я изучал по книге. - person Lefteris008; 31.03.2013

Я думаю, что ваша проблема здесь:

if(i == lIndex)

Способ проверить, закончились ли у вас элементы в списке, таков:

if (lIndex == left.length)

Другими словами, если вы возьмете некоторые элементы слева, а некоторые справа, даже если вы сначала исчерпаете левый массив, i НЕ будет равно lIndex, когда вы исчерпаете левый массив. Это будет больше.

person Jimmy Lee    schedule 31.03.2013
comment
Большое спасибо за ваш ответ. Как я писал в Ephemerality, оказалось непонимание псевдокода MergeSort, который я изучил по книге. - person Lefteris008; 31.03.2013