最近看 <<C++性能优化指南>> 留意到上面说 std::list::sort 算法能做到 O(nlog2(n)) 复杂度,而直接对 std::list 套用 std::sort 只能做到 O(n²)
思考后发现如果把 std::sort 套到 std::list 上由于是 Bidirectional Iterator 的原因,计算距离的时候需要一步一步的移动,经典的 intro sort/quick sort 无法在这个双端链表的结构上面施展,而 heap sort 需要先 make_heap,双端链表由于无法快速定位到中间的元素,第一步的 make_heap 都很难操作。
参考了网上资料以及<<STL源码剖析>> 发现,该排序算法使用的是类似 merge sort 的思想,代码比较简短,第一次看的时候不是很好理解,在此做个记录
一开始也排除了 merge sort, 因为传统的 merge sort 需要不停地对半,归并,对半,归并,在一个双端链表要怎么实现这个对半的过程呢?
这是 <<STL源码剖析>> 上面的 list::sort 编辑过后的代码
#include <iostream>
#include <sstream>
#include <list>
template <class T, class Alloc>
void pr_arr(const std::list<T, Alloc> &lst, std::string hint = "")
{
std::cout << hint << ": ";
for (const auto &i : lst)
{
std::cout << i << " ";
}
if (!lst.size())
std::cout << "empty list";
std::cout << std::endl;
}
template <class T, class Alloc = std::allocator<T>>
struct my_list: public std::list<T, Alloc>
{
void my_sort()
{
std::ostringstream str_os;
std::list<T, Alloc> carry;
std::list<T, Alloc> counter[64];
int fill = 0;
std::list<T, Alloc> &base_lst = *this;
while (! this->empty())
{
pr