链表的归并排序:来自STL_ list_ sort 算法
来源:互联网 发布:网络推广简历 编辑:程序博客网 时间:2024/06/05 01:54
侯捷STL源码剖析中列出了list的sort算法源码,感觉挺有意思:
template <class T, class Alloc>
void list<T,Alloc>::sort()
{
if (node->next==node||link_type(node->next)->next==node)
return;
list<T,Alloc> carry;
list<T,Alloc> counter[64];
int fill = 0;
while (!empty())
{
carry.splice(carry.begin(),*this,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]);
swap(counter[fill-1];32
}
其实就是归并排序,不过采用的不是自顶向下的递归,而是自底向上的归并。
counter数组用来保存有序的子串,其实就是起到递归栈的作用。其中counter[i]保存的是长度为2i的子串。carray是一个临时容器。
归并的顺序大致是这样的:首先从原list中取一个元素,将这个元素看做是一个长度为k=1的串,然后从counter数组的第i=1个list开始检查,如果这个list为空,则将子串放入counter[i];否则将carry和counter[i]归并为长度为2k的子串,再检查counter[i+1],以此类推。当原list为空时,将counter数组中各list归并起来就可以了。
因此我认为fill这个变量唯一的意义就在于记录一下counter数组最大利用长度,提高一下最终归并(最后一个for循环)的效率而已。
这个算法的实现限定了它所能排序的最长list为 264-1,这个数也确实足够大了。
一般来说程序里面不应该出现所谓的魔法数字,上面的(64),不过STL都在此处如此使用,看来只要有足够的理由(264-1对一般程序来说已经是个天文数字),规则也是可以打破的。硬编码的数组可以让代码更加干净整洁。
- 链表的归并排序:来自STL_ list_ sort 算法
- leetcode_效率题解_148. Sort List_(链表归并排序)
- STL_算法_对所有元素排序(sort、stable_sort)
- list_链表的常用操作
- LIST_找出链表的共同后缀
- 【算法】归并排序 merge sort
- 归并(Merge Sort)排序算法
- 算法-归并排序(Merge-Sort)
- Sort List——链表的快速/归并排序
- 链表的二路归并排序 Sort List
- leetcode:Sort List(链表的归并排序)
- LeetCode Sort List 链表的归并排序
- Leetcode Sort List 链表归并排序
- 链表和归并排序(Merge Sort)
- Sort List 归并排序链表
- 148. Sort List 链表归并排序
- list容器的特殊sort()算法:非递归--归并排序
- 经典排序算法 - 归并排序Merge sort
- Oracle中sign函数的简单用法
- 菜单的使用方法
- MPEG-2TS码流编辑的原理及其应用
- Android Sqlite3 编程详解
- oracle数据库中 case when的用法
- 链表的归并排序:来自STL_ list_ sort 算法
- MVC架构在Asp.net中的应用和实现
- 《优雅是女人最美的外衣》-欧石楠
- ASP.NET附件上传下载
- Flash设置为首页和收藏夹的代码
- Oracle数据库Decode()函数的使用方法
- RUP和瀑布模型
- 怎么让Tomcat6.X支持SSI功能配置
- QNX Momentics IDE 4.7.0显示行号