内置 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 函数和稳定排序函数有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

qsort函数sort函数 (精心整理篇)(转载)

qsort 使用啥排序算法?

C语言之qsort函数进行排序

qsort库函数排序

c语言重要库函数解读 和模拟实现————Qsort

qsort函数实现对任意数据的排序