MyTinySTL中的排序稳定性测试:stable_sort vs sort

MyTinySTL中的排序稳定性测试:stable_sort vs sort

【免费下载链接】MyTinySTL Achieve a tiny STL in C++11 【免费下载链接】MyTinySTL 项目地址: https://gitcode.com/gh_mirrors/my/MyTinySTL

在C++标准模板库(STL)中,排序算法是日常开发中最常用的功能之一。MyTinySTL作为一个轻量级STL实现,提供了多种排序相关函数。本文将重点对比两种常用排序函数的稳定性差异:stable_sortsort,通过实际测试案例帮助开发者理解何时选择适合的排序算法。

排序稳定性基础概念

排序稳定性指当待排序序列中存在相等元素时,排序前后这些元素的相对位置是否保持不变。稳定排序会保留相等元素的原始顺序,而非稳定排序则可能改变它们的相对位置。

在MyTinySTL中,algorithm_test.h文件包含了对排序算法的测试用例。测试结果表明,stable_sortsort在处理重复元素时表现出明显差异。

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);
}

测试结果表明,在大多数情况下,sortstable_sort具有更好的性能,特别是当数据量较大时。

应用场景建议

根据测试结果,我们可以得出以下使用建议:

  1. 当需要保持相等元素的相对顺序时(如多关键字排序),选择stable_sort或list的sort方法

  2. 对随机访问迭代器(如vector)进行排序且对稳定性无要求时,优先选择sort以获得更好性能

  3. 处理链表容器时,直接使用其成员函数sort,该实现本身就是稳定的

总结

MyTinySTL提供了多种排序方案,每种方案都有其适用场景。sort函数通过内省排序实现了高效的O(n log n)排序,但不保证稳定性;而stable_sort(若实现)和list的sort方法则提供稳定排序能力,但可能牺牲部分性能。

通过algorithm_test.halgorithm_performance_test.h中的测试用例,我们可以全面评估这些排序算法的正确性和性能表现,为实际开发中的算法选择提供依据。

在选择排序算法时,开发者应权衡稳定性需求和性能要求,结合具体数据结构特点,选择最适合的排序方案。

【免费下载链接】MyTinySTL Achieve a tiny STL in C++11 【免费下载链接】MyTinySTL 项目地址: https://gitcode.com/gh_mirrors/my/MyTinySTL

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值