由于 STL 本身的排序算法 sort 接受的输入迭代器是随机访问迭代器,但是双向 list 链表容器的访问方式是双向迭代器,因此,不能使用 STL 本身的排序算法 sort,必须自己定义属于自己访问的排序算法。
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::sort()
{
//@ 如果链表为空或者链表只有一个元素则不做任何操作
if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node)
{
list<_Tp, _Alloc> __carry; //@ carry 链表起到搬运的作用
//@ counter 作为中间的存储载体
/*
*其中对于counter[i]里面最多的存储数据为2^(i+1)个节点
*若超出则向高位进位即counter[i+1]
*/
list<_Tp, _Alloc> __counter[64];
int __fill = 0;
while (!empty())
{//@ 若不是空链表
//@ step1:
//@ 把当前链表的第一个节点放在 carry 链表头
__carry.splice(__carry.begin(), *this, begin());
int __i = 0;
while(__i < __fill && !__counter[__i].empty())
{
//@ step2:
__counter[__i].merge(__carry); //@ 把链表carry合并到counter[i]
//@ step3:
__carry.swap(__counter[__i++]); //@ 交换链表carry和counter[i]内容
}
//@ step4:
__carry.swap(__counter[__i]); //@ 交换链表carry和counter[i]内容
//@ step5:
if (__i == __fill) ++__fill;
}
for (int __i = 1; __i < __fill; ++__i)
//@ step6:
//@ 把低位不满足进位的剩余数据全部有序的合并到上一位
__counter[__i].merge(__counter[__i-1]);
//@ step7:
//@ 最后把已排序好的链表内容交换到当前链表
swap(__counter[__fill-1]);
}
}
待排序的原始链表:
第一次执行 while 循环
第二次执行 while 循环
第三次执行 while 循环
第四次执行while循环:
最后
原文:https://www.cnblogs.com/xiaojianliu/p/12595501.html