STL源码学习——Lists(链表)

STL源码学习——Lists(链表)

  今天突然想起来看看开源项目,找了找最后决定好好看看经典的STL喵~
  和STL里的代码比起来我突然觉得以前写的代码也太不规范了喵,估计很多ACMer都一样吧喵。

  先从简单的看、先挑了一发list的源码来看。总结如下:

    欢迎大家一起讨论喵~

  1 :list是用双向循环链表实现的,就是说 list.end()+1 == list.begin()
  2 :list中有一个关键结点,这个结点是 list.end()
  3 :在看了list中的erase函数后,发现这个函数没有对end()结点进行特殊处理,所以很遗憾list在erase(end)后就会出现一些意想不到的情况,比如以下代码会让list容器死循环喵~(虽然这个操作本来就是非法的)

 1 int main()
 2 {
 3     list<int> ls;
 4     ls.insert(ls.begin(), 0);
 5     ls.insert(ls.begin(), 1);
 6     ls.erase(ls.end());
 7     for(list<int>::iterator it=ls.begin(); it!=ls.end(); ++it)
 8         printf("it -> %d\n", *it);
 9     return 0;
10 }

  4 :erase(it)之后会返回应该在原先it位置的元素。同样erase(end)后返回值是不对的。(erase(end)后的返回值为begin喵~)

  5 :erase()函数并未检测传入参数是否是本身这个list的。所以如果你有两个list:L1、L2,你这样写也是对的喵~

L1.erase(
L2.begin() );

  

  6 :list里居然自己实现了sort算法喵,而且时间复杂度O(n*lg n)、空间复杂度O(1)。以前并没有仔细想list的排序问题,一直很单纯的以为list排序很慢。今天看了一发源码才知道原来链表排序也可以这么优越喵~

  这里,《STL源码剖析》中采用的如下解释:解释为快速排序。

  大致说一下算法喵:这里采用的是归并排序算法的思想。
  先将0、1两元素排序,再将2、3两元素排序。
  接下来就是排序前4个元素,
  然后,同上前8、16、32 ... 个元素
  具体实现用了64个桶,每个依编号存放2^n个元素。然后就像二进制加法一样,每次对个位进行加一操作,通过进位过程可将排好序的桶进行合并了喵。
由于链表的特殊性,无须另开空间存放元素,只需将原来的结点移动位置即可喵~

list::sort()

 1     void sort(_StrictWeakOrdering __comp)
 2     {
 3         // Do nothing if the list has length 0 or 1.
 4         if (_M_node._M_data->_M_next != _M_node._M_data &&
 5                 (_M_node._M_data->_M_next)->_M_next != _M_node._M_data)
 6         {
 7             list<_Tp, _Alloc> __carry;
 8             list<_Tp, _Alloc> __counter[64];
 9             int __fill = 0;
10             while (!empty())
11             {
12                 __carry.splice(__carry.begin(), *this, begin());   //个位加一
13                 int __i = 0;
14                 while(__i < __fill && !__counter[__i].empty())
15                 {
16                     __counter[__i].merge(__carry, __comp);
17                     __carry.swap(__counter[__i++]);
18                 }
19                 __carry.swap(__counter[__i]);
20                 if (__i == __fill) ++__fill;
21             }
22
23             for (int __i = 1; __i < __fill; ++__i)
24                 __counter[__i].merge(__counter[__i-1], __comp);
25             swap(__counter[__fill-1]);
26         }
27     }

  7 :关于resize()我以前一直以为list会存放一个size_val,结果它木有存,resize的复杂度是线性的。所以如果size比较大的话,还是少resize()为好喵。

当然现在也可以理解为什么没有存放size_val了喵,因为存在这个时间复杂度为O(1)的insert函数。

void insert(
iterator pos, input_iterator start, input_iterator end );

  

  8 :“operator=” list里这个函数比我想像的要聪明喵。
  我以为它会先erase(begin(), end()),然后再一个一个的加进去。
  结果它是先将就目标list中已创建的结点先用着,然后采用”多退少补“的原则喵~

时间: 2024-11-30 22:10:47

STL源码学习——Lists(链表)的相关文章

Redis源码学习——BIO

Redis源码学习之BIO BIO顾名思义,background IO,是redis中运行的后台IO. 网上千篇一律的说法是redis是单线程单进程. 实际上redis运行过程中并不是严格单进程单线程应用.Redis中的多进程: 在写入备份(RDB,AOF)的时候,会fork出子进程进行备份文件的写入.Redis中的多线程: AOF的备份模式中,如果我们设置的是AOF_FSYNC_EVERYSEC(每秒备份一次,这个设置可理解为弱同步备份),redis会create一个backgroud线程,在

DotText源码学习——ASP.NET的工作机制

--本文是<项目驱动学习--DotText源码学习>系列的第一篇文章,在这之后会持续发表相关的文章. 概论 在阅读DotText源码之前,让我们首先了解一下ASP.NET的工作机制,可以使我们更好的理解.ASP.NET是Web服务器(IIS)的 ISAPI(Internet Server API)扩展.当IIS接收到客户端浏览器发来的请求后,它根据请求的文件类型确定由哪个ISAPI扩展来处理该请求,并将请求转发给ASP.NET(如 果是ASP.NET处理的相应文件类型的话,如*.aspx.*.

Hadoop源码学习:RPC

Hadoop源码学习:RPC Hadoop RPC使用java NIO编写,达到高性能,轻量级,可控性. 主要分为四层:序列化层,函数调用层,网络传输层,服务器端处理框架 序列化层:实现Writable接口 函数调用层:java反射机制和动态代理实现函数调用 网络传输层:使用Socket机制 服务器端处理框架:基于Reactor设计模式的事件驱动I/O模型 如何使用Hadoop RPC: RPC Server: 1.定义一个协议,实现VersionedProtocol接口, public int

Java集合源码学习(二)ArrayList分析

Java集合源码学习笔记(二)ArrayList分析 1.关于ArrayList ArrayList直接继承AbstractList,实现了List. RandomAccess.Cloneable.Serializable接口, 为什么叫"ArrayList",因为ArrayList内部是用一个数组存储元素值,相当于一个可变大小的数组,也就是动态数组. (1)继承和实现 继承了AbstractList,实现了List:ArrayList是一个数组队列,提供了相关的添加.删除.修改.遍历

sgi- 今天看SGI STL源码剖析空间配置器部分,有一个疑问,求解 .

问题描述 今天看SGI STL源码剖析空间配置器部分,有一个疑问,求解 . 今天看SGI STL源码剖析空间配置器部分,有一个疑问,求解. 具体问题是: SGI STL的第二级空间配置器分配完空间之后,不回收给系统吗?(每次都添加都内存池free list) 没看到相关释放内存池的代码. 求解释.

c++-侯捷stl源码剖析红黑树代码问题

问题描述 侯捷stl源码剖析红黑树代码问题 在侯捷的stl源码剖析这本书中,P218,红黑树的数据结构代码中有这样一行代码: typedef simple_alloc rb_tree_node_allocator; ,在编译时会报错,其错误为: error: 'simple_alloc' does not name a type 一直没查找到答案,不知道该怎么修改,还请高手解答

怎样设置visual studio使得编译时不出现STL源码?

问题描述 怎样设置visual studio使得编译时不出现STL源码? 如图.错误列表没有给出我的源代码是在第几行出现了错误,而是给出在STL源码的第几行出现了错误.这让我很难看懂,我该怎样设置使得错误直接在我的源代码上标示出来?谢谢各位. 解决方案 Visual Studio打开文件时出现"向程序发送命令时出现问题Using STL without exceptions in Visual Studio 2005 解决方案二: 看堆栈调用窗口,在里面找错误断点的上下部分里找你的代码

有谁写过asp.netsql2000进销存的,我购源码学习?

问题描述 有谁写过asp.netsql2000进销存的,我购源码学习?我最近想学ASP.NET看了很多书,都不行.都差不多.所以想购源码来学习,价格在3000左右,要求商业,但不要求很完善的QQ:421520476 解决方案 解决方案二:但不要求很完善的????商业项目哪个不是比较完善后才出"厂"的,你去51aspx找一下吧,应该有供学习的--

Android源码学习之组合模式定义及应用_Android

组合模式定义: Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. 将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 如上图所示(截取自<Head First De