一直以来学习排序算法, 都没有在链表排序上下太多功夫,因为用得不多。最近看STL源码,才发现,原来即使是链表,也能有时间复杂度为O(nlogn)的算法,

大大出乎我的意料之外,一般就能想到个插入排序。

下面的代码就是按照源码写出的(去掉了模板增加可读性),注意forward_list是C++11新加的单向链表,这里选这个是因为它更接近我们自己实现链表时的做法。

void sort_list(forward_list<int>& l){
auto it = l.begin();
if (l.empty() || ++it == l.end())
return;
forward_list<int> carry;
forward_list<int> counter[64];//总共只设立了64个桶,因为第i个桶被填充的时候,里面至多2^i个元素,2^64,远超一般元素数目
int fill = 0; //fill记录的是当前填到哪个桶了
while (!l.empty()){
carry.splice_after(carry.cbefore_begin(), l, l.cbefore_begin());//每次从原链表上取下一个元素
int i = 0;
while (i < fill && !counter[i].empty()){
counter[i].merge(carry);
carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if (i == fill) ++fill;
}
for (int i = 1; i < fill; ++i)
counter[i].merge(counter[i - 1]);
l.swap(counter[fill - 1]);
}

  关于此算法的分析:网上很多争论这个到底是快速排序还是归并排序的(侯捷的书上说是快排)。

为了理解这个代码,可以手动运行一下。

fill,记录用到了几个桶,最外层循环保证这样一个事实:从第0个桶到第fill - 1个桶里面,要么为空,要么存储有2^fill个元素,而且是有序链表。

每次与新取下的元素(存储在carry中)合并的桶都是counter[0]。如果第0个桶里没有元素,那就直接放进去carry.swap(counter[i])。下一轮循环的

时候,因为counter[0]里有元素了,就会进入内层循环,这时候,counter[i].merge(carry)使得第0个桶变为一个含两个元素的链表,然后内层循环第二步,又将这个链表

转移到carry中,下一轮内层循环的时候,带有两个元素的carry就会争取与第1个桶合并(如果第1个桶不空的话),如果第一个桶为空,它将退出内层循环并将元素放进第一个桶,(此时发现i == fill,于是fill变为2)然后下一轮外层循环继续从链表中取下一个元素,(此时counter[0]为空,counter[1]中含有两个元素),如前面一样,先是发现counter[0]是空的,进不去内层循环,于是直接把元素填到counter[0]中,下一次外层循环又取一个元素,进入内层循环,与counter[0]合并,交换,然后下一轮内层循环中,带有两个元素的carry就会与带有两个元素的counter[1]合并,交换, i == fiil == 2退出内层循环,四个元素变到第2个桶中,fill++。

走完这一遍之后,感觉清晰了,但是除了外层循环的循环不变条件以外,实在是很难从基本的快排或归并排序的思想中想到这样去做。

STL 中的链表排序的更多相关文章

  1. stl中常用的排序算法

    #include"iostream" #include"vector" using namespace std; #include"string&qu ...

  2. STL中六大组件

    1)容器(Container),是一种数据结构,如list,vector,和deques ,以模板类的方法提供.为了访问容器中的数据,可以使用由容器类输出的迭代器: 容器(container)用于存放 ...

  3. C++的标准模板库STL中实现的数据结构之链表std::list的分析与使用

    摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解,即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第二篇.主要针对线性表中的链表 ST ...

  4. C++ STL中Map的按Key排序和按Value排序

    map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...

  5. C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET

    C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...

  6. STL中vector的赋值,遍历,查找,删除,自定义排序——sort,push_back,find,erase

    今天学习网络编程,那个程序中利用了STL中的sort,push_back,erase,自己没有接触过,今天学习一下,写了一个简单的学习程序.编译环境是VC6.0         这个程序使用了vect ...

  7. STL中sort排序算法第三个参数_Compare的实现本质

    关于C++ STL vector 中的sort排序算法有三种自定义实现,它们本质上都是返回bool类型,提供给sort函数作为第三个参数. 重载运算符 全局的比较函数 函数对象 我认为从实现方式看,重 ...

  8. C++ STL中Map的按Key排序

    为了实现快速查找,map内部本身就是按序存储的(比如红黑树).在我们插入<key, value>键值对时,就会按照key的大小顺序进行存储.这也是作为key的类型必须能够进行<运算比 ...

  9. STL中的排序算法

    本文转自:STL中的排序算法 1. 所有STL sort算法函数的名字列表: 函数名    功能描述 sort   对给定区间所有元素进行排序 stable_sort 对给定区间所有元素进行稳定排序 ...

随机推荐

  1. Node.js 配置Nginx

    1.修改nginx.conf upstream nodejs { server 127.0.0.1:3000; #server 127.0.0.1:3001; keepalive 64; } serv ...

  2. 使用WinSCP这个软件使linux和win7互传文件

    使用这个软件之前首先win7要可以ping通linux系统,且linux要开启,关机可不能通啊!!!!!!!!! 双击这个快捷方式 主机名写ip地址 我们可以将虚拟机上的文件下载下来进行使用 也可以将 ...

  3. MapReduce实战(五)实现关联查询

    需求: 利用MapReduce程序,实现SQL语句中的join关联查询. 订单数据表order: id date pid amount 1001 20150710 P0001 2 1002 20150 ...

  4. liunx下安装mysql(未完待更新)

    1.下载mysql-liunx 下载地址:http://download.csdn.net/download/yichen01010/10019139 2.删除系统自带mysql rpm -qa|gr ...

  5. 【Mac + Python + Selenium】之PyCharm配置Selenium自动化

    一.安装PyCharm 1.下载地址: Pycharm编辑器官网下载地址 2.安装完成之后打开,一路下去点击,直到填写注册码,参考: <[转载][Pycharm编辑器破解步骤]之idea和Pyc ...

  6. 让IE6支持min-width和max-width的方法

    正如君所想象的一样,同实现层的fixed一样,用的是expression语句.例如div#demo在: IE6下最小宽度300px:   或 *html div#demo { width:expres ...

  7. EasyUI项目学习

    介绍easyui的使用,主要包括以下组件 布局面板 - layout 可伸缩面板 - accordion 选项卡 - tabs 控制面板 - panel 窗口 - window 对话框 - dialo ...

  8. css3 一个简单的静态立方体

    <meta charset="utf8"> <style> .cube { position: absolute; left: 50%; top: 250p ...

  9. CNN图像分割总结

    深度学习(三十三)CRF as RNN语义分割-未完待续 http://blog.csdn.net/hjimce/article/details/50888915 Fully Convolutiona ...

  10. js 安全

    0x00 前言 在信息安全领域,可信系统(Trusted system)是一个让人心动的目标,它指的是一个通过实施特定的安全策略而达到一定可信程度的系统. 在计算机中,可信平台模块(Trusted P ...