C++——deque
文章目录Deque 与 vector 的异同点构造操作非更易型操作更易型操作使用例子 容器 deque (发音为“deck”)和 vector 非常相似。它也采用dynamic array来管理元素,提供随机访问,并有着和 vector 几乎一模一样的接口。不同的是 deque 的 dynamic array 头尾都开放,因此能在头尾两端进行快速安插和删除(如
·
容器 deque (发音为“deck”)和 vector 非常相似。它也采用dynamic array来管理元素,提供随机访问,并有着和 vector 几乎一模一样的接口。不同的是 deque 的 dynamic array 头尾都开放,因此能在头尾两端进行快速安插和删除(如下图所示)。
为了提供这种能力, deque 通常实现为一组独立区块,第一区块朝某方向扩展,最末区块朝另一方向扩展,如下图所示。
deque 包含在头文件< deque >中:
#include <deque>
其中,deque 类型定义于命名空间 std 内的一个class template:
namespace std {
template <typename T,
typename Allocator = allocator<T> >
class deque;
}
和 vector 相同,这里的第一个 template 参数用来表明元素类型。第二个 template 实参可有可无,用来指定内存模型,默认为 allocator。
Deque 与 vector 的异同点
Deque 与 vector 相比,功能上的差异如下:
- deque 两端都能快速安插元素和移除元素(vector 只在尾端逞威风)。这些操作可以在摊提的常量时间内完成。
- 访问元素时 deque 内部结构会多一个间接过程,所以元素的访问和迭代器的动作会稍稍慢一些。
- 迭代器需要在不同区块间跳转,所以必须是个 smart pointer,不能是寻常 pointer。
- 在内存区块大小有限制的系统中(例如PC系统), deque 可以内含更多元素,因为它使用不止一块内存。因此 deque 的 max_size() 可能更大。
- Deque 不支持对容量和内存重新分配时机的控制。特别要注意的是,除了头尾两端,在任何地点安插或删除元素都将导致指向 deque 元素的任何 pointer、reference 和 iterator 失效。不过,deque 的内存重分配优于 vector,因为其内部结构显示, deque 不必在内存重新分配时复制所有元素。
- Deque 会释放不再使用的内存区块。Deque 的内存大小是可缩减的,但要不要这么做,以及如何做,由实现决定。
Deque 的以下特性跟 Vector 差不多:
- 在中段安插、移除元素的速度相对较慢,因为所有元素都需移动以腾出或填补空间。
- 迭代器属于 random-access iterator (随机访问迭代器)。
以下情形最好采用 deque:
- 你需要在两端安插和移除元素(这是 deque 的拿手好戏)。
- 无须指向(refer to)容器内的元素。
- 要求“不再使用的元素必须释放”(不过 C++ standard 对此无任何保证)。
Vector 和 deque 的接口几乎一样,所以如果你不需要什么特殊性质,两者都可试试。
构造操作
操作 | 描述 |
---|---|
deque< Elem > c | Default 构造函数,产生一个空 deque,没有任何元素 |
deque< Elem > c(c2) | Copy 构造函数,建立 c2 的同型 deque 并成为 c2 的一份拷贝(所有元素都被复制) |
deque< Elem > c= c2 | Copy 构造函数,建立一个新的 deque 作为 c2 的拷贝(每个元素都被复制) |
deque< Elem > c(rv) | Move 构造函数,建立一个新的 deque,取 rvalue rv 的内容(始自C++11) |
deque< Elem > c = rv | Move 构造函数,建立一个新的 deque,取 rvalue rv 的内容(始自C++11) |
deque< Elem > c(n) | 利用元素的 default 构造函数生成一个大小为 n 的 deque |
deque< Elem > c(n, elem) | 建立一个大小为 n 的 deque,每个元素值都是 elem |
deque< Elem > c(beg, end) | 建立一个 deque,以区间 [beg, end) 作为元素初值 |
deque< Elem > c(initlist) | 建立一个 deque,以初值列 initlist 的元素为初值(始自C++11) |
deque< Elem > c = initlist | 建立一个 deque,以初值列 initlist 的元素为初值(始自C++11) |
c.~deque() | 销毁所有元素,释放内存 |
非更易型操作
操作 | 描述 |
---|---|
c.empty() | 返回是否容器为空(相当于 size()==0 但也许较快) |
c.size() | 返回目前的元素个数 |
c.max_size() | 返回元素个数之最大可能量 |
c.shrink_to_fit() | 要求降低容量,以符合元素个数(始自C++11) |
c1 == c2 | 返回 c1 是否等于 c2(对每个元素调用==) |
c1 != c2 | 返回 c1 是否不等于 c2(相当于!(c1==c2)) |
c1 < c2 | 返回 c1 是否小于 c2 |
c1 > c2 | 返回 c1 是否大于 c2(相当于c2<c1) |
c1 <= c2 | 返回 c1 是否小于等于 c2(相当于!(c2<c1)) |
c1 >= c2 | 返回 c1 是否大于等于 c2(相当于! (c1<c2)) |
c[idx] | 返回索引 idx 所指的元素(不检查范围) |
c.at(idx) | 返回索引 idx 所指的元素(如果 idx 超出范围就抛出 range-error 异常) |
c.front() | 返回第一元素(不检查是否存在第一元素) |
c.back() | 返回最末元素(不检查是否存在最未元素) |
c.begin() | 返回一个 random-access iterator 指向第一元素 |
c.end() | 返回一个 random-access iterator 指向最末元素的下一位置 |
c.cbegin() | 返回一个 const random-access iterator 指向第一元素(始自C++11) |
c.cend( | 返回一个 const random-access iterator 指向最末元素的下一位置(始自C++11) |
c.rbegin() | 返回一个反向的 (reverse) iterator 指向反向迭代的第一元素 |
c.rend() | 返回一个反向的 (reverse) iterator 指向反向迭代的最末元素的下一位置 |
c.crbegin() | 返回一个 const reverse iterator 指向反向迭代的第一元素(始自C++11) |
c.crend() | 返回一个 const reverse iterator 指向反向迭代的最末元素的下一位置(始自C++11) |
更易型操作
操作 | 描述 |
---|---|
c = c2 | 将 c2 的全部元素赋值给 c |
c = rv | 将 rvalue rv 的所有元素以 move assign 方式给予 c(始自C++11) |
c = initlist | 将初值列 inittist 的所有元素赋值给 c(始自C++11) |
c.assign(n, elem) | 复制 n 个 elem,赋值给 c |
c.assign(beg , end) | 将区间 [beg, end) 内的元素赋值给 c |
c.assign(initlist) | 将初值列 initlist 的所有元素赋值给 c |
c1.swap( c2) | 置换 c1 和 c2 的数据 |
swap(c1, c2) | 置换 c1 和 c2 的数据 |
c.push_back(elem) | 附加一个 elem 的拷贝于末尾 |
c.pop_back() | 移除最后一个元素,但是不返回它 |
c.push_front(elem) | 在头部插入 elem 的一个拷贝 |
c.pop_front() | 移除第一元素(但不返回) |
c.insert(pos, elem) | 在 iterator 位置 pos 之前方插入一个 elem 拷贝,并返回新元素的位置 |
c.insert(pos, n, elem) | 在 iterator 位置 pos 之前方插入 n 个 elem 拷贝,并返回第一个新元素的位置(或返回 pos——如果没有新元素的话) |
c.insert(pos, beg, end) | 在 iterator 位置 pos 之前方插入区间 [beg, end) 内所有元素的一份拷贝,并返回第一个新元素的位置(或返回 pos——如果没有新元素的话) |
c.insert(pos, initlist) | 在 iterator 位置 pos 之前方插入初值列 initlist 内所有元素的一份拷贝,并返回第一个新元素的位置(或返回 pos———如果没有新元素的话;始自C++11) |
c.emplace(pos, args . . .) | 在 iterator 位置 pos 之前方插入一个以 args 为初值的元素,并返回新元素的位置(始自C++11) |
c.emplace_back(args . . .) | 附加一个以 args 为初值的元素于末尾,不返回任何东西(始自C++11) |
c.emplace_front(args . . .) | 插入一个以 args 为初值的元素于起点,不返回任何东西(始自C++11) |
c.erase(pos) | 移除 iterator 位置 pos 上的元素,返回下一元素的位置 |
c.erase(beg, end) | 移除 [beg, end) 区间内的所有元素,返回下一元素的位置 |
c.resize(num) | 将元素数量改为 num(如果 size() 变大,多出来的新元素都需以 default 构造函数完成初始化) |
c.resize(num, elem) | 将元素数量改为 num(如果 size() 变大,多出来的新元素都是 elem 的拷贝) |
c.clear() | 移除所有元素,将容器清空 |
使用例子
#include <iostream>
#include <algorithm>
#include <string>
#include <deque>
using namespace std;
int main(){
deque<string> c;//创建一个空deque
c.assign(3, string("qwjy"));//复制3个qwjy复制给c
c.push_back("qw");//尾部插入一个元素
c.push_front("qy");//头部插入一个元素
for(int i = 0; i < c.size(); i ++)
printf("%s\n", c[i].c_str());
printf("\n");
c.pop_front();//移除最后一个元素
c.pop_back();//移除第一个元素
for(int i = 0; i < c.size(); i ++)
printf("%s\n", c[i].c_str());
printf("\n");
c[1] = c[1] + "666";
for(int i = 0; i < c.size(); i ++)
printf("%s\n", c[i].c_str());
printf("\n");
return 0;
}
更多推荐
已为社区贡献1条内容
所有评论(0)