迭代合并排序似乎不正确-产生有效输出

时间:2018-10-17 16:13:46

标签: java sorting mergesort

我知道可以在网上找到迭代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 :(得分:0)

我觉得这种实现是错误的。这更像是insert_sort(https://en.wikipedia.org/wiki/Insertion_sort)。合并排序的想法是将数据分成两个接近的偶数组,但是此实现并未这样做。您的“ a”基本上是先前排序元素的列表,“ b”是要添加的下一个元素。

答案 1 :(得分:0)

迭代合并排序通常是自下而上的。自下而上的合并排序不使用重复递归来拆分数组,而是跳过该步骤,并将n个元素的数组视为大小为1的n个运行,并立即开始合并运行。自上而下的合并排序仅将子运行拆分,直到在执行任何合并之前生成两个大小为1的子运行为止,并且运行速度稍慢,这就是为什么大多数库使用自下而上的合并排序的一些变体。 Wiki文章包含用于自底向上合并排序的伪代码:

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

可以通过交换指针或引用而不是复制来避免回写步骤。