【问题标题】:What's the difference between quicksort and mergesort?快速排序和归并排序有什么区别?
【发布时间】:2011-04-19 10:12:08
【问题描述】:

我是否正确地说,在这两种算法中,您所做的只是获取您的结构,递归地将其分成两部分,然后以正确的顺序构建您的结构?

那么,有什么区别呢?

编辑:我找到了以下用于在快速排序中实现分区的算法,但我不太明白它是如何工作的,特别是使用 (hi + low) >>> 1 作为参数的 swop 行!任何人都可以理解这一点吗?

private static int partition( int[] items, int lo, int hi ) 
{
    int destination = lo;
    swop( items, (hi + lo) >>> 1, hi );
    // The pivot is now stored in items[ hi ].
    for (int index = lo; index != hi; index ++) 
    {
        if (items[ hi ] >= items[ index ]) 
        {
            // Move current item to start.
            swop( items, destination, index );
            destination ++;
        }

        // items[ i ] <= items[ hi ] if lo <= i < destination.
        // items[ i ] > items[ hi ] if destination <= i <= index.
    }

    // items[ i ] <= items[ hi ] if lo <= i < destination.
    // items[ i ] > items[ hi ] if destination <= i < hi.
    swop( items, destination, hi );
    // items[ i ] <= items[ destination ] if lo <= i <= destination.
    // items[ i ] > items[ destination ] if destination < i <= hi.
    return destination;
}

【问题讨论】:

    标签: sorting quicksort mergesort


    【解决方案1】:

    我是否正确地说,在这两种算法中,您所做的只是获取您的结构,递归地将其分成两部分,然后以正确的顺序构建您的结构?

    是的。然而,不同之处在于结构何时以正确的顺序构建。在 Quicksort 中,实际的排序步骤是在拆分期间完成的(将元素移动到左半部分或右半部分,取决于与枢轴元素的比较)并且没有合并步骤来备份树(从数据点观察到观点;你的实现当然可能有堆栈展开),而在 Mergesort 中,排序是在向上的过程中完成的——拆分步骤根本不移动元素,但在返回的过程中,你需要合并两个排序的列表.

    关于性能比较:Quicksort 的最坏情况行为确实比 Mergsesort 更差,但平均情况的常数因子(几乎完全在实践中观察到)更小,这使得快速排序通常是通用、未排序输入的赢家。并不是很多人需要自己实现通用的排序例程……

    【讨论】:

      【解决方案2】:

      在最坏的情况下,快速排序将有 O(n^2),而合并排序将是 O(n*log n)

      快速排序使用枢轴并以枢轴作为参考点对两个部分进行排序,存在枢轴将是排序数组的最大值或最小值的风险。如果您将选择 错误 枢轴,您最终会得到 n^2 复杂度(n^2 比较)

      命名的合并排序是基于递归地将数组分成相同大小的两半并将它们合并回来。例如,wikipedia 上的解释非常好。尤其是带有树状刹车的图片似乎很好地解释了这一点。

      【讨论】:

        【解决方案3】:

        Quicksort 有一个最坏的情况,虽然 Mergesort 始终保证 O(n log n),但在实践中典型的 Quicksort 实现比 Mergesort 更快。

        此外,Mergesort 需要额外的存储空间,这在很多情况下都是一个问题(例如库例程)。这就是库例程几乎总是使用快速排序的原因。

        编辑:我发现了以下内容 算法实现 快速排序中的分区,但我没有 真正了解它的工作原理,, 特别是使用的swop线 (hi + low) >>> 1 作为参数!

        这是取 hi 和 low 的平均值,等于 (hi + low) / 2。

        【讨论】:

          【解决方案4】:

          底层数据结构的实现细节也是一个因素,例如有效的随机访问(快速排序需要),数据结构的可变性会影响内存需求(尤其是合并排序)

          【讨论】:

            【解决方案5】:

            是的,Quicksort 和 Mergesort 都是 divide-and-conquer algorithms

            Wikipedia's Quicksort page有一个简单的对比:

            快速排序还与 归并排序,另一种递归排序 算法,但受益于 最坏情况 O(n log n) 运行时间。 归并排序是一种稳定的排序,不像 快速排序和堆排序,并且可以是 很容易适应在链接上操作 列表和非常大的列表存储在 访问速度慢的媒体,例如磁盘 存储或网络附加存储。 虽然可以将快速排序写入 对链表进行操作,它通常会 遭受糟糕的支点选择 随机访问。主要缺点 归并排序的特点是,在操作时 在数组上,它需要 O(n) 辅助 空间在最好的情况下,而 就地快速排序的变体 分区和尾递归使用 只有 O(log n) 空间。 (请注意,当 对链表进行操作,归并排序 只需要少量恒定的量 辅助存储。)

            【讨论】:

              【解决方案6】:

              http://en.wikipedia.org/wiki/Sorting_algorithm 您可以快速了解常见的排序算法。快速排序和合并排序是前两个;)

              有关详细信息,请阅读有关每种算法的信息。 正如 Jan 所说,Mergesort 的复杂度总是 O(n * log n),而 Quicksort 在最坏的情况下达到 O(n^2)

              【讨论】:

                猜你喜欢
                • 2010-12-06
                • 2020-04-22
                • 2021-11-28
                • 2013-06-18
                • 1970-01-01
                • 2012-02-24
                • 2011-01-13
                • 1970-01-01
                • 2020-08-14
                相关资源
                最近更新 更多