我之前的博文中有专门的5篇整理并介绍了STL的概念:

STL1——整体介绍:https://www.cnblogs.com/grooovvve/p/10467794.html

STL2——泛型编程(模板类、迭代器):https://www.cnblogs.com/grooovvve/p/10467797.html

STL3——函数对象:https://www.cnblogs.com/grooovvve/p/10467800.html

STL4——算法:https://www.cnblogs.com/grooovvve/p/10491685.html

STL5——其他库总结:https://www.cnblogs.com/grooovvve/p/10491705.html

通过复习和提炼其实有助于加深对这些概念的理解。

STL 的英文全称叫做Standard Template Library,就是标准模板库的意思。

STL编程是一种泛型编程的思想。泛型的体现就是使用模板类来编程,模板类使得类可以独立于具体的数据类型;

这样子编程更加灵活,增强代码的复用;

STL中提供了一组容器迭代器函数对象、和算法模板;STL是提供了一组模板

====================================================

一、什么是容器:

容器是用来存储数据的,数据的类型可以是用户自定义的,也可以是预定义的。

这里主要要关注七大类容器:vector、list、deque、map、set、stack、queue;

这七大类容器按类型可分为三种

  顺序性容器:vector、list、deque;

  关联性容器:set、map(及其衍生的multiset、multimap);

  容器适配器:stack、queue;

接下来分别介绍一下这七大容器,然后再对三种容器类型进行总结;

1、vector:中文名叫做向量,其实就是一种封装了动态大小的数组的顺序性容器、也可以理解成一个序列。可以把它简单理解成存放任意数据类型的动态数组。和静态数组一样具有随机访问的能力。也就是说访问任意索引的元素的时间复杂度都是O(1)。vector支持对序列中的任意元素进行快速直接访问。 

对于vector的操作有很多,最常见的几种先熟悉一下:

  push_back() 往序列尾加入元素;

  empty() 判断向量是否为空;

  size() 判断向量中元素的个数;

  当然顺序性容器的特点就是可以用for循环进行遍历;

2、list:其底层实现是一种双向链表结构,所以相比于vector而言,其允许快速的插入和删除,但是随机访问比较慢。 vector的随机插入和删除比list慢,但是随机访问快。所以二者也算是各有优劣,根据实际情况选择性使用哪种。

3、deque:更像是vector的升级版,是一个双端的动态数组,无论在尾部还是在头部插入元素都比较迅速。但是在中间插入元素比较慢。

所以总结来看vector、deque的本质就是数组、list的本质就是链表。

之前的vector、deque是方便访问,不方便修改元素;list是方便修改元素,不方便访问。

那么对于一些既要修改又要访问的场景,该怎么办?这就涉及set(集合) 和map(映射、字典);

首先我们要知道set、map都是高级的数据结构,其底层实现是可以不一样的,可以是某种搜索树结构、也可以用哈希表实现。

哈希表的实现可以使得访问、修改元素的时间复杂度都为O(1)。但是会失去了数据的顺序性。

结构的访问和修改都是O(logn)级别的,也就是说是折中了访问和修改的性能。而且数据具有顺序性。

set、map主要用于解决一些查找问题。查找有无查找对应关系(例如:元素-频率)。

4、set :是一种关联性容器,存储了一堆同类型的元素,这些元素必须都是唯一的。

A standard container made up of unique keys, which can be retrieved in logarithmic time.

  常见的操作有:

  find()  查找元素是否存在;

  insert() 插入元素

  empty() 集合是否为空;

  ...

  

5、map:map中的元素是成对存在的,我们管它叫做键值对,C++中有pair、make_pair去声明和构建键值对。折中键值对适合用于查找对应关系,例如某个元素出现的频率等。

  常见的操作有:

  find()  查找元素是否存在;

  insert() 插入元素;

  empty() 集合是否为空;

  ...

  有一种map叫做unordered_map,其底层实现是哈希表,因此其查找速度非常快,缺点是哈希表的建立比较费时而且占用内存。对于查找问题使用unordered_map会跟快。同理set也有对应的unordered_set;这种set、map我们管它叫无序集合、无序映射。

stack栈、queue队列、priority_queue优先队列也是高级的数据结构,其底层实现可以是数组、也可以是链表。

6、stack 

  栈的特点是只能对栈顶元素进行操作。是一种先进后出的结构FIFO

  栈的操作:主要有压栈push、出栈pop、查看栈顶元素top、是否为空empty;

  栈的结构和操作虽然简单,但是使用起来非常灵活。

  而且栈和递归的关系非常密切。递归的操作就是通过栈的结构实现的。

  栈顶元素反应了嵌套的层次关系中,最近要匹配的元素。

  二叉树的的前中后序递归遍历、非递归遍历实际上就是应用了栈的原理;

7、queue

  是一种先进先出的结构FILO。队尾进元素,队首出元素。

  优先队列比较特殊的是出队的逻辑发生了改变,最高优先级的元素先出队。这个最搞优先级怎么定义视情况而定。实际上优先队列的底层实现是堆的结构(最大堆、最小堆)。堆的底层实现实际上是树的结构。链表实际上是特殊的树。这里不展开讲了。

  队列的操作有:入队push、出队pop、获取对顶元素top、队列是否为空empty;

====================================================

二、关于迭代器:

  在数组这样的结构中,遍历所有的元素显得很自然很方便。就是用数组下标访问即可。

  但是要遍历STL的容器中元素该怎么做呢?这就要使用迭代器。迭代器本质是一种对象。

  每种容器,都有其对应的迭代器对象。声明了相应容器的迭代器对象之后,就可以用迭代器访问该容器的任一元素。

  迭代器最重要的意义在于,其使用起来都是一样的且十分方便,屏蔽了不同容器的差异。

 

例如下方代码,使用迭代器iter遍历prority_queue中所有元素。容器提供了两种方法begin()、end()表示容器的第一个和最后一个元素。

迭代器的累加重载了++运算符,使得使用起来相当方便。

         priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;
for(unordered_map<int,int>::iterator iter = freq.begin(); iter!=freq.end(); iter++)
{
if(pq.size()==k)
{
if(iter->second > pq.top().first)
pq.pop();
pq.push(make_pair(iter->second,iter->first));
}
else
pq.push(make_pair(iter->second,iter->first));
}

====================================================

  

  

C++Review7_STL、容器、迭代器的更多相关文章

  1. 把《c++ primer》读薄(3-2 标准库vector容器+迭代器初探)

    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 标准库vector类型初探,同一种类型的对象的集合(类似数组),是一个类模版而不是数据类型,学名容器,负责管理 和 存储的元素 ...

  2. STL容器迭代器失效分析

    连续内存序列容器(vector, string, deque) 对于连续内存序列STL容器,例如vector,string,deque,删除当前iterator会使得后面所有的iterator都失效, ...

  3. Java容器---迭代器

    任何容器类,都必须有某种方式可以插入元素并将它们再次取回.毕竟,持有事物是容器最基本的工作. 对于List, add0是插入元素的方法之一,而get()是取出元素的方法之一. 如果从更高层的角度思考, ...

  4. STL容器迭代器失效问题讨论

    STL源码剖析---迭代器失效小结 vector迭代器的几种失效的情况: .当插入(push_back)一个元素后,end操作返回的迭代器肯定失效. .当插入(push_back)一个元素后,capa ...

  5. C++ Primer : 第十一章 : 关联容器之关联容器的迭代器和操作

    关联容器的操作 除了和顺序容器定义的类型之外,关联容器还定义了一下几种类型: 关联容器额外的类型别名  key_type    此容器类型的关键字类型 mapped_type  每个关键字关联的类型, ...

  6. C++ Primer 阅读笔记:迭代器和容器 小结

    原创 by zoe.zhang  0.写在前面的话 我是在2011年学的C++,但是那一年恰好是C++11新标准的一年,但是大学上学的C++还是基于C++98的风格的,使用的编译器也是VC6.0,啊, ...

  7. 疯子的算法总结(三) STL Ⅱ迭代器(iterator) + 容器

    一.迭代器(Iterator) 背景:指针可以用来遍历存储空间连续的数据结构,但是对于存储空间费连续的,就需要寻找一个行为类似指针的类,来对非数组的数据结构进行遍历. 定义:迭代器是一种检查容器内元素 ...

  8. C++ 顺序容器

    <C++ Primer 4th>读书笔记 顺序容器内的元素按其位置存储和访问.容器类共享公共的接口,每种容器类型提供一组不同的时间和功能折衷方案.通常不需要修改代码,只需改变类型声明,用一 ...

  9. C++STL之迭代器

    迭代器 迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围.迭代器就如同一个指针.事实上,C++的指针也是一种迭代器.但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值.例如, ...

  10. C++ 迭代器 基础介绍

    C++ 迭代器 基础介绍 迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围.迭代器就如同一个指针.事实上,C++的指针也是一种迭代器.但是,迭代器不仅仅是指针,因此你不能认为他们一定 ...

随机推荐

  1. SpingMVC ModelAndView, Model,Control以及参数传递总结

    1.web.xml 配置: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <servlet>     <servlet-name>dispatcher& ...

  2. linux查看用户组所有成员

    1.grep 'user1' /etc/group //找出用户组的gid user1:x:1004://得出gid=1004 2. awk -F":" '{print $1&qu ...

  3. LeetCode110 Balanced Binary Tree

    Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary ...

  4. git 本地仓库操作

    一.git对象模型和存储 二.常用命令 1)git checkout branch 切换分支 假设现在有两个分支,master和dev分支 i dev分支上没有readme.txt 在master分支 ...

  5. 12 Top Open Source Data Analytics Apps

    1. Hadoop It would be impossible to talk about open source data analytics without mentioning Hadoop. ...

  6. laravel 5.6 请教邮件中的cc,bcc是什么意思,有什么用?

    cc指抄送 bcc指暗送. cc:carbon copy bcc:blind carbon copy

  7. python实用工具包

    文本处理 FlashText     大规模关键字搜索利器,据说多余500个关键字时性能会明显优于正则表达式,暂未评测! 调试利器 pysnooper     不需要使用print进行调试

  8. SuperSocket命令加载器 (Command Loader)

    在某些情况下,你可能希望通过直接的方式来加载命令,而不是通过自动的反射. 如果是这样,你可以实现你自己的命令加载器 (Command Loader): public interface IComman ...

  9. Linux查看用户及其权限管理

    https://www.cnblogs.com/fxlttkl/p/7601224.html 查看用户 请打开终端,输入命令: $ who am i 或者 $ who mom likes 输出的第一列 ...

  10. 【JQ】toggle / slideToggle / fadeToggle 的区别

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...