STL-vector,stack,list,queue

vector是可以快速地在最后添加删除元素,并可以快速地访问任意元素
list是可以快速地在所有地方添加删除元素,但是只能快速地访问最开始与最后的元素
deque在开始和最后添加元素都一样快,并提供了随机访问方法,像vector一样使用[]访问任意元素,但是随机访问速度比不上vector快,因为它要内部处理堆跳转
deque也有保留空间.另外,由于deque不要求连续空间,所以可以保存的元素比vector更大,这点也要注意一下.还有就是在前面和后面添加元素时都不需要移动其它块的元素,所以性能也很高。

因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面
的原则:
1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。

cber:很遗憾地告诉你,你的回答只对了一半:((,看来老虎也有打盹的时候啊。

下面是“GotW #074”的主要内容,我知道你一定更喜欢看原文,但我贴此文是为了照顾一些刚学C++的朋友。

GotW #074主要内容:

// Example 1: [] vs. at()//void f( vector<int>& v ){  v[0];      // A  v.at(0);   // B}在这个例子中,如果v不是空的,则A句和B句无分别。若v是空的,那么B句会throw一个std::out_of_range的exception;C++ Standard从效率和兼容‘内建型别’上考虑,并不要求A句throw出exception。即vector<T>::at()有下标越界检查(Bounds checking),而vector<T>::operator []()一般(注意是一般,C++ Standard并没有说operator[]一定不能做下标越界检查)没有做下标越界检查。如果向operator[]传入非法的下标,其行为“不可预测”

// Example 2: Some fun with vectors

vector<int> v;

v.reserve( 2 );assert( v.capacity() == 2 );1. 如cber所说,v.reserve(2)表示v的内部缓冲区至少能容纳2个元素,而不一定刚好容纳2个元素(可能更多)。vector的大小是按指数增长的,即cber所说“选择2的n次方来分配空间”,这句话应该改为assert( v.capacity() >= 2 );

2. 其实这个assert( v.capacity() >= 2 );也是多余的,因为C++ Standard保证执行v.reserve(n);后, 一定有v.capacity() >= n;即在vector<T>::reserve()中已经做了类似的assert,你又何必自己再来做重复的工作呢?除非你对你的C++  Standard Libaray的健壮性不放心:)。

v[0] = 1;v[1] = 2;这两条语句有明显的错误:v.reserve()只是增加了vector的存储空间,并没有增加其中元素的个数。这时v仍然是空的(v.size() == 0,v.capacity() >= 2),所以这里下标越界了。可以考虑改为v.push_back(1);v.push_back(2);

for( vector<int>::iterator i = v.begin(); i < v.end(); i++ ){  cout << *i << endl;}1. 这个循环不会打印任何东西,因为此时v是空的。2. 尽量使用const,这里的iterator并没有改动v的元素,所以应该用const_iterator3. 循环的结束条件处,比较两个iterators应该用 != 而非 < ,只有random-access iterator才能用 “<”来比较,而作为循环的结束条件,更加普遍的做法是用 “!=”来比较iter与v.end()。4. 用++i取代i++,两者效率不同。5. 避免不必要的重复计算,因为v.end()的值在循环中没有变,所以在循环之前对v.end()求一次值就可以了。6. 用‘\n‘替代endl,因为使用endl会强制flush(冲洗) ostream的内部输出缓冲区,如果你不是每打印一个*i就需要flush一次缓冲区的话,用‘\n‘。7. 使用标准的演算法,可以避免以上所有问题:copy( v.begin(), v.end(), ostream_iterator<int>(cout, "\n") );另外,似乎没有copy( v.begin(), v.end(), ostream_iterator<int>(cout, endl) );这种写法,所以当你确实需要每打印一行就flush一次缓冲区时,自己写一个copy()吧。

cout << v[0];一般情况下,输出1,其实v[0]是越界了。

v.reserve( 100 );assert( v.capacity() == 100 );同上,这里的assert是不正确且多余的。这里v重新分配(realloc)了缓冲区,但它认为自己只有0个元素,故原来的v[0] == 1并没有复制到新的缓冲区,所以新的v[0] == 0;所以下一句cout << v[0];会打印0,这一定会气倒一片人的。

v[2] = 3;v[3] = 4;// ...v[99] = 100;首先下标越界,其次按cber说的可以用for_each()

for( vector<int>::iterator i = v.begin();    i < v.end(); i++ ){  cout << *i << endl;}改为:copy( v.begin(), v.end(), ostream_iterator<int>(cout, "\n") );关于用STL演算法取代自己编写循环的进一步讨论,请参看CUJ 2001十月,Scott Meyers写的《STL Algorithms vs. Hand-Written Loops》一文

好多的陷阱啊,一不小心就掉进去了,非得好好看看Effective STL / Exceptional C++不可。我晕了,你晕了没有?
vector:
Constructors 构造函数
Operators 对vector进行赋值或比较
assign() 对Vector中的元素赋值
at() 返回指定位置的元素
back() 返回最末一个元素
begin() 返回第一个元素的迭代器
capacity() 返回vector所能容纳的元素数量(在不重新分配内存的情况下)
clear() 清空所有元素
empty() 判断Vector是否为空(返回true时为空)
end() 返回最末元素的迭代器(译注:实指向最末元素的下一个位置)
erase() 删除指定元素
front() 返回第一个元素
get_allocator() 返回vector的内存分配器
insert() 插入元素到Vector中
max_size() 返回Vector所能容纳元素的最大数量(上限)
pop_back() 移除最后一个元素
push_back() 在Vector最后添加一个元素
rbegin() 返回Vector尾部的逆迭代器
rend() 返回Vector起始的逆迭代器
reserve() 设置Vector最小的元素容纳数量
resize() 改变Vector元素数量的大小
size() 返回Vector元素数量的大小
swap() 交换两个Vector 

list:
assign() 给list赋值
back() 返回最后一个元素
begin() 返回指向第一个元素的迭代器
clear() 删除所有元素
empty() 如果list是空的则返回true
end() 返回末尾的迭代器
erase() 删除一个元素
front() 返回第一个元素
get_allocator() 返回list的配置器
insert() 插入一个元素到list中
max_size() 返回list能容纳的最大元素数量
merge() 合并两个list
pop_back() 删除最后一个元素
pop_front() 删除第一个元素
push_back() 在list的末尾添加一个元素
push_front() 在list的头部添加一个元素
rbegin() 返回指向第一个元素的逆向迭代器
remove() 从list删除元素
remove_if() 按指定条件删除元素
rend() 指向list末尾的逆向迭代器
resize() 改变list的大小
reverse() 把list的元素倒转
size() 返回list中的元素个数
sort() 给list排序
splice() 合并两个list
swap() 交换两个list
unique() 删除list中重复的元素 

stack:
操作 比较和分配堆栈
empty() 堆栈为空则返回真
pop() 移除栈顶元素
push() 在栈顶增加元素
size() 返回栈中元素数目
top() 返回栈顶元素 

queue:
back() 返回最后一个元素
empty() 如果队列空则返回真
front() 返回第一个元素
pop() 删除第一个元素
push() 在末尾加入一个元素
size() 返回队列中元素的个数
时间: 2024-10-21 16:50:30

STL-vector,stack,list,queue的相关文章

STL之stack 和 queue

这两种容器在STL中被称为是适配器,是对deque的一种限制容器,操作仅仅可以在头部或者是尾部进行. STL中的stack默认是用deque来实现的,但是我觉得用list实现第更高效一点,简单的slist就可以这样做. 当然也可以使用vector来进行实现,不过vector的生长确实是要考虑的范畴,因此觉得单纯的stack用单向列表进行实现就很好了. template <class _Tp, class _Sequence> class stack { // requirements: __S

STL容器用法速查表:list,vector,stack,queue,deque,priority_queue,set,map

STL容器用法速查表:list,vector,stack,queue,deque,priority_queue,set,map   list vector deque stack queue priority_queue set [unordered_set] map [unordered_map] multimap [unordered_multimap]     contiguous storage double-ended queue LIFO FIFO 1st is greatest  

STL学习——Stack/Queue篇

STL学习--Stack/Queue篇 Stack 概述 stack是一种先进先出的数据结构,只有一个出口,stack允许新增元素,移除元素,取得最顶端元素.但除了最顶端外,没有任何办法可以存取stack其他元素.即不允许遍历行为. 实现 stack实现是以容器为底部结构的,将容器的接口改变,使其符合"先进先出"特性,便形成了一个栈.具体实现可以将底部deque的头端开口封闭,便实现了stack.因为stack具有"修改某物接口,形成另一种风貌"性质,故称为&quo

STL之stack容器和queue容器

摘要:本文主要介绍了两种容器——stack容器和queue容器. 1.基本概念   stack容器 queue容器 容器介绍 stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口, 形式如图所示.stack容器允许新增元素,移除元素,取得栈顶元素,但是除了 最顶端外,没有任何其他方法可以存取stack的其他元素.换言之,stack不允 许有遍历行为. 有元素推入栈的操作称为:push,将元素推出stack的操作称为pop. Queue是一种先进先出(

STL ——vector 学习

STL简介 C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), lists(链表), 和 stacks(栈)等.  C++ STL 提供给程序员以下三类数据结构的实现: 标准容器类   顺序性容器  vector 从后面快速的插入与删除,直接访问任何元素  deque 从前面或后面快速的插入与删除,直接访问任何元素 list 双链表,从任何地方快速插入与删除   关联容器  

STL之容器适配器queue的实现框架

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 上篇文章STL之容器适配器stack的实现框架已经介绍了STL是如何借助基础容器实现一种常用的数据结构stack (栈),本文介绍下另外一种STL内部定义的另外一种STL容器适配器queue(队列). 对于接触过数据结构的人来说,队列并不陌生,它是一种FIFO(first in first out)的数据结构.与栈相比,队列的不同之处在于:(1)队列是一种先进先出的数据结构,而栈则是一种后进先出的数据结构:(2)队列支持首尾两端的访问操作,而栈

STL之stack适配器的实现框架

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 一提到适配器(adapter),我们就想到了早期用电话线上网所用的调制解调器,俗称"猫","猫"的作用是实现数模转化和模数转化,在客户端,它可以将电话的模拟信息转化为我们计算机能够接收的数字信息,所以猫相当于一个转换器.再举个更加好理解的例子来说明"适配器"的含义.相信在我们每个人的家里都有插排,假设就这么一种情况,现在我们家里的墙壁上只有一个三角的插口,而我们的电视却是两个口,怎么办?毫无疑问

C++ Primer 学习笔记_55_STL剖析(十):容器适配器(stack、 queue 、priority_queue)源码浅析与使用示例

七种基本容器:vector.deque.list.set.multiset.map.multimap 一.容器适配器 stack queue priority_queue stack.queue.priority_queue 都不支持任一种迭代器,它们都是容器适配器类型,stack是用vector/deque/list对象创建了一个先进后出容器:queue是用deque或list对象创建了一个先进先出容器:priority_queue是用vector/deque创建了一个排序队列,内部用二叉堆实

java中List、Map、Set、Collection、Stack、Queue等的使用

java中这几个东西是比较常用的,虽然我用的不多,也正是因为用的不多,所以我一直搞不清楚他们之间的具体用法以及相互之间的关系,现在特单独作为一个东西来总结一下. 本文参考一下资料: 1.<java编程思想>一书第11章 2.http://blog.sina.com.cn/s/blog_a345a8960101k9vx.html 3.http://f51889920.iteye.com/blog/1884810 4.http://blog.csdn.net/speedme/article/det

java中List、Map、Set、Stack、Queue、Collections等的使用

java中List.Map.Set.Stack.Queue.Collections等的使用 List 创建方法: List<String> list=new ArrayList<>(); add(val) : 添加元素. get(index) : 获取元素. remove(index) : 删除元素. remove(Object o) : 按照元素内容删除 {eg:list.add("marry") ; list.remove(0)==list.remove(&