STL中关于map和set的一些问题
2015-10-20 10:09
323 查看
1,STL封装了许多复杂的数据结构算法和大量常用数据结构操作,如vector封装数组,list封装了链表,map和set封装了二叉树等,另外STL采用自己的Allocator分配内存,以内存池的方式来管理这些内存,大大减少内存碎片的产生,从而提升系统的整体性能
2, STL中标准关联容器set,multiset, map, multimap内部采用的是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-BlackTree)。RB树的统计性能要好于一般的平衡二叉树(有些书籍根据作者姓名,Adelson-Velskii和Landis,将其称为AVL-树),所以被STL选择作为了关联容器的内部结构
3,为何map和set的插入删除效率比用其他序列容器高?
因为对于关联容器来说,不需要做内存拷贝和内存移动,map和set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点,因此插入的时候只需把节点的指针指向新的节点,删除的时候把指向删除节点的指针指向其他节点就好了,一切操作都是指针操作,和内存无关,所以效率高
4,为何每次insert之后,以前保存的iterator不会失效?
iterator相当于指向节点的指针,内存没有变,指向内存的指针自然不会失效(当然被删除的元素本身已经失效了)。相对于vector来说,每一次删除和插入,指针都有可能失效,调用push_back在尾部插入也是如此。因为为了保证内部数据的连续存放,iterator指向的那块内存在删除和插入过程中可能已经被其他内存覆盖或者内存已经被释放了。即使是push_back的时候,容器内部空间可能不够,需要一块新的更大的内存,只有把以前的内存释放,申请新的更大的内存,复制已有的数据元素到新的内存,最后把需要插入的元素放到最后,那么以前的内存指针自然就不可用了。特别是在和find等算法在一起使用的时候,牢记这个原则:不要使用过期的iterator
5,为何map和set不能像vector一样有个reserve函数来预分配数据?
map和set内部存储的不仅仅是元素本身,还包括元素的节点信息,所以不能用reserve函数来预分配数据
6,当数据元素增多时(10000和20000个比较),map和set的插入和搜索速度变化如何?
map和set中查找是使用二分查找,时间复杂度为logn,当元素增大时,插入和搜索速度并不会受到太多影响
2, STL中标准关联容器set,multiset, map, multimap内部采用的是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-BlackTree)。RB树的统计性能要好于一般的平衡二叉树(有些书籍根据作者姓名,Adelson-Velskii和Landis,将其称为AVL-树),所以被STL选择作为了关联容器的内部结构
3,为何map和set的插入删除效率比用其他序列容器高?
因为对于关联容器来说,不需要做内存拷贝和内存移动,map和set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点,因此插入的时候只需把节点的指针指向新的节点,删除的时候把指向删除节点的指针指向其他节点就好了,一切操作都是指针操作,和内存无关,所以效率高
4,为何每次insert之后,以前保存的iterator不会失效?
iterator相当于指向节点的指针,内存没有变,指向内存的指针自然不会失效(当然被删除的元素本身已经失效了)。相对于vector来说,每一次删除和插入,指针都有可能失效,调用push_back在尾部插入也是如此。因为为了保证内部数据的连续存放,iterator指向的那块内存在删除和插入过程中可能已经被其他内存覆盖或者内存已经被释放了。即使是push_back的时候,容器内部空间可能不够,需要一块新的更大的内存,只有把以前的内存释放,申请新的更大的内存,复制已有的数据元素到新的内存,最后把需要插入的元素放到最后,那么以前的内存指针自然就不可用了。特别是在和find等算法在一起使用的时候,牢记这个原则:不要使用过期的iterator
5,为何map和set不能像vector一样有个reserve函数来预分配数据?
map和set内部存储的不仅仅是元素本身,还包括元素的节点信息,所以不能用reserve函数来预分配数据
6,当数据元素增多时(10000和20000个比较),map和set的插入和搜索速度变化如何?
map和set中查找是使用二分查找,时间复杂度为logn,当元素增大时,插入和搜索速度并不会受到太多影响
相关文章推荐
- SQL8数据库定期自动备份
- 基于ArcGIS API for JavaScript的统计图表实现
- Windows Update 时出现8024402C的错误
- 函数式编程收藏
- DotNet中的HTTP操作
- 遍历Map的四种方法
- 【Fix】自己动动手修理鼠标滚轮回跳
- 扩展GridView控件――为内容项添加拖放及分组功能
- 给xcode添加预编文件的方法
- Qt学习笔记 线程(一)
- unity安卓打包的问题
- 常用服务器日志分析命令大全(二)
- 修饰函数和函数返回值的const的差别
- 调整好心态
- 一次线上多线程程序问题排查
- 用replace()方法去除双引号
- 虚拟化数据中心的网络“指挥塔”
- Discuz function_core 常用函数解析
- 全面认识桥接、交换和路由等相关知识
- HTTP响应头和请求头信息对照表