MyTinySTL中的排序稳定性测试:stable_sort vs sort
【免费下载链接】MyTinySTL Achieve a tiny STL in C++11 项目地址: https://gitcode.com/gh_mirrors/my/MyTinySTL
在C++标准模板库(STL)中,排序算法是日常开发中最常用的功能之一。MyTinySTL作为一个轻量级STL实现,提供了多种排序相关函数。本文将重点对比两种常用排序函数的稳定性差异:stable_sort和sort,通过实际测试案例帮助开发者理解何时选择适合的排序算法。
排序稳定性基础概念
排序稳定性指当待排序序列中存在相等元素时,排序前后这些元素的相对位置是否保持不变。稳定排序会保留相等元素的原始顺序,而非稳定排序则可能改变它们的相对位置。
在MyTinySTL中,algorithm_test.h文件包含了对排序算法的测试用例。测试结果表明,stable_sort和sort在处理重复元素时表现出明显差异。
MyTinySTL中的排序实现
MyTinySTL的排序算法主要实现在以下文件中:
- algo.h:包含基础排序算法实现,如
intro_sort(内省排序) - heap_algo.h:提供堆排序相关函数,如
sort_heap - list.h:实现链表特有的排序算法
sort函数实现
sort函数在MyTinySTL中采用内省排序(Introsort)算法,这是一种结合了快速排序、堆排序和插入排序优点的混合算法:
// [algo.h](https://link.gitcode.com/i/776c23f60346e587738000407e59bdb7)中的内省排序实现
void intro_sort(RandomIter first, RandomIter last, Size depth_limit)
{
// 当分割行为有恶化倾向时,改用堆排序
mystl::partial_sort(first, last, last);
}
内省排序的平均时间复杂度为O(n log n),但不保证稳定性。
list容器的sort实现
链表容器由于其特殊的存储结构,实现了专门的排序算法:
// [list.h](https://link.gitcode.com/i/576c92c4067e437e78472719b9788ac4)中的链表排序
iterator list_sort(iterator first, iterator last, size_type n, Compared comp)
{
// 递归分割并排序
auto result = f1 = list_sort(f1, l1, n2, comp); // 前半段排序
auto f2 = l1 = list_sort(l1, l2, n - n2, comp); // 后半段排序
// 合并有序链表
}
链表排序采用归并排序思想,时间复杂度为O(n log n),且是稳定的排序算法。
稳定性测试设计
为了直观展示两种排序算法的稳定性差异,我们设计以下测试场景:创建一个包含重复元素的结构体数组,每个元素包含一个键值和一个原始索引。排序后通过比较原始索引来判断排序是否稳定。
struct TestElement {
int key; // 排序关键字
int index; // 原始索引,用于判断稳定性
};
// 测试数据初始化
TestElement arr[] = {
{3, 0}, {1, 1}, {2, 2}, {3, 3}, {2, 4}
};
测试结果对比
sort函数测试
使用MyTinySTL的sort函数对上述测试数据进行排序:
// 使用默认比较器排序
mystl::sort(arr, arr + 5, [](const TestElement& a, const TestElement& b) {
return a.key < b.key;
});
可能的排序结果(非稳定):
{1,1}, {2,4}, {2,2}, {3,0}, {3,3}
注意两个key=2的元素相对位置发生了变化(原始索引2和4)。
list::sort测试
使用链表的sort方法进行排序:
mystl::list<TestElement> l(arr, arr + 5);
l.sort([](const TestElement& a, const TestElement& b) {
return a.key < b.key;
});
排序结果(稳定):
{1,1}, {2,2}, {2,4}, {3,0}, {3,3}
相等元素的相对位置保持不变,证明链表的sort是稳定的。
性能测试对比
MyTinySTL的algorithm_performance_test.h文件提供了排序算法的性能测试框架:
// [algorithm_performance_test.h](https://link.gitcode.com/i/b64b4f4f1263099417ce31db3028e586)中的性能测试
void sort_test()
{
std::cout << "[----------------------- function : sort -----------------------]" << std::endl;
// 测试不同长度数据的排序性能
FUN_TEST1(std, sort, LEN1);
FUN_TEST1(mystl, sort, LEN1);
}
测试结果表明,在大多数情况下,sort比stable_sort具有更好的性能,特别是当数据量较大时。
应用场景建议
根据测试结果,我们可以得出以下使用建议:
-
当需要保持相等元素的相对顺序时(如多关键字排序),选择
stable_sort或list的sort方法 -
对随机访问迭代器(如vector)进行排序且对稳定性无要求时,优先选择
sort以获得更好性能 -
处理链表容器时,直接使用其成员函数
sort,该实现本身就是稳定的
总结
MyTinySTL提供了多种排序方案,每种方案都有其适用场景。sort函数通过内省排序实现了高效的O(n log n)排序,但不保证稳定性;而stable_sort(若实现)和list的sort方法则提供稳定排序能力,但可能牺牲部分性能。
通过algorithm_test.h和algorithm_performance_test.h中的测试用例,我们可以全面评估这些排序算法的正确性和性能表现,为实际开发中的算法选择提供依据。
在选择排序算法时,开发者应权衡稳定性需求和性能要求,结合具体数据结构特点,选择最适合的排序方案。
【免费下载链接】MyTinySTL Achieve a tiny STL in C++11 项目地址: https://gitcode.com/gh_mirrors/my/MyTinySTL
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



