内置 qsort 函数和稳定排序函数有啥区别?
Posted
技术标签:
【中文标题】内置 qsort 函数和稳定排序函数有啥区别?【英文标题】:What is the difference between inbuilt qsort function and stable sort function?内置 qsort 函数和稳定排序函数有什么区别? 【发布时间】:2015-12-18 02:17:32 【问题描述】:从引用的各种来源中,我知道内置的 C 函数 stable_sort 是稳定的,但 qsort 是不稳定的。如果是这样,我们为什么要使用 qsort 呢?这不是多余的吗?为什么不使用 stable_sort 呢?
【问题讨论】:
stable_sort
仅适用于 C++。它不是当前 C 标准的一部分。
【参考方案1】:
稳定的排序意味着保持相等元素的顺序。这并不总是必需的。
如果不需要,算法更简单,有时更快和/或更节省内存。 稳定排序算法的一个典型例子是merge sort。
【讨论】:
【参考方案2】:选择快速排序而不是稳定排序的原因主要是速度:qsort
通常比stable_sort
快,这不足为奇,因为stable_sort
具有更强的保证。
O(N·log2(N))。如果有额外的内存可用,那么复杂度是 O(N·log(N))。
空间是另一个考虑因素:qsort
已就地完成,这意味着不需要额外的内存分配。另一方面,stable_sort
尝试临时分配大小等于正在排序的数组。
此函数尝试分配一个大小与要排序的序列相同的临时缓冲区。如果分配失败,则选择效率较低的算法。
rcgldr 的评论注解:(std::stable_sort
的 HP/Microsoft 实现使用了 1/2 大小的序列的临时缓冲区。后半部分排序到后半部分序列的一半,前半部分进入临时缓冲区,然后临时缓冲区和序列的后半部分合并回序列中。
【讨论】:
HP/Microsoft 的 std::stable_sort 实现使用了一个 1/2 序列大小的临时缓冲区。后半部分排序到序列的后半部分,前半部分进入临时缓冲区,然后临时缓冲区和序列的后半部分合并回序列中。 @rcgldr 他们太聪明了!感谢您的注意,我将其复制到答案中。 HP / Microsoft std::stable_sort 先排序前半部分,然后是后半部分,然后完成一半复制到临时缓冲区,最后合并完成(看起来有代码可选地进行向后合并(从最后一个到第一个),不确定这是使用还是遗留代码)。我在回忆一个优化版本,它避免了额外的复制步骤。关键思想仍然是使用序列大小为 1/2 的临时缓冲区。【参考方案3】:如果是这样,我们为什么还要使用 qsort?
stable_sort()
不是标准 C 的一部分。qsort()
是标准 C 的一部分。
C 的qsort()
没有指定使用快速排序算法,也不需要稳定也不需要不稳定。
qsort()
经常被使用,因为它是最便携的。由于qsort()
没有关于速度、内存效率和数据稳定性的规范,因此通常使用目标平台的实用方法对其进行编码。在嵌入式平台上,内存空间通常比速度更重要。在台式机上,速度可能是最重要的。
【讨论】:
以上是关于内置 qsort 函数和稳定排序函数有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章