C++队列
文章目录
- C++队列
- 队列:queue
- 基本函数
- 经典例题
- 双端队列:deque
- 成员类型
- 基础函数
- 访问与赋值
- 容量
- 修改器
- 详细说明:assign()
- 详细说明:insert()
- 详细介绍:resize()
- 双端例题:LC103 二叉树的锯齿形层序遍历
- 优先队列:priority_queue
- 例题:[LC264 丑数 II](https://leetcode.cn/problems/ugly-number-ii/)(使用优先队列实现小根堆)
队列:queue
API: C++ queue
队列是一种FIFO(先进先出)的数据结构
头文件:# include<queue>
定义一个队列:queue<T> queueName;
,和stack一样,队列也可以包含pair元素
queue<char, list<char>> q1;
queue<int, deque<int>> q2;
基本函数
函数名 | 作用 |
---|---|
front() | 访问第一个元素 |
back() | 访问最后一个元素 |
empty() | 检查容器是否为空 |
size() | 返回元素数 |
push() | 尾端插入元素 |
emplace()【C++11】 | 在尾部原位构造元素(比起push省了复制操作) |
pop() | 移除首位元素 |
swap()【C++11】 | 交换内容,交换a、b两个队列容器中的内容 |
经典例题
双端队列:deque
API: C++ deque
std::deque 是有索引的序列容器,允许在首尾两端快速插入和删除元素。(任意端的插入删除操作不会使指向其他元素的指针(or 引用)失效)
特性:①非连续存储 ②索引访问必须进行二次指针解引用 ③存储按需自动扩张&收缩 ④拥有较大的最小内存开销(只保有一个元素的 deque 必须分配它的整个内部数组)
存储方式:典型实现采用一系列单独分配的固定尺寸数组,外加额外的簿记数据
常见操作复杂度:
- 随机访问——常数 O(1)。
- 在结尾或起始插入或移除元素——常数 O(1)。
- 插入或移除元素——线性 O(n)。
成员类型
待补充,在实战中学习
基础函数
带*为C++11新特性
访问与赋值
函数 | 作用 | 失效 |
---|---|---|
assign() | 将值赋给容器【详见】 | |
at() | 带越界检查访问指定索引的元素 | |
front() | 访问第一个元素 | |
back() | 访问最后一个元素 | |
begin() *cbegin() | 返回指向起始的迭代器 | |
end() *cend() | 返回指向末尾的迭代器 | |
rbegin() *crbegin() | 返回指向起始的逆向迭代器 | |
rend() *crend() | 返回指向末尾的逆向迭代器 |
容量
函数 | 作用 |
---|---|
empty() | 判空 |
size() | 返回元素数 |
max_size() | 返回可容纳的最大元素数 |
shrink_to_fit() | 释放未使用的内存,减少内存的使用 |
修改器
函数 | 作用 | 失效 |
---|---|---|
clear() | 清除内容 | |
insert() | 插入元素详见 | |
*emplace() | 原位构造元素(pos, &&args) | |
erase() | 擦除元素(参数为迭代器(pos) OR 迭代器begin和end) | |
push_back() | 尾端添加元素 | |
*emplace_back() | 尾端原位构造元素 | |
pop_back() | 移除尾端元素 | |
push_front() | 在首端添加元素 | |
*emplace_front() | 首端原位构造元素 | |
resize() | 改变存储元素的个数详见 | |
swap() | 交换内容 |
详细说明:assign()
使用方式
std::deque<char> characters;// 用法1
void assign(size_type count, const T& value);
characters.assign(5, 'a'); // 容器:a a a a a// 用法2
void assign( InputIt first, InputIt last );
const std::string extra(6, 'b');
characters.assign(extra.begin(), extra.end()); //容器:bbbbbb// 用法3
void assign( std::initializer_list<T> ilist ); // C++11新特性
characters.assign({'C', '+', '+', '1', '1'}); // 容器:C++11
- 用count个value副本替换容器中的内容
- 以[first, last)中的元素替换(其中有任一实参是指向*this中的迭代器时行为未定义)
- 以来自ilist 的元素替换内容。
详细说明:insert()
// 用法1
iterator insert( const_iterator pos, const T& value );
iterator insert( const_iterator pos, T&& value ); //C++11 起// 用法3
iterator insert( const_iterator pos, size_type count, const T& value );// 用法4
iterator insert( const_iterator pos, InputIt first, InputIt last );// 用法5 C++11起
iterator insert( const_iterator pos, initializer_list<T> ilist );
- 用法1、2:在pos前插入value
- 用法3:在pos前插入value个count副本
- 用法4:在 pos 前插入来自范围 [first, last) 的元素。
- 用法5:在pos前插入ilist元素
详细介绍:resize()
重设容器大小以容纳count个元素
void resize( size_type count );
void resize( size_type count, const value_type& value );
如果deque.size() > count:减少容器到它的前count个元素
如果deque.size() <= count:①追加额外的默认插入元素②追加额外的value的副本
双端例题:LC103 二叉树的锯齿形层序遍历
题目
返回Z字型顺序下,树的节点值数组(层层遍历,从左往右,从右往左,交替)
每层存一个数组,最后返回元素是数组的数组
解答:
class Solution
{
public:vector<vector<int>> zigzagLevelOrder(TreeNode *root){if (!root){return {};}// 使用双端队列deque<TreeNode *> treeq;treeq.push_back(root);// 判断当前,队列从头pop还是从尾popbool lTor = true;vector<vector<int>> answer;while (!treeq.empty()){deque<TreeNode *> temp = treeq;treeq.clear();// 遍历当前层级TreeNode *curnode;// 层级节点值vector<int> levelVec = {};while (!temp.empty()){// 从左至右出,从头出// 子节点从尾端进入,按前序遍历if (lTor){curnode = temp.front();temp.pop_front();levelVec.push_back(curnode->val);if (curnode->left)treeq.push_back(curnode->left);if (curnode->right)treeq.push_back(curnode->right);}else{// 从右至左,从尾出// 子节点从首端进入,后序遍历curnode = temp.back();temp.pop_back();levelVec.push_back(curnode->val);if (curnode->right)treeq.push_front(curnode->right);if (curnode->left)treeq.push_front(curnode->left);}}lTor = !lTor;answer.push_back(levelVec);}return answer;}
};
优先队列:priority_queue
头文件:<queue>
初始化与定义
// elemtype为队列中元素的类型
// what_vector为,存储元素的底层容器是什么
// class_type是一个类,用于比价
std::priority_queue<elem_type, what_vector, class_type> pq;// 创建一个大根堆,默认情况下
std::priority_queue<int> max_heap;
// 创建一个小根堆
std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap; // 自定义比较器
struct compare{// 需要重载()运算符bool operator()(int a, int b){return a > b;}
};std::priority_queue<int, std::vector<int>, compare> custom_min_heap;
成员函数
- pop()
- push()
- top()
- front()
【关于优先队列的比较器】
我们可以把堆想象成一个水平横向的会场,最右端为入口(即top)
更尊贵的客人更深入会场,即更靠近会场左端。
而更为尊贵的客人,是在比较器中获得true的那一位。
所以,less
重载了operator<
,我们获取的却是大根堆,因为更小
的元素往里走了。
参考文章