目录
引言
标准库中的deque
一、deque的基本概念
二、deque的常用接口
1.deque的迭代器
2.deque的初始化
3.deque的容量操作
3.1 有效长度和容量大小
3.2 有效长度和容量操作
4.deque的访问操作
5.deque的修改操作
三、deque的应用场景
结束语
引言
在C++中,deque是STL(标准模板库)提供的一种容器类,专门用于存储各种类型的元素,并支持在两端进行快速的插入和删除操作。今天我们就试着来学习一下这一数据结构。
标准库中的deque
一、deque的基本概念
Deque是一种线性数据结构,它允许在两端进行插入和删除操作。这两端通常被称为前端(front)和后端(rear),或者端点1和端点2。Deque的灵活性在于,它既可以用作队列(FIFO,先进先出),也可以用作栈(LIFO,后进先出),具体取决于元素的插入和删除操作是在哪一端进行的。deque是C++STL(标准模板库)中的一种容器,可以用于存储各种类型的元素。deque的特点是可以在队列的两端进行元素的操作,并且可以高效地在队列的任意位置进行元素的插入和删除操作。
二、deque的常用接口
1.deque的迭代器
与string和vector类似,deque也有迭代器。
由于deque定义在deque类中,因此我们想要使用deque的迭代器需要通过域作用限定符访问——deque<类型>::iterator 。
其中,begin(),end(),rbeign(),rend()的使用访问方法与string和vector的使用方法类似。
我们来看代码:
int main()
{
deque<int> d = { 0,1,2,3,4, };
deque<int>::iterator it = d.begin();
cout << "顺序遍历:";
while (it != d.end())
{
cout << *it << " ";
++it;
}
cout << endl;
cout << "逆序遍历:";
deque<int>::reverse_iterator rit = d.rbegin();
while (rit != d.rend())
{
cout << *rit << " ";
++rit;
}
return 0;
}
输出结果为:
2.deque的初始化
来看代码演示:
void Print(deque<int>& d)
{
for (deque<int>::iterator it = d.begin(); it != d.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
deque<int> d1;
for (int i = 0; i < 5; ++i)
{
d1.push_back(i);
}
deque<int> d2(d1.begin(), d1.end());
deque<int> d3(5, 5);
deque<int> d4(d3);
cout << "打印d1: ";
Print(d1);
cout << "打印d2: ";
Print(d2);
cout << "打印d3: ";
Print(d3);
cout << "打印d4: ";
Print(d4);
return 0;
}
输出结果为:
3.deque的容量操作
下面是关于deque的容量操作:
函数名称 | 功能 |
size | 返回deque的有效长度 |
clear | 清空deque |
empty | 检查deque是否为空,是则返回ture,否则返回false |
resize | 重新设置有效元素的数量,超过原来有效长度则用c字符填充 |
3.1 有效长度和容量大小
deque没有capacity接口。deque,即双端队列(Double Ended Queue),是一个双向开口的连续线性空间,允许在头尾两端分别进行插入和删除操作。其特性决定了它不需要像某些其他数据结构(如vector)那样具有固定的容量(capacity)概念。
下面是简单的测试用例:
int main()
{
deque<int> d = { 0,1,2,3,4 };
cout << d.size() << endl;
if (d.empty())
{
cout << "d为空" << endl;
}
else
{
cout << "d不为空" << endl;
}
d.clear();
if (d.empty())
{
cout << "d为空" << endl;
}
else
{
cout << "d不为空" << endl;
}
return 0;
}
3.2 有效长度和容量操作
deque这个容器没有提供reserve接口,接下来我们来学习一下resize这个接口:
resize()与我们之前学习的string、vector用法一致,在这里就不多介绍了
来看代码演示:
int main()
{
deque<int> d = { 1,2,3,4,5 };
d.resize(3);
for (int i = 0; i < d.size(); i++)
{
cout << d[i] << " ";
}
cout << endl;
d.resize(4);
for (int i = 0; i < d.size(); i++)
{
cout << d[i] << " ";
}
cout << endl;
d.resize(5, 9);
for (int i = 0; i < d.size(); i++)
{
cout << d[i] << " ";
}
cout << endl;
return 0;
}
输出结果为:
4.deque的访问操作
函数名称 | 功能 |
operator[] | 返回指定位置的元素,越界则报错 |
at | 返回指定位置的元素,越界则抛异常 |
front | 返回字符串第一个元素 |
back | 返回字符串最后一个元素 |
这部分内容和之前学习的vector容器部分内容差不多
int main()
{
deque<int> d = { 0,1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < d.size(); i++)
{
cout << d[i] << " ";
}
cout << endl;
for (int i = 0; i < d.size(); i++)
{
cout << d.at(i) << " ";
}
cout << endl;
cout << "front:" << d.front() << endl;
cout << "back:" << d.back() << endl;
return 0;
}
输出结果:
5.deque的修改操作
deque的修改操作有如下几个:
函数名称 | 功能 |
push_back | 在数组后追加元素 |
pop_back | 删除数组最后一个元素 |
insert | 在指定位置追加元素 |
assign | 使用指定数组替换原数组 |
erase | 删除数组指定部分区间 |
swap | 交换两个数组 |
直接看代码:
尾删和尾插:
int main() { deque<int> d = { 0,1,2,3,4,5,6,7,8,9 }; for (int i = 0; i < d.size(); i++) { cout << d.at(i) << " "; } cout << endl; d.push_back(10); for (int i = 0; i < d.size(); i++) { cout << d.at(i) << " "; } cout << endl; d.pop_back(); for (int i = 0; i < d.size(); i++) { cout << d.at(i) << " "; } cout << endl; return 0; }
输出结果为:
assign和swap:
int main() { deque<int> d1 = { 9,9,9,9,9 }; d1.assign(3, 3); for (int i = 0; i < d1.size(); i++) { cout << d1[i] << " "; } cout << endl; deque<int> d2 = { 1,1,1,1,1 }; d1.swap(d2); for (int i = 0; i < d1.size(); i++) { cout << d1[i] << " "; } cout << endl; for (int i = 0; i < d2.size(); i++) { cout << d2[i] << " "; } cout << endl; return 0; }
输出结果为:
insert:
int main() { deque<int> d1(5, 10); deque<int>::iterator it = d1.begin(); it = d1.insert(it, 100); cout << "d1:"; for (it = d1.begin(); it < d1.end(); it++) { cout << *it << " "; } cout << endl; d1.insert(it, 2, 1000); it = d1.begin(); cout << "d1:"; for (it = d1.begin(); it < d1.end(); it++) { cout << *it << " "; } cout << endl; deque<int> d2(2, 10000); it = d1.begin(); d1.insert(it + 2, d2.begin(), d2.end()); cout << "d1:"; for (it = d1.begin(); it < d1.end(); it++) { cout << *it << " "; } cout << endl; return 0; }
输出结果为:
erase:
int main() { deque<int> d = { 0,1,2,3,4,5,6,7,8,9 }; deque<int>::iterator it = d.erase(d.begin() + 3); // 删除值为3的元素 it = d.erase(it); // 删除值为4的元素 for (int i = 0; i < d.size(); i++) { cout << d[i] << " "; } cout << endl; it = d.erase(d.begin(), d.begin() + 5); for (int i = 0; i < d.size(); i++) { cout << d[i] << " "; } cout << endl; return 0; }
输出结果为:
三、deque的应用场景
1.缓存机制:在需要频繁从两端添加或移除元素的场景下,如浏览器历史记录、消息队列等,deque能高效地处理数据。
2.任务调度:在并发编程中,deque可以用于线程池的任务队列,既能快速添加新的任务,也能方便地取出已完成的任务进行后续处理。
3.算法实现:许多排序算法,比如循环队列、滑动窗口算法等,会用到deque来进行辅助存储。
4.游戏开发:游戏中角色的行动序列、回合制系统的牌堆管理等也常使用deque。
5.文本编辑器:滚动条下方的撤销/重做功能,也可以利用deque来存储历史状态。
结束语
没啥时间写博客,浅浅水一篇吧~
感谢大佬支持,求点赞收藏评论关注!!!
十分感谢!!!