zoukankan      html  css  js  c++  java
  • 【转】STL容器的实现原理

    STL的容器可以分为以下几个大类:
    一:序列容器, 有vector, list, deque, string.

     : 关联容器,     set, multiset, map, mulmap

                   hash_set,hash_map, hash_multiset, hash_multimap

    其他的杂项: stack, queue, valarray, bitset

     

    STL各个容器的实现:

     

    (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
    按照键进行排序存储, 值必须可以进行比较, 可以理解为set就是键和值相等的map
    键唯一。
    元素默认按升序排列。
    如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。

    (9)multiset
    键可以不唯一。
    其它特点与set相同。

    (10)hash_set
    set相比较,它里面的元素不一定是经过排序的,而是按照所用的hash函数分派的,它能提供更快的搜索速度(当然跟hash函数有关)。hash_setkey进行hash 然后将key放在hash值对应的桶中, 原理可以这样理解, hash_set就是key value相等的hash_map
    其它特点与set相同。

    (11)hash_multiset
    键可以不唯一。
    其它特点与hash_set相同。

    (12)map
    键唯一。
    元素默认按键的升序排列。
    如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。

    (13)multimap
    键可以不唯一。
    其它特点与map相同。

    (14)hash_map
    map相比较,它里面的元素不一定是按键值排序的,而是按照所用的hash函数分派的,它能提供更快的搜索速度(当然也跟hash函数有关)。
    其它特点与map相同。

    (15)hash_multimap
    键可以不唯一。
    其它特点与hash_map相同。

     

     

     

    STL容器的实现原理 

     
    STL共有六大组件
     1、容器。2、算法。3、迭代器。4、仿函数。6、适配器。

    STL容器的实现原理

    STL来管理数据十分方便,省去了我们自己构建数据结构的时间.其实,STL的实现也是基于我们常见的数据结构.


    序列式容器:
    vector-数组,元素不够时再重新分配内存,拷贝原来数组的元素到新分配的数组中。
    list-单链表。
    deque-分配中央控制器map(并非map容器),map记录着一系列的固定长度的数组的地址.记住这个map仅仅保存的是数组的地址,真正的数据在数组中存放着.deque先从map中央的位置(因为双向队列,前后都可以插入元素)找到一个数组地址,向该数组中放入数据,数组不够时继续在map中找空闲的数组来存数据。当map也不够时重新分配内存当作新的map,把原来map中的内容copy的新map中。所以使用deque的复杂度要大于vector,尽量使用vector。


    stack-基于deque。
    queue-基于deque。
    heap-完全二叉树,使用最大堆排序,以数组(vector)的形式存放。
    priority_queue-基于heap。
    slist-双向链表。

    关联式容器:
    set,map,multiset,multimap-基于红黑树(RB-tree),一种加上了额外平衡条件的二叉搜索树。


    hash table-散列表。将待存数据的key经过映射函数变成一个数组(一般是vector)的索引,例如:数据的key%数组的大小=数组的索引(一般文本通过算法也可以转换为数字),然后将数据当作此索引的数组元素。有些数据的key经过算法的转换可能是同一个数组的索引值(碰撞问题,可以用线性探测,二次探测来解决),STL是用开链的方法来解决的,每一个数组的元素维护一个list,他把相同索引值的数据存入一个list,这样当list比较短时执行删除,插入,搜索等算法比较快。


    hash_map,hash_set,hash_multiset,hash_multimap-基于hash table。

    综上所述大家应该知道了什么情况下该使用哪一个STL容器更合适,可以在适当时候避免使用一些影响效率的STL容器.

  • 相关阅读:
    Java内存模型(JMM)是什么?JMM 通过控制主内存与每个线程的本地内存之间的交互,来提供内存可见性保证
    【普及组_在线赛】班级聚会(reuntion)
    面试官:你对Redis缓存了解吗?面对这11道面试题是否有很多问号?
    【华为云技术分享】浅谈产品模型(Profile)在程序设计中的作用
    【华为云技术分享】LiteAI四大绝招,解锁物联网智能设备AI开发难关
    【华为云技术分享】漫谈Huawei LiteOS五大内核模块
    科技感满满,华为云DevCloud推出网页暗黑模式
    赶在520之前,程序员如何用Python送上最特别的“我爱你”表白
    【华为云技术分享】从部署和运维说说DLI(1)
    【2017.11.25普及组模拟】The Farthest House题解
  • 原文地址:https://www.cnblogs.com/zhiqli/p/3078006.html
Copyright © 2011-2022 走看看