STL之deque容器

摘要:本文主要介绍了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 }
原文地址:https://www.cnblogs.com/lzy820260594/p/11378398.html