摘要:本文主要介绍了deque容器以及一些API的使用。
1、基本概念
1.1 deque容器介绍
该容器和vector容器很相似,不同之处在于两点:第一是它可以实现头部的插入和删除;第二在于deque没有容量的概念,因为它是动态的以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。
1.2 实现原理
Deque容器是连续的空间,至少逻辑上看来如此,连续现行空间总是令我们联想到array和vector,array无法成长,vector虽可成长,却只能向尾端成长,而且其成长其实是一个假象,事实上(1) 申请更大空间 (2)原数据复制新空间 (3)释放原空间 三步骤,如果不是vector每次配置新的空间时都留有余裕,其成长假象所带来的代价是非常昂贵的。
Deque是由一段一段的定量的连续空间构成。一旦有必要在deque前端或者尾端增加新的空间,便配置一段连续定量的空间,串接在deque的头端或者尾端。Deque最大的工作就是维护这些分段连续的内存空间的整体性的假象,并提供随机存取的接口,避开了重新配置空间,复制,释放的轮回,代价就是复杂的迭代器架构。
既然deque是分段连续内存空间,那么就必须有中央控制,维持整体连续的假象,数据结构的设计及迭代器的前进后退操作颇为繁琐。Deque代码的实现远比vector或list都多得多。
Deque采取一块所谓的map(注意,不是STL的map容器)作为主控,这里所谓的map是一小块连续的内存空间,其中每一个元素(此处成为一个结点)都是一个指针,指向另一段连续性内存空间,称作缓冲区。缓冲区才是deque的存储空间的主体。
2、常用API
2.1 deque构造函数
deque<T> deqT | 默认构造形式 |
deque(beg, end) | 构造函数将[beg, end)区间中的元素拷贝给本身 |
deque(n, elem) | 构造函数将n个elem拷贝给本身 |
deque(const deque &deq) | 拷贝构造函数 |
2.2 deque赋值操作
assign(beg, end) | 将[beg, end)区间中的数据拷贝赋值给本身 |
assign(n, elem) | 将n个elem拷贝赋值给本身 |
deque& operator=(const deque &deq) | 重载等号操作符 |
swap(deq) | 将deq与本身的元素互换 |
2.3 deque大小操作
deque.size() | 返回容器中元素的个数 |
deque.empty() | 判断容器是否为空 |
deque.resize(num) |
重新指定容器的长度为num,若容器变长,则以默认值填充新位置。 如果容器变短,则末尾超出容器长度的元素被删除 |
deque.resize(num, elem) |
重新指定容器的长度为num,若容器变长,则以elem值填充新位置, 如果容器变短,则末尾超出容器长度的元素被删除 |
2.4 deque双端插入和删除操作
push_back(elem) | 在容器尾部添加一个数据 |
push_front(elem) | 在容器头部插入一个数据 |
pop_back() | 删除容器最后一个数据 |
pop_front() | 删除容器第一个数据 |
2.5 deque数据存取
at(idx) | 返回索引idx所指的数据,如果idx越界,抛出out_of_range |
operator[] | 返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错 |
front() | 返回第一个数据 |
back() | 返回最后一个数据 |
2.6 deque插入操作
insert(pos,elem) | 在pos位置插入一个elem元素的拷贝,返回新数据的位置 |
insert(pos,n,elem) | 在pos位置插入n个elem数据,无返回值 |
insert(pos,beg,end) | 在pos位置插入[beg,end)区间的数据,无返回值 |
2.7 deque删除操作
clear() | 移除容器的所有数据 |
erase(beg,end) | 删除[beg,end)区间的数据,返回下一个数据的位置 |
erase(pos) | 删除pos位置的数据,返回下一个数据的位置 |
3、代码示例
1 #include <iostream> 2 #include<deque> 3 #include<algorithm> 4 5 using namespace std; 6 7 void printDeque(const deque<int>&d) { 8 for (deque<int>::const_iterator it=d.begin();it!=d.end();it++) 9 { 10 cout << *it <<" "; 11 } 12 cout << endl; 13 } 14 15 void test01() { 16 deque<int>d1; 17 d1.push_back(10); 18 d1.push_back(20); 19 d1.push_front(5); //注意可以前面插入 20 d1.push_back(30); 21 printDeque(d1); 22 23 deque<int>d2(d1.begin(),d1.end()); //将d1首尾区间的内容复制到d2 24 printDeque(d2); 25 d2.push_back(40); 26 printDeque(d2); 27 28 d1.swap(d2); //交换 29 printDeque(d2); 30 } 31 32 void test02() 33 { 34 deque<int>d; 35 d.push_back(10); 36 d.push_back(30); 37 d.push_back(20); 38 d.push_front(100); 39 d.push_front(200); 40 41 printDeque(d); // 200 100 10 30 20 42 43 //删除 头删 尾删 44 d.pop_back(); 45 d.pop_front(); 46 printDeque(d); // 100 10 30 47 48 cout << "front: " << d.front() << endl; 49 cout << "back: " << d.back() << endl; 50 51 //插入 52 deque<int>d2; 53 d2.push_back(50); 54 d2.push_back(60); 55 d2.insert(d2.begin(), d.begin(), d.end()); 56 printDeque(d2); // 100 10 30 50 60 57 } 58 59 bool myCompare(int v1, int v2) 60 { 61 return v1 > v2; // 100 10 62 } 63 64 //排序 sort 65 void test03() 66 { 67 deque<int>d; 68 d.push_back(5); 69 d.push_back(15); 70 d.push_back(3); 71 d.push_back(40); 72 d.push_back(7); 73 74 printDeque(d); 75 //排序 76 sort(d.begin(), d.end()); 77 78 printDeque(d); 79 80 //从大到小 81 sort(d.begin(), d.end(), myCompare); 82 //从小到大 83 //sort(d.begin(), d.end()); 84 printDeque(d); 85 86 } 87 88 int main() { 89 //test01(); 90 //test02(); 91 test03(); 92 system("pause"); 93 return 0; 94 }