《STL源码剖析》容器

来源:互联网 发布:win7网络和共享打不开 编辑:程序博客网 时间:2024/06/06 00:02

STL六大组件:

容器

迭代器

算法

配接器

配置器

仿函数

       

序列式容器

序列式容器:元素可序,并不是有序

vector

特点:维护连续线性空间,随机存取,random access itetator

      迭代器start,finish标记已经使用空间的头尾

      迭代器end_of_storage指向整块连续空间(含备用空间)的尾部

     capacity容量用于>=大小

 

vector与array的区别:唯一区别:空间运用的灵活性

array:静态空间, 

vector:动态空间,内部自动扩充空间容纳元素

与deque区别:

双端开口的连续线性序列

vector:单向开口的线性连续序列

vector实现

1,嵌套型别的定义

2,空间的头尾,可用空间的尾

3,利用2计算begin(),end()_,size(),capacity()

4,resize()

新空间大小<原来的,只保留原空间的部分,erase()

新空间大小>原来的,在原空间的适当位置插入,insert()---实际上是,开辟-复制-销毁

        
   

push_back

1,有空间,直接放到后面,调整finish

2,没有空间,扩充空间

配置原则:

原大小=0,配置1

原大小!=0,配置原大小的两倍(开辟新空间,原vector内容拷贝到新空间,析构并释放原vector,调整新vector的start,finish,end_of_storage)

注释:动态增加大小,不是在原空间之后接新空间,而是2倍的大小另外开辟,拷贝原内容,释放原空间。

      指向原vector的所有迭代器均失效

insert函数

1-如果如果备用空间>=新增元素个数;

2- 如果如果小于,就必须配置额外内存(决定新长度,新开辟,复制,释放原内存)

list

特点:

插入删除,常量时间,

     双向环形链表,一个指针,可以遍历

     非连续存储空间

      迭代器前后移动,bidirectionaliterators

注意:

list不能使用STL算法sort(),必须使用自己的sort()成员函数

因为STL算法sort()只接受随机访问迭代器

插入:

   vector可能所有迭代器失效,

   list不会失效

注意:尾部增加一个空白节点:满足前开后闭

  

clear

清除所有节点:遍历+析构删除

unique

删除重复元素:遍历+相同则删除 复杂度:n*n

transfer

list内部的transfer函数:节点间的指针移动

同一个list时,其实是同一个list的两个区段

   

priority queue

heap不是STL的容器组件

maxheap作为priorityqueue的底部实现

注:heap没有迭代器,priority queue没有迭代器

不使用二叉搜索树实现的原因:

1,要求输入有随机性

2,二叉搜索树不容易实现

   

 

slist

单向链表,不在STL标准规格内

     forward iterator迭代器

     架构运用了继承关系

  

注意:

 

关联容器

 

RB-tree特点:

1,每个节点不是红色就是黑色

2,根节点是黑色

3,若节点为红,其子节点必须为黑

4,任一节点到NULL(尾端)的任何路径,所含的黑节点数必须相同。

根据3,4.新增节点的父节点必须为黑

set

元素根据键值自动排序

键值就是实值

不允许重复 insert_unique

不能改变实值,const迭代器

插入,删除,迭代器不失效

map

实值,键值

键值不能重复

键值不能修改,实值可以修改

插入,删除,迭代器不失效

非mul和mul版本的唯一区别:

set和map插入时调用:insert_unique

multiset和multimap插入时调用:insert_equal

hash table

特点:

插入,删除,搜索:常数时间o(1)

不需要输入元素的随机性(不像二叉搜索树,logn)

散列函数:x%n (n是array的大小) 得到一个整数,范围:0~n-1

问题

带来的问题:碰撞问题

办法:开链法:

  线性探测的缺点:表格足够大;每个元素独立(难以达到)

二次探测的缺点:二次聚集

  

buckets聚合体:vector实现

前进操作:operator++

前进操作:

1,尝试从目前指的节点处罚,前进一个节点,由于节点安置于list内,所以利用节点的next指针达到前进操作。

2,如果目前节点是list的尾端,就跳到下一个bucket上,那正是指向下一个list的头节点。

没有后退操作,即operator--

解决冲突:

开链法(不要求表格大小必须为质数)在STL仍然以质数设计表格大小

1,将28个质数(逐渐呈现大约2倍的关系)设计好,以便随时访问,

2,提供一个函数,查询这28个质数中,最接近某数且大于某数的质数【代码使用二分查找实现】

insert_unique(key)

       

 

insert_equal类似

clear

    
 copy_from
      
 例子:
    
      

hash函数

     

hash_set

  

hash_map

 

 





0 0