导读:
声明,所有的朋友,如果要转我的帖子,务必注明"作者:黑啤 来源:CSDN博客"和具体的网络地址http://blog.csdn.net/nx500/archive/2007/10/22/1837810.aspx,并且我的所有博客内容,禁止任何形式的 商业用途,请大家尊重我的劳动.谢谢!
目 录九.顺序容器.
001 顺序容器类型.
vector 支持快速随机访问.
list 支持快速插入删除.
deque 双端队列.
顺序容器适配器.
stack 后进先出栈LIFO.
queue 先进先出栈FIFO.
priority_queue 有优先级管理的队列.
002 顺序容器的定义,所有的容器都是模板,要定义具体的容器,必须在容器名后加一对尖括号,括号里提供容器存放元素的类型.
#include
#include
#include
vector svec;
list ilist;
deque items;
003 顺序容器的构造函数
C c; 创建一个名为c的空容器
C c(c2); 创建容器c2的副本c,c和c2必须具有相同的容器类型.
C c(b, e); 创建容器c,其元素是迭代器b和e标示范围内的元素的副本,e标示一个停止指针,指向的内容并不复制.
C c(n, t); 用n个t元素创建容器c,只适合顺序容器,不适合关联容器
C c(n); 创建n个值初始化的元素的容器c.只适合顺序容器,不适合关联容器
vector ivec;
vector ivec2(ivec); // ok.
list ilist(ivec); // error, ivec是vector类型,而ilist是list类型.
vector dvec(ivec); // error, 容器内的元素类型不同.
004 将一个容器复制给另一个容器时,类型必须匹配:容器类型和元素类型都必须相同.
使用迭代器时,不要求容器类型相同,容器内的元素类型也可以不同,只要它们互相兼容,能够将要复制的元素转换为所构建的新容器所构建的元素类型.
采用这种方式可以复制不能直接复制的容器,特别的,可以复制另外容器的一个子序列.
list slist(svec.begin(), svec.end());
vector ::iterator mid = svec.begin() + svec.size()/2;
deque front(svec.begin(), mid);
deque back(mid, svec.end());
类似的,可以通过内置数组的指针来初始化一个容器.
char *words[] = {"stately", "plump", "buck", "mulligan"};
size_t words_size = sizeof(words)/sizeof(char *);
list wordsList(words, words + words_size);
初始化指定数目的元素.
const list ::size_type list_size = 64;
list slist2(list_size, "heipi o");
list ilist2(list_size);
005 容器元素的限制:必须支持赋值运算,对象必须可以复制.引用类型不可以作为容器的元素(不能赋值),标准输入输出不能作为容器的元素.
如果类没有默认的构造函数,那么在定义容器的时候,必须定义空的容器,或者提供显式构造函数的参数.
假设Foo只有一个需要一个int参数的构造函数,那么:
vector empty; // ok
vector bad(2); // error, 无法默认的创建元素,所以不行.
vector fine(2, 0); // ok, 通过参数0,创建两个元素.
可以定义容器的容器.
vector< vector lines;
lines.push_back(svec);
006 常用的迭代器运算.
*iter 返回迭代器iter所指向的元素的引用.
iter->mem 对iter解引用,获取指定元素中mem的成员,等效于(*item).mem
++iter/iter++/--iter/iter--
iter1 == iter2 比较两个迭代器是否指向同一个元素 (iter1 != iter2).
vector 和 deque容器的额外运算.
iter +/- n
iter +/- = n
iter1 - iter2
>, >=, <, <=
注意啦:在list容器中不支持" +/- n"的操作,也不支持逻辑关系运算.
007 使用迭代器编写程序时,必须留意那些使迭代器失效的操作,防止野指针问题.通常,要求涉及迭代器的代码尽可能短小.
008 容器定义的类型.
size_type
iterator
const_iterator
reverse_iterator
const_reverse_iterator
difference_type
value_type 元素的类型.
reference 元素的引用类型 value_type&
const_reference 元素的常量左值类型.
009 容器的begin和end操作,每个操作还和容器是否为const有关.
c.begin() / c.end()
c.rbegin() / c.rend()
010 容器中添加元素的操作
c.push_back(t) 在末尾加t,返回void.
c.push_front(t) 只适用于list和deque容器类型,返回void.
c.insert(p, t) 在p的前边插入t,返回指向新添加元素的迭代器.
c.insert(p, n, t) 在p的前边插入n个t,返回void.
c.insert(p, b, e) 在p的前边插入迭代器b和e之间的元素,返回void.
添加单个元素.
vector
list slist;
string spouse("Beth");
// 等同于slist.push_front(spouse).
slist.insert(slist.begin(),spouse);
// vector没有push_front,但是可以采用在begin前插入的方式实现该功能.
// 要注意,对于vector容器,在前部或中间插入元素,是非常耗费资源的一个行为.
svec.insert(svec.begin(),spouse);
// 借用insert(p,t)的返回值,循环向容器的头部添加元素.
list ::iterator iter = slist.begin();
while(cin >>spouse){
iter = ilist.insert(iter, spouse);
}
插入一段元素.
svec.insert(svec.end(), ilist.begin(), ilist.end());
string sarr[4] = {"wangyi", "aichao", "master", "huawei"};
svec.insert(svec.begin(), sarr, sarr + 4);
要注意,添加元素可能造成迭代器失效.比如在vector中添加元素,可能会导致整个容器的重新加载,迭代器自然也就无效了.
因此不要保存begin()或end()操作的返回值,而是每次使用时都要执行一次该函数.
vector ::iterator first = v.begin();
while(first != v.end()){
first = v.insert(first, 42);
++first;
}
011 关系操作符.容器的比较是基于容器内元素的比较,如果元素不支持某种类型的比较,容器也就不能做这种比较运算.
如果两个容器具有相同的长度而且所有元素相等,那么两个元素就相等.
如果两个容器的长度不相同,但较短的容器中所有元素都等于较长容器中对应的元素,则称较短的容器小于另一个容器.
如果两个容器都不是对方的初始子序列,则它们的比较结果取决于所比较的第一个不相等的元素.
/*
ivec1: 1 3 5 7 9 12
ivec2: 0 2 4 6 8 10 12
ivec3: 1 3 9
ivec4: 1 3 5 7
ivec5: 1 3 5 7 9 12
*/
ivec2
ivec1
ivec4
ivec1 == ivec5
012 容器大小的操作.
c.size()
c.max_size() 返回类型是c::size_type.
c.empty()
c.resize(n) 如果n
c.resize(n,t) 新添加的元素,都用t来初始化.resize操作可能会使迭代器失效.
013 访问元素.如果容器非空,那么容器的front()和back()成员将返回容器内第一个和最后一个元素的"引用".
注意:返回的是引用,begin()和end()返回的是指针.
if (!list.empty()){
list /> ::reference
list ::reference val2 = ilist.front();
list ::reference last1 = *--ilist.end();
list ::reference last2 = ilist.back();
}
其他操作.
c[n] 这两个操作,只适用于vector和deque容器.
c.at(n) 如果给出的下标无效,at函数会抛出out_of_range异常,所以推荐使用,最好还是用迭代器.
如果容器为空,那么所有访问容器的操作都是没有定义的(也就是说只有鬼才知道会返回点什东西),导致程序出现严重的错误.
014 删除元素.
c.erase(p) 删除迭代器p指向的元素,返回被删除元素后边元素的迭代器.
c.erase(b, e) 删除迭代器b和e范围内的元素,返回被删除段后面元素的迭代器.
c.clear() 删除容内全部的元素,返回void.
c.pop_back() 删除容器c的最后一个元素,返回void,c不能为空.
c.pop_front() 删除容器c的第一个元素,返回void,c不能为空,只适用于list或deque.
删除第一个或者最后一个元素,注意,pop_back()和pop_front()都是不返回值的.
while(!ilist.empty()){
// process(ilist.front());
ilist.pop_front();
}
删除容器内的一个元素,要注意,erase是不检查迭代器参数是否有效的.
string searchValue("Quasimodo");
list ::iterator iter = find(slist.begin(), silist.end(), searchValue);
if(iter != slist.end())
slist.erase(iter);
删除容器内的所有元素.
slist.clear();
slist.erase(slist.begin(), slist.end());
015 赋值与swap.除swap外,所有的操作,都可以用earse和insert取代.
c1 = c2
c1.swap(c2) 用c2容器的元素取代c1容器的元素.
c.assign(b, e) c中原来的元素清空,将迭代器b和e标记范围内的所有元素复制到c中.
c.assign(n, t)
带有一对迭代器的assin函数,允许我们将一个容器的元素赋给另一个不同类型的容器.
016 容器的capacity和reserve成员.
为了使vector容器实现快速的内存分配,其实际分配的容量要比当前所需的空间多一些.vector容器预留了这些额外的存储区,用于存放新添加的元素.
于是,不必为每个新元素重新分配空间,所以,比起list和deque容器,vector的增长效率要高一些.
vector ivec;
cout<< "ivec::size "<
<
// 09020.cpp
#include
#include
using std::stack;
using std::cout;
using std::cerr;
using std::endl;
int main()...{
const stack ::size_type stk_size = 10
stack intStack;
int ix = 0
while(intStack.size() != stk_size)...{
intStack.push(ix++);
}
int error_cnt = 0
while(!intStack.empty())...{
int value = intStack.top();
if (value != --ix)...{
cerr << "oops! expected " << ix << " received " << value << endl;
++error_cnt;
}
cout << value << " "
intStack.pop();
}
cout << endl;
cout << "Our program ran with " << error_cnt << " errors!" << endl;
return 0
}
021 队列和优先级队列支持的操作.
q.empty()
q.size()
q.pop()
q.front() 返回队首元素,但不删除该元素,只适用于队列.
q.back() 返回队尾元素,但不删除该元素,只适用于队列.
q.top() 返回具有最高优先级的元素,但不删除该元素,只适合优先级队列.
q.push(item) 对于队列,在队尾压如一个新元素,对于优先级队列,在适当的位置插入新元素.
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1837810
本文转自
http://blog.csdn.net/nx500/archive/2007/10/22/1837810.aspx ::reference>
声明,所有的朋友,如果要转我的帖子,务必注明"作者:黑啤 来源:CSDN博客"和具体的网络地址http://blog.csdn.net/nx500/archive/2007/10/22/1837810.aspx,并且我的所有博客内容,禁止任何形式的 商业用途,请大家尊重我的劳动.谢谢!
目 录九.顺序容器.
001 顺序容器类型.
vector 支持快速随机访问.
list 支持快速插入删除.
deque 双端队列.
顺序容器适配器.
stack 后进先出栈LIFO.
queue 先进先出栈FIFO.
priority_queue 有优先级管理的队列.
002 顺序容器的定义,所有的容器都是模板,要定义具体的容器,必须在容器名后加一对尖括号,括号里提供容器存放元素的类型.
#include
#include
#include
vector svec;
list ilist;
deque items;
003 顺序容器的构造函数
C c; 创建一个名为c的空容器
C c(c2); 创建容器c2的副本c,c和c2必须具有相同的容器类型.
C c(b, e); 创建容器c,其元素是迭代器b和e标示范围内的元素的副本,e标示一个停止指针,指向的内容并不复制.
C c(n, t); 用n个t元素创建容器c,只适合顺序容器,不适合关联容器
C c(n); 创建n个值初始化的元素的容器c.只适合顺序容器,不适合关联容器
vector ivec;
vector ivec2(ivec); // ok.
list ilist(ivec); // error, ivec是vector类型,而ilist是list类型.
vector dvec(ivec); // error, 容器内的元素类型不同.
004 将一个容器复制给另一个容器时,类型必须匹配:容器类型和元素类型都必须相同.
使用迭代器时,不要求容器类型相同,容器内的元素类型也可以不同,只要它们互相兼容,能够将要复制的元素转换为所构建的新容器所构建的元素类型.
采用这种方式可以复制不能直接复制的容器,特别的,可以复制另外容器的一个子序列.
list slist(svec.begin(), svec.end());
vector ::iterator mid = svec.begin() + svec.size()/2;
deque front(svec.begin(), mid);
deque back(mid, svec.end());
类似的,可以通过内置数组的指针来初始化一个容器.
char *words[] = {"stately", "plump", "buck", "mulligan"};
size_t words_size = sizeof(words)/sizeof(char *);
list wordsList(words, words + words_size);
初始化指定数目的元素.
const list ::size_type list_size = 64;
list slist2(list_size, "heipi o");
list ilist2(list_size);
005 容器元素的限制:必须支持赋值运算,对象必须可以复制.引用类型不可以作为容器的元素(不能赋值),标准输入输出不能作为容器的元素.
如果类没有默认的构造函数,那么在定义容器的时候,必须定义空的容器,或者提供显式构造函数的参数.
假设Foo只有一个需要一个int参数的构造函数,那么:
vector empty; // ok
vector bad(2); // error, 无法默认的创建元素,所以不行.
vector fine(2, 0); // ok, 通过参数0,创建两个元素.
可以定义容器的容器.
vector< vector lines;
lines.push_back(svec);
006 常用的迭代器运算.
*iter 返回迭代器iter所指向的元素的引用.
iter->mem 对iter解引用,获取指定元素中mem的成员,等效于(*item).mem
++iter/iter++/--iter/iter--
iter1 == iter2 比较两个迭代器是否指向同一个元素 (iter1 != iter2).
vector 和 deque容器的额外运算.
iter +/- n
iter +/- = n
iter1 - iter2
>, >=, <, <=
注意啦:在list容器中不支持" +/- n"的操作,也不支持逻辑关系运算.
007 使用迭代器编写程序时,必须留意那些使迭代器失效的操作,防止野指针问题.通常,要求涉及迭代器的代码尽可能短小.
008 容器定义的类型.
size_type
iterator
const_iterator
reverse_iterator
const_reverse_iterator
difference_type
value_type 元素的类型.
reference 元素的引用类型 value_type&
const_reference 元素的常量左值类型.
009 容器的begin和end操作,每个操作还和容器是否为const有关.
c.begin() / c.end()
c.rbegin() / c.rend()
010 容器中添加元素的操作
c.push_back(t) 在末尾加t,返回void.
c.push_front(t) 只适用于list和deque容器类型,返回void.
c.insert(p, t) 在p的前边插入t,返回指向新添加元素的迭代器.
c.insert(p, n, t) 在p的前边插入n个t,返回void.
c.insert(p, b, e) 在p的前边插入迭代器b和e之间的元素,返回void.
添加单个元素.
vector
list slist;
string spouse("Beth");
// 等同于slist.push_front(spouse).
slist.insert(slist.begin(),spouse);
// vector没有push_front,但是可以采用在begin前插入的方式实现该功能.
// 要注意,对于vector容器,在前部或中间插入元素,是非常耗费资源的一个行为.
svec.insert(svec.begin(),spouse);
// 借用insert(p,t)的返回值,循环向容器的头部添加元素.
list ::iterator iter = slist.begin();
while(cin >>spouse){
iter = ilist.insert(iter, spouse);
}
插入一段元素.
svec.insert(svec.end(), ilist.begin(), ilist.end());
string sarr[4] = {"wangyi", "aichao", "master", "huawei"};
svec.insert(svec.begin(), sarr, sarr + 4);
要注意,添加元素可能造成迭代器失效.比如在vector中添加元素,可能会导致整个容器的重新加载,迭代器自然也就无效了.
因此不要保存begin()或end()操作的返回值,而是每次使用时都要执行一次该函数.
vector ::iterator first = v.begin();
while(first != v.end()){
first = v.insert(first, 42);
++first;
}
011 关系操作符.容器的比较是基于容器内元素的比较,如果元素不支持某种类型的比较,容器也就不能做这种比较运算.
如果两个容器具有相同的长度而且所有元素相等,那么两个元素就相等.
如果两个容器的长度不相同,但较短的容器中所有元素都等于较长容器中对应的元素,则称较短的容器小于另一个容器.
如果两个容器都不是对方的初始子序列,则它们的比较结果取决于所比较的第一个不相等的元素.
/*
ivec1: 1 3 5 7 9 12
ivec2: 0 2 4 6 8 10 12
ivec3: 1 3 9
ivec4: 1 3 5 7
ivec5: 1 3 5 7 9 12
*/
ivec2
ivec1
ivec4
ivec1 == ivec5
012 容器大小的操作.
c.size()
c.max_size() 返回类型是c::size_type.
c.empty()
c.resize(n) 如果n
c.resize(n,t) 新添加的元素,都用t来初始化.resize操作可能会使迭代器失效.
013 访问元素.如果容器非空,那么容器的front()和back()成员将返回容器内第一个和最后一个元素的"引用".
注意:返回的是引用,begin()和end()返回的是指针.
if (!list.empty()){
list /> ::reference
list ::reference val2 = ilist.front();
list ::reference last1 = *--ilist.end();
list ::reference last2 = ilist.back();
}
其他操作.
c[n] 这两个操作,只适用于vector和deque容器.
c.at(n) 如果给出的下标无效,at函数会抛出out_of_range异常,所以推荐使用,最好还是用迭代器.
如果容器为空,那么所有访问容器的操作都是没有定义的(也就是说只有鬼才知道会返回点什东西),导致程序出现严重的错误.
014 删除元素.
c.erase(p) 删除迭代器p指向的元素,返回被删除元素后边元素的迭代器.
c.erase(b, e) 删除迭代器b和e范围内的元素,返回被删除段后面元素的迭代器.
c.clear() 删除容内全部的元素,返回void.
c.pop_back() 删除容器c的最后一个元素,返回void,c不能为空.
c.pop_front() 删除容器c的第一个元素,返回void,c不能为空,只适用于list或deque.
删除第一个或者最后一个元素,注意,pop_back()和pop_front()都是不返回值的.
while(!ilist.empty()){
// process(ilist.front());
ilist.pop_front();
}
删除容器内的一个元素,要注意,erase是不检查迭代器参数是否有效的.
string searchValue("Quasimodo");
list ::iterator iter = find(slist.begin(), silist.end(), searchValue);
if(iter != slist.end())
slist.erase(iter);
删除容器内的所有元素.
slist.clear();
slist.erase(slist.begin(), slist.end());
015 赋值与swap.除swap外,所有的操作,都可以用earse和insert取代.
c1 = c2
c1.swap(c2) 用c2容器的元素取代c1容器的元素.
c.assign(b, e) c中原来的元素清空,将迭代器b和e标记范围内的所有元素复制到c中.
c.assign(n, t)
带有一对迭代器的assin函数,允许我们将一个容器的元素赋给另一个不同类型的容器.
016 容器的capacity和reserve成员.
为了使vector容器实现快速的内存分配,其实际分配的容量要比当前所需的空间多一些.vector容器预留了这些额外的存储区,用于存放新添加的元素.
于是,不必为每个新元素重新分配空间,所以,比起list和deque容器,vector的增长效率要高一些.
vector ivec;
cout<< "ivec::size "<
<
// 09020.cpp
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#include
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#include
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using std::stack;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using std::cout;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using std::cerr;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using std::endl;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
int main()...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
const stack ::size_type stk_size = 10
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
stack intStack;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int ix = 0
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
while(intStack.size() != stk_size)...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
intStack.push(ix++);
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int error_cnt = 0
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
while(!intStack.empty())...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int value = intStack.top();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
if (value != --ix)...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
cerr << "oops! expected " << ix << " received " << value << endl;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
++error_cnt;
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout << value << " "
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
intStack.pop();
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout << endl;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout << "Our program ran with " << error_cnt << " errors!" << endl;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return 0
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
021 队列和优先级队列支持的操作.
q.empty()
q.size()
q.pop()
q.front() 返回队首元素,但不删除该元素,只适用于队列.
q.back() 返回队尾元素,但不删除该元素,只适用于队列.
q.top() 返回具有最高优先级的元素,但不删除该元素,只适合优先级队列.
q.push(item) 对于队列,在队尾压如一个新元素,对于优先级队列,在适当的位置插入新元素.
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1837810
本文转自
http://blog.csdn.net/nx500/archive/2007/10/22/1837810.aspx ::reference>