Проблемы сортировки слиянием

1

Итак, немного фона:

Наш учитель в основном сел и сделал базовую реализацию SQL на Java, можно сказать. Он сказал нам попробовать сделать реализацию алгоритма Merge-Algorithm в этой системе, которую он создал.

Я пытаюсь выполнить Merge-Sort (сверху вниз), но у меня есть несколько вопросов.

Предполагается, что Merge-Sort принимает две таблицы (имитируемые из сделанной им реализации базы данных) и упорядочивает их так, чтобы они отображались от наименьшего до самого высокого в порядке возрастания (1-8).

Код позволяет мне использовать DbIterator, который наш учитель написал, чтобы перебирать таблицу и ее содержимое. Таким образом, у нас есть две таблицы, которые имеют следующие данные:

[hello1, 5]
[hello2, 6]
[hello3, 7]
[hello4, 8]

И другая таблица:

[goodbye4, 4]
[goodbye2, 2]
[goodbye3, 3]
[goodbye1, 1]

После сортировки слияния он должен распечатать это:

[goodbye1, 1]
[goodbye2, 2]
[goodbye3, 3]
[goodbye4, 4]
[hello1, 5]
[hello2, 6]
[hello3, 7]
[hello4, 8]

Но это то, что он печатает:

null
[hello1, 5]
[hello2, 6]
[hello3, 7]

Я немного озадачен этим и попытался отладить, чтобы понять, что пойдет не так, но я, возможно, пробовал так много, что я стал слепым к реальной проблеме. Итак, вот код (сортировка происходит по последним трем методам):

public String[] MergeSort(String table1, String table2) {
    DbIterator scannerA = getTableScanner(table1);
    DbIterator scannerB = getTableScanner(table2);
    HashMap<Integer, String> records = new HashMap<>();
    ArrayList<Integer> A = new ArrayList<>();
    ArrayList<Integer> B = new ArrayList<>();
    int n = 0;
    scannerA.open();
    while(scannerA.hasNext()) {
        Record r = scannerA.next();
        StringField sF = (StringField) r.getField(0);
        IntegerField iF = (IntegerField) r.getField(1);
        records.put(iF.hashCode(), sF.toString());
        A.add(iF.hashCode());
        n++;
    }
    scannerA.close();

    scannerB.open();
    while(scannerB.hasNext()) {
        Record r = scannerB.next();
        StringField sF = (StringField) r.getField(0);
        IntegerField iF = (IntegerField) r.getField(1);
        records.put(iF.hashCode(), sF.toString());
        B.add(iF.hashCode());
        n++;
    }
    scannerB.close();

    int[] mergeResult;
    int[] aA = convertIntegers(A);
    int[] bB = convertIntegers(B);
    mergeResult = TopDownSplitMerge(aA, 0, n, bB);
    String[] results = new String[mergeResult.length];
    for(int v = 0; v < mergeResult.length; v++) {
        if(records.containsKey(v)) {
            results[v] = "[" + records.get(v) + ", " + v +"]";
        }
    }

    return results;
}

private int[] CopyArray(int[] B, int iBegin, int iEnd, int[] A) {
    for(int k = iBegin; k < iEnd; k++)
        A[k] = B[k];
    return A;
}

private int[] TopDownSplitMerge(int[]A,int iBegin, int iEnd, int[]B) {
    if(iEnd - iBegin < 2) {
        return null;
    }
    int iMiddle = (iEnd + iBegin) / 2;
    TopDownSplitMerge(A, iBegin, iMiddle, B);
    TopDownSplitMerge(A, iMiddle, iEnd, B);
    TopDownMerge(A, iBegin, iMiddle, iEnd, B);
    int[] tmp = CopyArray(B, iBegin, iEnd, A);
    return tmp;
}

public void TopDownMerge(int[] A, int iBegin, int iMiddle, int iEnd, int[] B) {
    int i0 = iBegin;
    int i1 = iMiddle;

    for(int j = iBegin; j < iEnd; j++) {
        if(i0 < iMiddle && (i1 >= iEnd || A[i0] <= A[i1])) {
            B[j] = A[i0++];
        } else {
            B[j] = A[i1++];
        }
    }
}

Прежде всего, это не мой личный алгоритм, а я пытаюсь реализовать его из вики. Единственная часть, которую я не могу понять, которая может решить всю проблему вместе, - это то, что они называют "iEnd". Значение n. Я не могу понять, как вычислить это или какое значение дать. Возможно, проблема в целом.

Теги:
mergesort

1 ответ

0
Лучший ответ

Чтение TopDownMerge - объединяет элементы из двух отсортированных частей массива A в соответствующую часть B, затем CopyArray копирует объединенные данные обратно в A Таким образом, B - это всего лишь временный буфер для объединения данных, а не источник данных. Вы не должны вызывать TopDownSplitMerge с двумя массивами ввода aA и bB а скорее конкатенировать их в один массив и использовать этот массив как параметр A (а другой массив - как буфер B).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню