C++ Primer学习笔记2--c++顺序容器

来源:互联网 发布:淘宝第二阶层 编辑:程序博客网 时间:2024/05/16 04:58

顺序容器

vector    支持快速随机访问

 

list      支持快速插入/删除

 

deque      双端队列

 

顺序容器适配器

 stack后进先出(LIFO)堆栈

 

 queue先进先出(FIFO)队列

 

 priority_queue有优先级管理的队列

 

 

 为了定义 一个容器类型的对象,必须先包含相关的头文件,即下列头文件之一:

 #include <vector>

 #include <list>

 #include <deque>

 

 所有的容器都是类模板。要定义某种特殊的容器,必须在容器名后加一对尖括号,尖括号里面提供容器中存放的元素的类型:

 vector<string> svec; 

 list<int> ilist; 

 deque<Sales_item> items;

  

 容器的构造函数(以vector为例)

 1.默认构造函数   vector<string> svec;  

 2.将一个容器初始化为另一个容器的副本 vector<string> ivec2(svec); //容器类型元素类型必须相同

 3.初始化为一段元素的副本(传递2个迭代器为参数,标记开始结束,不要求容器类型相同。容器内的元素类型也可以不相同,只要它们相互兼容,能够将要复制的元素转换为所构建的新容器的元素类型,即可实现复制。)

 

 list<string> slist(svec.begin(), svec.end());

 

 vector<string>::iterator mid = svec.begin() + svec.size()/2;

 

 deque<string> front(svec.begin(), mid);

 deque<string> back(mid, svec.end());

 

 通过使用内置数组中的一对指针初始化容器

 char *words[] = {"stately", "plump", "buck", "mulligan"};

 

 size_t words_size = sizeof(words)/sizeof(char *);


 list<string> words2(words, words + words_size);//通过指向第一个元素的指针 words 和指向数组中最后一个元素的下一位置的指针,实现了 words2的初始化。其中第二个指针提供停止复制的条件,其所指向的位置上存放的元素并没有复制。

 

 4.分配和初始化指定数目的元素(=顺序容器=

  const list<int>::size_type list_size = 64;

  list<string> slist(list_size, "eh?");64eh?

  list<int> ilist(list_size);64采用这种类型的初始化,元素类型必须是内置或复合类型,或者是提供了默认构造函数的类类型。如果元素类型没有默认构造函数,则必须显式指定其元素初始化式。

 

 • 元素类型必须支持赋值运算。

 • 元素类型的对象必须可以复制。

 IO标准库类型和引用类型不能作为容器元素类型

 

 

 

 迭代器

 

 常用迭代器运算

 

 *iter       返回迭代器 iter 所指向的元素的引用

 

 iter->mem   iter 进行解引用,获取指定元素中名为 mem 的成员。等效于 (*iter).mem

 

 *iter       返回迭代器 iter 所指向的元素的引用

 

 ++iter   iter++ iter 1,使其指向容器里的下一个元素

 --iter   iter-- iter 1,使其指向容器里的前一个元素

 

 iter1 ==iter2

 iter1 !=iter2

 比较两个迭代器是否相等(或不等)。当两个迭代器指向同一个

 容器中的同一个元素,或者当它们都指向同一个容器的超出末端

 的下一位置时,两个迭代器相等

 

 

 vector  deque专有操作

 iter+n iter-n

 在迭代器上加()整数值 n,将产生指向容器中前面(后面) n 个元素的迭代器。新计算出来的迭代器必须指向容器中的元素或超出 容器末端的下一位置

 

 iter1 += iter2 iter1 -= iter2 

 这里迭代器加减法的复合赋值运算: iter1加上或减去 iter2 运算结果赋给 iter1

 

 iter1 - iter2

 两个迭代器的减法,其运算结果加上右边的迭代器即得左边的迭代器。这两个迭代器必须指向同一个容器中的元素或超出容器末端的下 一位置

 只适用于 vector deque 容器

 

 

 >, >=, <, <=

 迭代器的关系操作符。当一个迭代器指向的元素在容器中位于另一个迭代器指向的元素之前,则前一个迭代器小于后一个迭代器。关系操作符的两个迭代器必须指向同一个容器中的元素或超出容器末端的 下一位置

 

 list 容器的迭代器既不支持算术运算(加法或减法),也不支持关系运算(<=, <, >=, >),它只提供前置和后置的自增、自减运算以及相等 (不等)运算。

 

 

 容器定义的类型别名:

 

 size_type 无符号整型,足以存储此容器类型的最大可能容器长

 iterator 此容器类型的迭代器类型

 const_iterator  元素的只读迭代器类型

 reverse_iterator 按逆序寻址元素的迭代器

 const_reverse_iterator 元素的只读(不能写)逆序迭代器

difference_type 足够存储两个迭代器差值的有符号整型,可为负数

value_type 元素类型

reference 元素的左值类型, value_type&的同义词

 const_reference 元素的常量左值类型,等效于 const value_type&

 

 使用类型别名定义变量

 list<string>::iterator iter;

 

 vector<int>::difference_type cnt;

 

 

 c.begin()

返回一个迭代器,它指向容器 c的第一个元素

 

 c.end()

 返回一个迭代器,它指向容器 c的最后一个元素的下一位置

 

 c.rbegin()

 返回一个逆序迭代器,它指向容器 c的最后一个元素

 

 c.rend()

 返回一个逆序迭代器,它指向容器 c的第一个元素前面的位置

 

 添加元素

 除了 push_back 运算,list deque 容器类型还提供了类似的操作: push_front

 

 

 在顺序容器中添加元素的操作

 c.push_back(t)

 在容器 c 的尾部添加值为 t 的元素。返回 void类型

 

 c.push_front(t)

 在容器 c 的前端添加值为 t 的元素。返回 void 类型 只适用于 list deque 容器类型.

 

 c.insert(p,t)

 在迭代器 p 所指向的元素前面插入值为 t 的新元素。返回指向新添加元素的迭代器

 

 

 c.insert(p,n,t)

 在迭代器 p 所指向的元素前面插入 n 个值为 t的新元素。 返回 void类型

 

 

 c.insert(p,b,e)

 在迭代器 p 所指向的元素前面插入由迭代器 b e标记 的范围内的元素。返回 void类型

 

 

 

 顺序容器大小操作

 c.size()

 

 返回容器 c 中的元素个数。返回类型为 c::size_type

 

 c.max_size()

 

 返回容器 c 可容纳的最多元素个数,返回类型为 c::size_type

 

 

 c.empty()

 

 返回标记容器大小是否为 0的布尔值

 

 c.resize(n)

 调整容器 c 的长度大小,使其能容纳 n个元素,如果 n < c.size(),则删除多出来的元素;否则,添加采用值初始化的新元素

 

 

 c.resize(n,t)

 

 调整容器 c 的长度大小,使其能容纳 n个元素。所有新添加 的元素值都为 t

 

 

 

----访问顺序容器内元素的操作

 

 list<int>::reference val = *ilist.begin();

 list<int>::reference val2 = ilist.front();

 

 c.back()

 返回容器 c 的最后一个元素的引用。如果 c 为空,则该操作未定

 

 

 c.front(

 返回容器 c 的第一个元素的引用。如果 c 为空,则该操作未定义

 

 c[n]

 返回下标为 n 的元素的引用

 如果 n <0 n >= c.size(),则该操作未定义 只适用于 vector deque 容器

 

 

 c.at(n)

 返回下标为 n 的元素的引用。如果下标越界,则该操作未定义只适用于 vector deque容器

  

 

---删除顺序容器内元素的操作

 c.erase(p)

 

 

 删除迭代器 p 所指向的元素

 返回一个迭代器,它指向被删除元素后面的元素。如果 p指向 容器内的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。如果 p 本身就是指向超出末端的下一位置的迭代,则该函数未定义

 c.erase(b,e)

 

 

 删除迭代器 b e 所标记的范围内所有的元素

 返回一个迭代器,它指向被删除元素段后面的元素。如果 e 身就是指向超出末端的下一位置的迭代器,则返回的迭代器也指向容器的超出末端的下一位置

 

 

 c.clear()

 

 删除容器 c 内的所有元素。返回 void

 c.pop_back()

 

 删除容器 c 的最后一个元素。返回 void。如果 c为空容器, 则该函数未定义

 

 c.pop_front()

 

 删除容器 c 的第一个元素。返回 void。如果 c为空容器,该函数未定义

 只适用于 list deque 容器

 

 选择容器类型的法则:

 1. 如果程序要求随机访问元素,则应使用 vector deque 容器。

 2. 如果程序必须在容器的中间位置插入或删除元素,则应采用 list容器。

 3. 如果程序不是在容器的中间位置,而是在容器首部或尾部插入或删除元

 ,则应采用 deque容器。

 4. 如果只需在读取输入时在容器的中间位置插入元素,然后需要随机访问元

 ,则可考虑在输入时将元素读入到一个 list容器,接着对此容器重新排序,使其适合顺序访问,然后将排序后的 list容器复制到一个 vector 容器。

 

 

 

 容器适配器

 除了顺序容器,标准库还提供了三种顺序容器适配器:queue priority_queue stack

 #include <stack>    

 #include <queue>

 假设 deq deque<int> 类型的容器,则可用 deq初始化一个新的栈,如下所示:

 stack<int> stk(deq);    

原创粉丝点击