Итеративная сортировка слиянием кажется неправильной - выдает корректный вывод - PullRequest
0 голосов
/ 17 октября 2018

Я понимаю, что итеративное merge sort можно найти в Интернете, однако созданная мною реализация, похоже, сильно отличается от примеров, которые я видел в Интернете.

Вот что у меня есть.Я реализовал это итеративно, но думаю, что это не правильно, поскольку это не совсем то, что следует за реализацией recursive.

Рекурсивная реализация splits/sorts одна половина, а затем другая, а затем сливается.Эта реализация разбивает / сортирует весь список, а затем объединяет их один за другим с stack.

Мой вопрос заключается в том, является ли это правильной итеративной реализацией?
Я думаю, мне следует использовать queue вместо stack.

public static List<Integer> iterativeMergeSort(List<Integer> nums){

    Stack<List<Integer>> stack = new Stack<List<Integer>>();

    for (int num : nums) {
        stack.push(new ArrayList<Integer>(Arrays.asList(num)));
    }

    while (stack.size() > 1) {
        List<Integer> a = stack.pop();
        List<Integer> b = stack.pop();
        stack.push(merge(a,b));
    }

    return stack.pop();
}

public static List<Integer> merge(List<Integer> a, List<Integer> b) {

    int i = 0;
    int j = 0;
    List<Integer> merged = new ArrayList<Integer>();

    while (i < a.size() && j < b.size()) {

        if (a.get(i) == b.get(j)) {
            merged.add(a.get(i));
            merged.add(b.get(j));
            i++;
            j++;
        }
        else if (a.get(i) < b.get(j)) {
            merged.add(a.get(i));
            i++;
        }
        else { //a.get(i) > b.get(j)
            merged.add(b.get(j));
            j++;
        }
    }

    while (i < a.size()) {
        merged.add(a.get(i));
        i++;
    }

    while (j < b.size()) {
        merged.add(b.get(j));
        j++;
    }

    return merged;
}

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Итеративная сортировка слиянием обычно идет снизу вверх.Вместо использования повторяющейся рекурсии для разделения массива сортировка по слиянию снизу пропускает этот шаг и обрабатывает массив из n элементов как n прогонов размера 1, и немедленно начинает прогоны слияния.Сортировка сверху вниз объединяет только подпроцессы до тех пор, пока не произведет два подпроцесса размера 1, прежде чем будет выполнено какое-либо объединение, и немного медленнее, поэтому большинство библиотек используют некоторые варианты сортировки по принципу снизу вверх.Статья Wiki включает в себя псевдо-код для сортировки слиянием снизу вверх:

https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation

Шаги копирования назад можно избежать, если вместо копирования поменять местами указатели или ссылки.

0 голосов
/ 17 октября 2018

Эта реализация кажется мне неправильной.Это скорее вставка_сортировки (https://en.wikipedia.org/wiki/Insertion_sort).). Идея сортировки слиянием состоит в том, что вы разбиваете данные на 2 почти четные группы, но эта реализация этого не делает. Ваше 'a' - это, по сути, список ранее отсортированныхelements и 'b' - следующий добавляемый элемент.

...