STL容器

迭代器失效

vector:
    1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。
    2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。
    3.当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。

deque迭代器的失效情况:
   1.在deque容器首部或者尾部插入元素不会使得任何迭代器失效。
   2.在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。
   3.在deque容器的任何其他位置的插入和删除操作将使指向该容器元素的所有迭代器失效。

List/set/map

   1.删除时,指向该删除节点的迭代器失效。

   2.list的end迭代器不会因插入删除数据而失效。因为list的end() 实际就是list的首个节点。

   3.红黑树的end实际也是头结点地址。所以它也不会随着元素增删失效的。

    容器替换时需注意:当map、set、list替换为vector、deque时,
        1.需要关注调用insert、erase的位置,erase(it++)在改为顺序容器后不可继续使用。
        2.需关注循环遍历中出现修改insert、erase的位置,end = store.end(),顺序容器不能存储末尾迭代器。

    其实就是关注存在插入删除位置代码,否则易出现迭代器使用bug已发内存问题。

容器判空

    容器的empty()方法用来判空效率高一点点

总结各种容器特点

(1) vector
   内部数据结构:数组。
   随机访问每个元素,所需要的时间为常量。
   在末尾增加或删除元素所需时间与元素数目无关,在中间或开头增加或删除元素所需时间随元素数目呈线性变化。
   可动态增加或减少元素,内存管理自动完成,但程序员可以使用reserve()成员函数来管理内存。
   vector的迭代器在内存重新分配时将失效(它所指向的元素在该操作的前后不再相同)。当把超过capacity()-size()个元素插入vector中时,内存会重新分配,所有的迭代器都将失效;否则,指向当前元素以后的任何元素的迭代器都将失效。当删除元素时,指向被删除元素以后的任何元素的迭代器都将失效。
(2)deque
   内部数据结构:数组。
   随机访问每个元素,所需要的时间为常量。
   在开头和末尾增加元素所需时间与元素数目无关,在中间增加或删除元素所需时间随元素数目呈线性变化。
   可动态增加或减少元素,内存管理自动完成,不提供用于内存管理的成员函数。
   增加任何元素都将使deque的迭代器失效。在deque的中间删除元素将使迭代器失效。在deque的头或尾删除元素时,只有指向该元素的迭代器失效。
(3)list
   内部数据结构:双向环状链表。
   不能随机访问一个元素。
   可双向遍历。
   在开头、末尾和中间任何地方增加或删除元素所需时间都为常量。
   可动态增加或减少元素,内存管理自动完成。
   增加任何元素都不会使迭代器失效。删除元素时,除了指向当前被删除元素的迭代器外,其它迭代器都不会失效。
(4)slist
   内部数据结构:单向链表。
   不可双向遍历,只能从前到后地遍历。
   其它的特性同list相似。
(5)stack
   适配器,它可以将任意类型的序列容器转换为一个堆栈,一般使用deque作为支持的序列容器。
   元素只能后进先出(LIFO)。
   不能遍历整个stack。
(6)queue
   适配器,它可以将任意类型的序列容器转换为一个队列,一般使用deque作为支持的序列容器。
   元素只能先进先出(FIFO)。
   不能遍历整个queue。
(7)priority_queue
   适配器,它可以将任意类型的序列容器转换为一个优先级队列,一般使用vector作为底层存储方式。
   只能访问第一个元素,不能遍历整个priority_queue。
   第一个元素始终是优先级最高的一个元素。
(8)set
   键和值相等。
   键唯一。
   元素默认按升序排列。
   如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。
(9)multiset
   键可以不唯一。
   其它特点与set相同。
   (10)hash_set
   与set相比较,它里面的元素不一定是经过排序的,而是按照所用的hash函数分派的,它能提供更快的搜索速度(当然跟hash函数有关)。
   其它特点与set相同。
(11)hash_multiset
   键可以不唯一。
   其它特点与hash_set相同。
(12)map
   键唯一。
   元素默认按键的升序排列。
   如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。
(13)multimap
   键可以不唯一。
   其它特点与map相同。
(14)hash_map
   与map相比较,它里面的元素不一定是按键值排序的,而是按照所用的hash函数分派的,它能提供更快的搜索速度(当然也跟hash函数有关)。
   其它特点与map相同。
(15)hash_multimap
   键可以不唯一。
   其它特点与hash_map相同。

1.list的end() 实际就是list的首个节点。 end()不会随list中数据增删发生变化。1.红黑树的end实际就是头结点地址。

原文地址:https://www.cnblogs.com/dongzhiquan/p/2292761.html