STL实现

1.STL的六大组件


2.空间配置器(allocator)


3.迭代器及实现(trait编程技术)


4.序列式容器(vector(动态数组),list(双端链表) ,deque,stack,queue,priority_queue,slist)及其每个容器相应的迭代器类型。

vector:内存如何分布及其特点,迭代器类型,每个成员函数的调用过程(begin,end,size,capcity,empty,front,back,push_back,pop_back,erase,resize,insert)


list:node节点构造,迭代器类型,list的数据结构环状队列,包含一个空白节点,表示终止,每个成员函数的使用过程(begin,end,list()产生空链表,其实产生一个空白节点,push_back(),insert, push_front,  erase ,   pop_front,   pop_back,   clear,    remove ,    unique,    splice ,    merge,   reverse,   sort)。其中merge将一个链表融合,需要两个链表都是排序好的。(merge,sort,reverse 都利用了内部函数transfer)


deque:内存构造及其特点,deque的中继器(通过一个指针数组来指向每一段连续内存地址(缓冲区)),deque有一个数据成员map,为T**,deque的迭代器,该迭代器成员有,指向每段缓冲区头,尾,当前内存,以及指向map与中继器关联,(T* cur,T* begin,T* end, T** map)还需注意deque迭代器实现许多操作符重载(*,-》,+,-,++,--,[],....),deque 内的数据成员,iterator start,iterator finish,T** map, int map_size,故,deque成员函数的实现过程(begin(),end(),front(),back(),size())注意deque内存细节,构造,插入,删除,等操作缓存区变化,以及指向缓冲区地址的指针数组大小变化,(构造,push_back,push_front,还需要判断map重新配置,pop_back,pop_front,clear()清除后会保留一个缓冲区,erase,insert 都会带来移动,计算从后向前移动与从前向后移动的代价进行选择)。


stack。内部一般通过deque实现

queue,内部一般通过deque实现


heap。指的是maxheap,通过vector实现,并且vector第一位置为空,方便计算。heap提供几个算法,push_heap(两个条件,1.两个迭代器指向首尾,2.元素已经插入最尾端),pop_heap,,sort_heap(通过pop_heap实现),make_heap(键最大堆)


priority_queue,具有权重概念的堆,通过heap实现,保证权重最大的元素处在第一个位置上。


slist.单链表



5.关联式容器(map,set,hash_map,hash_set,multimap,multiset,hash_multiset,hash_multimap)及其每个容器相应的迭代器类型。


RB树:首先掌握RB树的特点,性质,(难度在于红黑树的四个装换)。然后红黑树的节点设计 node(color,parent ,left,right,(继承)value),RB的迭代器,通过继承,base_iterator(成员base_node* node,increment(实现与++),decrement(实现与--)),iterator成员(++,--,*,->)

RB树数据结构:成员主要有一个header,header-》left指向最小,header-》right指向最大。构造函数会构造出一个header,begin()返回header-》left,end()返回header。(两个内置函数insert_unique ,insert_equal可以为分别出set ,multiset,插入元素后,需要旋转以及改变颜色使RB树合法)。


set。底层通过RB树实现,不可通过set迭代器改变set元素值, 因为set::iterator 被转换为const_iterator.set 有几个特殊的成员函数,find,count,lower_bound,upper_bound,equal_bound.


map.底层通过RB树实现。同上,不过区别在,typedef pair<constkey,value> value_type,iterator还是常规iterator,不过值类型的键值为const,值为非const。operaor[]重载成员函数内部调用了insert成员函数。


hashtable。实现开链法避免冲突。桶通过vector实现,vector buckets.  节点node{value ,node* next};

首先理解hashtable的迭代器iterator。重点两个成员变量,node*cur,hashtable * ht保证与容器的联系。

hashtable的数据结构:主要成员vectorbuckets. 重点在于hashtable的构造与内存管理,初始化时仅仅初始化vector buckets 根据大小。每个元素为0.当插入的元素个数大于buckets的大小时,就会重建,重建的节点顺序按照先进来的节点连接在后面。两种插入,insert_unique,insert_equal。hashset,hashmap实现同理。


6.算法(熟悉每个算法实现过程及适用场景及复杂度)

可分为两大类:

1.质变:一般有两个版本,

1.就地改变对象,

   2.copy版本,将操作对象的内容复制一份副本,然后再副本上进行修改并返回副本,算法以_copy加后缀。

2.非质变

 算法一般有缺省行为可以传入一个仿函数,或者_if 版本表示表示接受仿函数。

///


具体实现:


///


7.仿函数:

分类方式:

1.按操作数个数可分为一元,二元仿函数

2.按功能可分为算术运算,关系运算,逻辑运算三大类(每类有哪些函数?)


若使仿函数的可配接,需要仿函数定义自己的相应型别,主要继承下面两个类:

template

struct unary_function{

typedef Arg argument_type

typedef Result result_type

}


template

struct binary_function{

typedef Arg1 first_argument_type

typedef Arg2 second_argument_type

typedef Result result_type

}



8.配接器(适配器)

主要三种适配器:

1.容器适配器:stack,queue,priority_queue

2.迭代器适配器:front_insert_iterator,back_insert_iterator,insert_iterator(插入迭代器),Reverse iterator,istream_iterator, ostream_iterator(iostream iterator)

3.仿函数适配器:bind1st,bind2nd,not1,not2,compose1,compose2,以及应用于普通函数的ptr_fun,以及应 用于成员函数的mem_fun使它们成为一个可配接的仿函数。

首先看看迭代器适配器的实现

1.插入迭代器实现:

back_insert_iterator, front_insert_iterator 内部通过一个相应容器成员,然后再operator=成员函数内部调用容器的push_back,以及push_front函数

insert_iterator内部通过通过相应容器成员以及容器的相应iterator,operator=内部通过调用容器的insert函数。

2.reverse_iterator,内部通过一个真正的正向迭代器成员iter,修改操作iter++,--,+,-的作用方式,然后通过base成员函数返回成员iter。因此其实reverse_iterator 与iterator指向的实体位置一样,只是解释方式或者逻辑位置不一样,reverse_iterator取某地址值会会iter--,然后取*iter。

3.istream_iterator,内部其实通过维持istream 成员,对该迭代器的operator++操作会调用内部的>>操作。ostream_iterator,内部通过ostream成员,以及string str(代表每次输出后的间隔字符),operator=操作即调用内部的<<。

再看函数适配器实现:

主要都是通过将可配接仿函数作为bind,not ,compose的成员,然后operator()调用该成员。

应用于普通函数的ptr_fun,主要1.继承相应仿函数类别基类unary_function,binary_function,然后成员为相应函数指针,然后operator()直接作用于该函数指针上。

应用于成员函数mem_ptr







你可能感兴趣的:(c++)