STL相关容器的学习

Vector

迭代器:begin、end、cap

pointer类型

构造和析构函数:

先init_space一个cap空间,同时更新迭代器,然后对size范围内调用构造函数,size-cap只分配空间,没有构造元素

  • fill_init(n, value):调用uninitialized_fill_n()

  • range_init(first, last):调用uninitialized_copy(),拷贝构造

  • initializer_list : range_init(ilist.begin(), ilist.end()); 相当于vector< int>( {1,2,3} )

  • operator = (rhs):

  • rhs.size > cap:构建一个新的vector,然后swap

  • rhs.size < size:先copy(rhs.begin, rhs.end)的内容,然后destroy后面的内容,更新end

  • else:先copy(rhs.begin, rhs.begin+size)的内容,然后uninitialize_copy(rhs.begin+size, rhs.end, end),然后更新end

    因为vecotr是非POD类型,size外需要construct,调用构造函数

  • 析构函数,先destroy()调用析构函数,再deallocate调用operator delete释放空间

容器相关操作

empty():return begin == end

size():end - begin

capcity():cap - begin

访问元素接口

  • 重载[]:return *(begin + n)

  • at函数:return (*this)[n]

  • front:return *begin

  • back:return * (end - 1)

修改容器接口

  • assign:调用fill_assign和 copy_assign

  • fill_assign:如果n>cap,则构造新vector再swap;如果n>size,则先 fill 再uninit_fill_n;否则先fill_n再erase

  • copy_assign(input迭代器):*cur = *first,赋值结束时,erase(cur, end);如果空间不够调用insert(cur, first, end)

  • copy_assign(forward迭代器):如果len>cap则先构造vector再swap;如果len<size则调用copy再destroy;否则先copy再uninit_copy()

  • emplace:参数为参数包,对右值进行操作,在尾部就地构造元素避免额外开销。如果插入位置是尾部,则赋值;如果不是,则原来end值赋值给尾部,再调用copy_backward(pos, end - 1, end) 从end位置向前拷贝,最后元素赋值给*pos

  • emplace_back:对右值进行操作,在尾部就地构造元素避免额外开销。

  • push_back:参数为左值引用和右值引用,右值调用emplace_back,也是调用construct(end, value) 但是需要一个已经存在的对象,再拷贝一次(左值)

  • pop_back:调用destroy(),更新end

  • insert:右值调用emplace,左值和emplace一样,也需要一个已经存在的对象,再拷贝一次(左值)

  • insert(pos, n, value):调用fill_insert

  • insert(pos, first, last):调用copy_insert

  • fill_insert(pos,n,val):如果备用空间大于增加空间且pos后元素大于n,则先将end前n个元素uninit_copy到end后,再将pos后剩余元素move_backward到end前,再uninit_fill_n增加元素。如果小于n,则先将end后uninit_fill_n 多的元素(n-elem),再将pos后元素uninit_move到end后,最后将新元素uninit_fill_n到pos处

    如果备用空间小于增加空间,则获得新的空间,调用三次uninit_move/fill_n/move,将pos前的元素,加的元素,pos后的元素添加

  • copy_insert(pos, first, last):和fill_insert一样,将uninit_fill_n换成uninit_copy

  • erase:调用move(pos+1, end, pos)将区间元素向pos后覆盖,然后destroy最后一个元素,更新end

  • erase(first, last):first-begin = n, r指向first,调用move(r+n, end, r),再destroy r+n后的元素

  • resize:如果newsize<size,则erase;否则insert

  • swap:如果不等互换三个迭代器

  • reserve:预留空间,当n > cap时,temp=allocate(n),然后调用uninitialize_move(begin, end, temp),再将原来的deallocate后更新迭代器

push_back() 向容器尾部添加元素时,首先构造函数创建这个元素,然后再拷贝构造或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,调用stl::forward强制转换,将参数传递给类的构造函数,调用construct就地构造,无需再拷贝一次


List

  • list_node_base:有prev和next两个指针

  • list_node:继承list_node_base类,且有数据域 value

  • list_iterator:继承双向迭代器类型,有一个指针node,指向当前节点,重载*,->,++(2),--(2),=,!=

  • list_const_iterator:同上

  • list:有一个指针node_指向末尾节点(),和一个 size

构造函数和析构函数

fill_init(n, value);

如果是input_iterator类 或 initializer_list:copy_init(first, last);

如果是左值:copy_init(cbegin, cend);如果是右值:直接初始化构造函数,然后将右值置空

拷贝构造:左值调用 assign(rhs.begin(), rhs.end());右值调用 splice(end(), rhs);initializer_list直接构造list,然后swap

析构函数:调用clear(),然后将node释放置空,size置0

迭代器相关操作:

bidirectional_iterator_tag

begin():return node_->next;

end():return node_;

重载操作符++、--、->、*

容器相关操作:

size():return size;

empty(): return node_ == node_->next;

访问容器相关操作:

front():return *begin();

back():return *(--end()); 因为end为最后一个空节点,back为空节点的上一个节点(有值)

修改容器相关操作:

  • assign(n, value):调用fill_assign(n, value);

  • assign(first, last):调用copy_assign(first, last); 必须是 input_iterator 或 initializer_list

  • emplace_front(args):调用create_node()创建节点,然后link_node_at_front,size++

  • emplace_back(args):调用create_node()创建节点,然后link_node_at_back,size++

  • emplace(pos, args):调用create_node()创建节点,然后link_node,size++

  • insert(pos, &/&&value):调用create_node()创建节点,size++,然后link_iter_node();

  • insert(pos, n, value):调用fill_insert(pos, n, value);

  • insert(pos, first, last):首先计算距离n,然后copy_insert(pos, n, value);

    注:insert可以插入多个;emplace一次只能原地构造一个,参数为构造元素的参数

  • push_front(value):右值调用emplace_front;左值调用create_node()创建节点,然后link_node_at_front,size++

  • push_back(value):右值调用emplace_back;左值调用create_node()创建节点,然后link_node_at_back,size++

  • pop_front():先让node_->next指向头节点,然后unlink_nodes() 断开头节点连接,再destroy()释放头节点,size--

  • pop_back():先让node_->prev指向尾节点,然后unlink_nodes() 断开尾节点连接,再destroy()释放尾节点,size--

  • erase(pos):先unlink_nodes() 断开节点连接,再destroy()释放节点,size--

  • erase(first, last):先unlink_nodes(first,last->prev) 断开节点连接,再destroy()释放节点,size--;注:左开右闭

  • clear():将头节点到尾节点的前一个节点都释放destroy(),然后将尾节点断开连接unlink(),再size=0

  • resize(new_size):先while循环计算从begin开始的距离且len < new_size,如果len = new_size,erase(i, node_);否则说明

    直到end() ,len < new_size,创建node insert(node_, new_size - len)

  • splice(pos, x):将链表x接合于pos之前。首先得到链表x的头节点和尾节点,然后x.unlink(头,尾),再link_nodes(pos, 头,尾) 将x连接在链表pos位置,最后更新size

  • splice(pos, x, it):判断pos.node是否等于it.node或者it.node->next;然后将x中的node断开连接,再将节点连接到链表中,更新size

  • splice(pos, x, first, last):判断first和last是否相等且this和x是否相同;然后将x中的(first, last)断开连接,再将节点连接到链表中,更新size;注:左闭右开

  • remove_if(pred):将一元谓词 pred 为 true 的所有元素移除;先得到头节点和尾节点,然后遍历节点,当pred(cur)满足时,erase(cur);

  • unique(pred):将一元谓词 pred 为 true 的重复元素移除;先得到头节点、头节点的next节点和尾节点,然后遍历节点,当pred(cur,next)满足时,erase(next);

  • merge(x, cmp):按cmp合并list;首先得到两个链表头尾节点,while (f1 != l1 && f2 != l2)时,比较两个链表节点,如果cmp为真,则用for循环得到cmp为真的x链表区间,然后断开连接unlink(),再连接到f1中;如果cmp为假则++f1;如果f1比较完,则将剩余x链表断开连接后加入f1中,如果f2比较完则不操作;最后更新size

  • reverse():互换prev和next指针:while循环 swap(i.node->prev, i.node->next); 再swap(e.node->prev, e.node->next);

  • create_node(args):通过指针指向一块allocate空间,再调用construct将参数赋值给指针的value,将next和prev置空

  • destroy_node():destroy()和deallocate()

  • fill_init(n, value):先allocate node_节点,然后将node _断开连接,之后for循环create_node(value),再link_at_back()加入连接

  • copy_init(first, last):先allocate node_节点,然后将node _断开连接,计算迭代器距离n,之后for循环create_node(*first),再link_at_back()加入连接

  • link_iter_node(pos, node):在pos处加入节点;如果是头节点调用link_node_at_front();如果是尾节点调用link_node_at_back()

    其余调用link_node(pos, node)

  • link_node(pos, first, last):将[first, last]加入pos节点前面

  • link_node_at_front(first, last):将[first, last]加入头节点

  • link_node_at_back(first, last):将[first, last]加入尾节点

  • unlink_nodes(first, last):将[first, last]断开连接

  • fill_assign(n, value):for循环 *i= value;当赋值结束时,如果多了则erase(i, e),如果少了则insert(e, n, value)

  • copy_assign(f2, l2):for循环 *f1= *f2;当赋值结束时,如果多了则erase(f1, l1),如果少了则insert(l1, f2, l2)

  • fill_insert(pos, n, value):先创建一个节点node,迭代器end指向node, prev置空,再for循环(n--, end++),创建节点,并和node互连,最后link_node加入连接

  • copy_insert(pos, n, first):同上,将value改为*first

  • list_sort(f1, l2, n, cmp):归并排序;当n==2时,排序,然后递归list_sort(f1, l1, n2, cmp),list_sort(f2, l2, n-n2, cmp);再将两段有序区间合并


deque

缓冲区大小函数:

deque_buf_size():sizeof(T) < 256 ? 4096 / sizeof(T) : 16;

迭代器:

random_access_iterator_tag

buffer_size:缓冲区大小,调用deque_buf_size()

cur:当前元素的位置

first:第一个元素的位置

last:最后一个元素的下一个位置

node:缓冲区所在节点,是map_pointer类型,指针的指针

构造函数:直接初始化(有参、无参、拷贝、operate=先正同)

set_node():转到另外一个缓冲区,方便++、--操作

operator*:return *cur ;

operator-:长度 = buffer长度 *(buffer个数 - 1)+ 当前buffer中元素个数相减()

operator++:先++cur,判断cur == last,如果是则set_node(node + 1),然后cur = first

operator--:判断cur == first,如果是则set_node(node - 1),然后cur = last,再--cur;

operator+=(n):判断cur+n超过缓冲区大小,没超过直接cur+=n;超过先set_node()移动缓冲区,再cur = first + 剩余量

operator+:调用+=

operator-=:调用+=

operator-:调用-=

operator[]:return * (*this+n)

deque成员

begin:第一个缓冲区的第一个元素

end:最后一个缓冲区的最后一个元素的下一个位置

map:缓冲区指针的指针

map_size:map大小

构造函数:

  • 普通构造:调用fill_init()

  • 迭代器拷贝构造或initializer_list:调用copy_init(first, last)

  • 拷贝构造:左值copy_init();

  • 移动构造:右值直接构造函数初始化

  • operator=左值:先证同,对比两边长度,如果自身大,则erase( copy(r.begin, r.end, begin), end );

    如果左值大,则迭代器mid指向左值中的长度位置,先copy(r.begin, mid, begin),再insert(end, mid, r.end);

  • operator=右值:先clear(),然后赋值

析构函数:

调用clear(),只保留头部缓冲区,然后调用deallocate将头部缓冲区释放,再释放map

容器函数:

empty():begin == end

size():end - begin

访问元素

operator[]:return begin[n];

at:return *this[n];

front():return *begin;

back():return *(end - 1);

都要检查异常是否为空

修改容器相关操作:

assign(n, value):调用fill_assign();

assign(first, last)或initializer_list:调用copy_assign();

resize(new_size, value):小于则erase(begin + new_size, end);大于则insert(end, end + len, value);

shrink_to_fit():从map开始将map中begin前的缓冲区释放从map开始,从end.node+ 1开始将end后的缓冲区释放

emplace_front(args):如果begin.cur != first,则construct(begin.cur - 1, value),然后--cur;如果begin.cur == first,则create_buffer增加一块缓冲区在begin前,再--begin,construct(begin.cur, value)

emplace_back(args):如果end.cur != end.last - 1,则construct(end.cur, value),然后++cur;如果如果end.cur == end.last - 1,则create_buffer增加一块缓冲区在end后,然后construct(end.cur, value),然后++end

emplace(pos, args):如果在头尾,调用emplace_front/back;否则调用insert_aux(pos, value)

push_back(value):同emplace_back();右值调用emplace_back()

push_front(value):同emplace_front();右值调用emplace_front()

注:emplace参数为args只调用构造函数,push参数为拷贝或移动的元素

pop_front():判断begin.cur是否在last-1处,如果不在则destroy(cur),然后++cur;如果在则destroy(cur),然后++begin,再destroy(beign.node -1, beign.node -1,)释放缓冲区

pop_back():判断end.cur是否在first处,如果不在则--cur,再destroy(cur);如果在则--cur,然后destroy(cur),再destroy(end.node + 1, end.node + 1)释放缓冲区

insert(pos, 左值value):头/尾调用push_front/back(),否则调用insert_aux(pos, value);

insert(pos, 右值value):头/尾调用emplace_front/back(),否则调用insert_aux(pos, move(value));

insert(pos, n, value):如果是头部则require(n),newbegin = begin - n,调用uninit_fill_n(),然后更新begin

如果是尾部则require(n),newend = end + n,调用uninit_fill_n(),然后更新end;否则调用fill_insert(pos, n, value)

erase(pos):next指向pos+1位置,计算pos前的元素个数,如果小于size/2,则调用copy_backward(begin, pos, next)将[begin, pos)区间内元素从next先前拷贝,再调用pop_front();如果大于size/2,调用copy(next, end, pos)将next后元素拷贝到 pos位置,再调用pop_back();

erase(firse, last):如果是头尾则clear;计算first到last长度len,如果len<size/2,则调用copy_backward(begin, first, last),然后destroy前面空间,再更新begin;如果len>size/2,则调用copy(last, end, first),destroy后面空间,再更新end;

clear():先将除begin 和 end的缓冲区全destroy,然后再destroy(begin.cur, begin. last),destroy(end.first, end.cur),end = begin

保留了头部缓冲区,(begin.first, begin.cur)

swap(rhs):交换四个成员变量

create_map():for循环将*(map + i ) = nullptr

create_buffer():*cur = allocate(buffer_size)

destroy_buffer(): deallocate(*n, buffer_size), *n = nullptr

map_init():先将elenum / buffersize + 1算出缓冲区个数,然后调用create_map(),然后让nstart和nend指向map中间区域方便扩充,然后调用create_buffer(),更新begin 和 end迭代器

fill_init(n, value):先调用map_init(),然后for循环将除了最后一个缓冲区(不一定满)从头到尾uninit_fill(*cur, * cur + buffersize, value), 然后再uninit_fill(end. first, end.cur, value)填充

copy_init(firsrt, last):input类型,先计算迭代器距离,再map_init(),然后for循环emplace_back(*first); //迭代器不能动,只能插入

copy_init(firsrt, last):forward类型,先计算迭代器距离,再map_init(),然后for循环uninit_copy(first, first + bufferize, *cur)除最后一个缓冲区,更新first,然后单独uninit_copy(first, last, end, first)最后一个缓冲区

fill_assign(n, value):如果n>size,则先erase,再fill()赋值;如果n<size,则先fill(),再insert(n-size, value)

copy_assign(first, last):input类型,for循环赋值,如果还有剩余空间则erase,如果自身空间不足则insert_dispatch(first, last, end);

//迭代器不能动,只能插入

copy_assign(first, last):forward类型,先计算长度,如果空间不足,更新next = first + len,先copy(first, next, begin)然后insert_dispatch();长度足够则copy()再erase();

insert_aux(pos, args):如果pos前面元素少,则先emplace_front(),将copy(begin + 1, pos, begin);如果后面元素少,则emplace_back(),copy_backward(pos, end - 1, end);最后将pos位置构造args

fill_insert(n, value):如果前面元素小,且元素大于n,先require_cap(n)空间,begin往前移动n,将begin后n个元素移动到最前方uninit_copy(),再将pos前剩余元素copy()到原begin位置,最后fill();如果小于n则先将begin到pos元素uninit_copy到最前方,再uninit_fill()将value赋值到begin,再fill将begin到pos位置赋值


stack

stack<class T, class container>,默认使用deque

使用底层容器的型别

没有迭代器

成员

container c (deque)

构造和析构函数

调用duque的构造和析构函数

访问元素操作

top():调用deque.back();

容器访问操作

empty():调用deque.empty()

size():调用deque.size()

修改容器相关操作

push():调用deque.push_back()

emplace():调用deque.emplace_back()

pop():调用deque.pop_back()

clear():while(!empty()) pop()

swap():调用deque.swap()

重载操作符:比较成员deque


queue

queue<class T, class container>,默认使用deque

使用底层容器的型别

没有迭代器

成员

container c (deque)

构造和析构函数

调用duque的构造和析构函数

访问元素操作

front():调用deque.front();

back():调用deque.back();

容器访问操作

empty():调用deque.empty()

size():调用deque.size()

修改容器相关操作

push():调用deque.push_back()

emplace():调用deque.emplace_back()

pop():调用deque.pop_front()

clear():while(!empty()) pop()

swap():调用deque.swap()

重载操作符:比较成员deque


heap

底层为vector实现的完全二叉树

函数

push_heap():新元素已插入到低端,调整heap

pop_heap():将根节点调整到低端,调整heap

make_heap():将容器内的数据变成heap

sort_heap():不断进行pop_heap()并缩减范围,得到递增序列


priority_queue

queue<class T, class container, class cmp>,默认使用vector、less(大堆根,从大到小)

使用底层容器的型别

没有迭代器

成员

container c (vector)

compare cmp

构造和析构函数

调用vector的构造和析构函数,然后调用make_heap()比较优先级赋值

访问元素操作

top():调用vector.front();

容器访问操作

empty():调用vector.empty()

size():调用vector.size()

修改容器相关操作

push():调用vector.push_back(),再push_heap()排序

emplace():调用vector.emplace_back(),再push_heap()排序

pop():先调用pop_heap()将队首元素放到队尾,再调用vector.pop_back()

clear():while(!empty()) pop()

swap():调用vector.swap()

重载操作符:比较成员vector


rbtree

节点base 1、颜色:非黑即红

2、左右节点指针

3、父节点指针

4、最大值和最小值函数:

由于RB_tree是BST树,因此一直向左就是最小值,一直向右就是最大值

节点:继承base

节点值

迭代器base

继承bidirectional双向迭代器

1、指向节点的指针

inc():迭代器前进,找第一个比他大的值

如果右节点不为空,则先向右走,然后向左子树走到底;

如果没有右节点,则找到父节点,直到当前node不是右子节点,返回node的父节点

特殊情况:如果node为header,且node右节点为根节点,则++后仍然是header

dec():迭代器后退,找第一个比他小的值

如果node为header(红色)则node的右子节点为解答,

如果有左子节点,则先向左,再向右走到底;

如果不是head也没有左节点,则一直向上直到node不是左节点,返回node的父节点

迭代器:继承base

重载++:调用inc()

重载--:调用dec()

重载*:返回value

重载->:返回*的取地址

数据结构

1、header节点(与根节点互为对方的父节点)

2、节点数

3、key_cmp

函数

root():返回header的父节点,即根节点

leftmost():返回header->left,最小节点

rightmost():返回header->right,最大节点

获取成员:left, right, color, parent, value, key

init():初始化,产生一个header,为红色(和root区分),并且left 和 right为自己

insert_equal():可以重复插入,从root开始,遇到大的向左边,遇到小的向右边,然后找到合适位置,调用insert(x, v, add_to_left)

insert_unique():多一个检查键值重复,不重复返回pair<insert, true>,重复返回pair<insert, false>

insert(x, y, v):如果y为header,则root为新节点,leftmost和rightmost都为新节点;先比较v和插入父节点y

如果在左边插入,则插入到左边,选择维护leftmost(),如果在右边,插入到右边,选择维护rightmost()

最后调用rebalance()重新平衡

rebalance():每次插入/删除完都要操作调整,root永远为黑

find():向左走更新父节点,记录第一个大于等于key值的节点,最后返回

迭代器操作:

begin():返回leftmost()

end():返回header


hash_table

迭代器:

有两个指针,一个node*,一个hashtable *

迭代器只有前进操作,继承了forward_iterator

重载++操作:

1、如果链表节点的next不为空,则跳转next

2、如果为空,则找到自己的bucket,然后++bucket,跳转到bucket所在链表的头节点

迭代器操作

begin():返回第一个bucket不为空的位置

构造函数

没有默认构造函数

1、有参构造

2、迭代器构造

3、拷贝构造,左值和右值

4、赋值运算符

数据结构

1、hashtable_node:自己维护节点结构,拥有next指针 和 存储value值

2、bucket_type为 vector<node_ptr>,vector维护篮子大小,篮子中维护节点指针,方便动态扩充

函数

ht_next_prime(n):找出最接近并大于n的质数

insert_unique_noresize(value):不需要重建表格的情况下插入新节点

首先找到值对应的篮子节点,遍历该篮子节点的整个链表是否有相等值,如果有立即返回pair<iterator, false>

如果没找到相等值或对应篮子节点为空,则先创建该值的节点,然后让该节点成为链表的头部,返回pair<iterator, true>

insert_multi_noresize(value):如果找到相同节点则立即插入

emplace_unqiue(args):先原地构造节点,再判断异常(数量是否超了),再调用insert

rehash_if_need:判断是否超出节点数量,n > 篮子数量 * 最大负载因子(1.0)

replace_bucket(n):先创建一个新bucket,然后遍历篮子,然后遍历篮子中的链表,创建新链表节点,再判断节点在哪个bucket内,for循环遍历新bucket的对应bucket位置,如果为空,则直接插入当前节点,如果不为空,在判断是否键值冲突

如果键值冲突则一直向下遍历,不冲突则将链表节点放入新篮子中;操作结束swap两个bucket,然后新的bucket局部内存会释放

hash_function:判断元素应该落在哪个bucket中

clear():遍历每一个bucket,将bucket_list中的每一个节点删除,最后将bucket置空,但bucket数组还是原来大小

copy():先clear原数组,再reserve()如果空间不如对方则增大,都是调用vector中的函数,然后遍历目标数组,先拷贝bucket中的节点,再拷贝每一个节点

find(key):先通过hashfunc找到key对应的bucket,然后遍历bucket链表,直到找到该键值

set

set<class key, class cmp>:缺省使用less

使用底层容器的型别

注:set的迭代器、指针、引用都被定义为tree的const形式,不允许键被改变

成员:rb_tree tree;

cmp为value_cmp和key_cmp

构造和析构函数:

1、先构造tree(),然后调用tree.unique_insert() 函数插入元素

2、拷贝构造:调用tree的拷贝构造

3、operator=:调用tree的operator=

4、initializer_list:先tree.clear()再调用tree.unique_insert()

迭代器

begin():调用tree.begin()

end():调用tree.end()

容器相关操作:

empty():调用tree.empty()

size():调用tree.size()

max_size():调用tree.max_size()

插入删除操作:

emplace(args):调用tree.emplace_unique();

emplace_hint(hint, args):调用tree.emplace_unique_use_hint();当插入元素接近hint,降低时间复杂度

insert():调用tree.insert_unique();包括左值,右值,迭代器范围

erase(pos):调用tree.erase();

erase(key):调用tree.erase_unique();

erase(firse, last):调用tree.erase();

查找操作:

find(key):调用tree.find(key)

count(key):调用tree.count_unique()

lower_bound(key):调用tree.lower_bound(),找到键值不小于key的第一个位置

upper_bound(key):调用tree.upper_bound(),找到键值大于key的第一个位置

equal_range(key):将 lower_bound 和 upper_bound 以pair形式返回

swap():调用tree.swap()

符号重载

调用tree的重载


map

map<class key, class T, class cmp>

value_type为pair<key, value>

其中cmp为key_cmp,value_cmp需要自己定义

成员:1、value_cmp:通过比较pair.first ;2、re_tree tree

指针、迭代器和引用均为正常,因为可以改变值

构造和析构函数

1、有参构造:先构造tree(),在调用tree.insert_unique()

2、拷贝构造:调用tree的拷贝构造

3、operator=:调用tree的operator=

4、operator=的initializer_list:先clear(),再tree.insert_unique()

迭代器相关:

begin():返回tree.beign()

end():返回tree.end()

容量相关:

empty():返回tree.empty()

size():返回tree.size()

max_size():返回tree.max_size()

元素访问

at():调用lower_bound(),返回it->second;如果key不存在则抛出异常

重载[]:调用lower_bound(),没有的话默认插入调用empalce_hint(),值默认是0

插入删除操作:

empalce(args):调用tree.emplace_unique();

empalce_hine(args):调用tree.emplace_unique_use_hint();

insert(value)左右值:调用tree.insert_unique()

insert(hint, value)左右值:调用tree.insert_unique()

erase(pos):调用tree.earse()

ersae(key):调用tree.erase_unique()

erase(firse, last):调用tree.earse()

map相关操作

find():调用tree.find()

count():调用tree.count_unique()

lower_bound():调用tree.lower_bound()

upper_bound():调用tree.upper_bound()

equal_range():调用tree.equal_range_unique()

swap():调用tree.swap()

重载操作符:调用tree的重载


unordered_set

class<class key, class hash, class key_equal> hash缺省使用hash函数,key_equal缺省使用equal_to

成员:一个hashtable ht

构造和析构函数:

1、默认bucket_count为100

2、有参构造函数(迭代器):for循环调用ht.insert_unique_noresize()

3、拷贝构造函数:调用ht的拷贝构造

4、operator=:如果是initializer_list,先clear(),再reserve(list.size()),然后循环调用ht.insert_unique_noresize()

迭代器相关

begin():调用ht.begin()

end():调用ht.end()

容器相关

empty():调用ht.empty()

size():调用ht.size()

max_size():调用ht.max_size()

修改容器操作

emplace(args):调用ht.empalce_unique()

emplace(args, hint):调用ht.empalce_unique_use_hint()

insert(value)左右值:调用ht.insert_unique()/ht.empalce_unique()

insert(hint, value)左右值:调用ht.insert_unique_use_hint()/ht.empalce_unique_use_hin()

erase(pos):调用ht.erase()

erase(key):调用ht.erase_unique()

clear():调用ht.clear()

查找相关

count():调用ht.count_unique()

find():调用ht.find()

equal_range():调用ht.equal_range_unique()

swap():调用ht.swap()

bucket_interface

迭代器类型为local_iterator

begin(n):调用ht.begin(n)

end(n):调用ht.end(n)

bucket_count():调用ht.bucket_count()

max_bucket_count():调用ht.max_bucket_count()

bucket_size(n):调用ht.bucket_size(n)

bucket(key):调用ht.bucket(key)

hash_policy

load_factor():调用ht.load_factor()

max_load_factor():调用ht.max_load_factor()

rehash():调用ht.rehash()

reserve():调用ht.reserve()

符号重载只有 == 和 !=:调用ht的符号/调用ht.equal_range_unique()


unordered_map

unordered_map<class key, class T, class hash, class euqal> 缺省使用hash 和 equal_to

成员:hashtable ht

ht的参数为键值对形式pair<key, value>

构造和析构函数:

1、默认bucket_count为100

2、有参构造函数(迭代器):for循环调用ht.insert_unique_noresize()

3、拷贝构造函数:调用ht的拷贝构造

4、operator=:如果是initializer_list,先clear(),再reserve(list.size()),然后循环调用ht.insert_unique_noresize()

迭代器相关

begin():调用ht.begin()

end():调用ht.end()

容器相关

empty():调用ht.empty()

size():调用ht.size()

max_size():调用ht.max_size()

修改容器操作

emplace(args):调用ht.empalce_unique()

emplace(args, hint):调用ht.empalce_unique_use_hint()

insert(value)左右值:调用ht.insert_unique()/ht.empalce_unique()

insert(hint, value)左右值:调用ht.insert_unique_use_hint()/ht.empalce_unique_use_hin()

erase(pos):调用ht.erase()

erase(key):调用ht.erase_unique()

clear():调用ht.clear()

查找相关操作:

at(key):调用ht.find(key),返回it->second;key不存在则抛出异常

重载[]:调用ht.find(key),如果it->node是空指针,则调用emplace_unique()原地构造键,值为0,返回it->second

count():调用ht.count_unique()

find():调用ht.find()

equal_range():调用ht.equal_range_unique()

swap():调用ht.swap()

bucket_interface

迭代器类型为local_iterator

begin(n):调用ht.begin(n)

end(n):调用ht.end(n)

bucket_count():调用ht.bucket_count()

max_bucket_count():调用ht.max_bucket_count()

bucket_size(n):调用ht.bucket_size(n)

bucket(key):调用ht.bucket(key)

hash_policy

load_factor():调用ht.load_factor()

max_load_factor():调用ht.max_load_factor()

rehash():调用ht.rehash()

reserve():调用ht.reserve()

符号重载只有 == 和 !=:调用ht的符号/调用ht.equal_range_unique()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值