1. queue的介绍和使用
1.1 queue的介绍
1.队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。
2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。
3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:
- empty:检测队列是否为空
- size:返回队列中有效元素的个数
- front:返回队头元素的引用
- back:返回队尾元素的引用
- push_back:在队列尾部入队列
- pop_front:在队列头部出队列
4.标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。
1.2 stack的使用
函数声明 | 接口说明 |
---|---|
queue (const container_type& ctnr = container_type()) | 构造空的队列 |
bool empty() const | 检测队列是否为空,是返回true,否则返回false |
size_type size() const | 返回队列中有效元素的个数 |
value_type& front() | 返回队头元素的引用 |
const value_type& front() const | 返回队头元素的const引用 |
value_type& back() | 返回队尾元素的引用 |
const value_type& back() const | 返回队尾元素的cosnt引用 |
void push(value_type& val) | 在队尾将元素val入队列 |
void pop() | 将队头元素出队列 |
template <class… Args> void emplace (Args&&… args) (C++11) | 在队尾构造元素 |
void swap(queue& x) | 交换两个队列中的元素 |
1.3 queue在OJ上的使用
1.3.1 二叉树的层次遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if (!root)
{
return res;
}
vector<int> vtmp;
queue<TreeNode *> qu; // 需要操作其左右孩子,则queue类型确定为TreeNode*
TreeNode * cur;
int len = 1;
qu.push(root);
while (!qu.empty())
{
for (int i = 0; i < len; i++)
{
cur = qu.front();
vtmp.push_back(cur->val);
qu.pop();
if (cur->left)
{
qu.push(cur->left);
}
if (cur->right)
{
qu.push(cur->right);
}
}
res.push_back(vtmp);
vtmp.clear();
len = qu.size(); // len统计该层有多少元素
}
return res;
}
};
1.3.2 二叉树的层次遍历II
修改一行代码即可
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
if (!root)
{
return res;
}
vector<int> vtmp;
queue<TreeNode *> qu; // 需要操作其左右孩子,则queue类型确定为TreeNode*
TreeNode * cur;
int len = 1;
qu.push(root);
while (!qu.empty())
{
for (int i = 0; i < len; i++)
{
cur = qu.front();
vtmp.push_back(cur->val);
qu.pop();
if (cur->left)
{
qu.push(cur->left);
}
if (cur->right)
{
qu.push(cur->right);
}
}
res.insert(res.begin(), vtmp); // 只需要修改一行即可
vtmp.clear();
len = qu.size(); // len统计该层有多少元素
}
return res;
}
};
1.3.3 两个队列实现一个栈
class queueStack
{
queue<int> m_qu1;
public:
queueStack()
{
}
void push(int x)
{
m_qu1.push(x);
}
void pop()
{
queue<int> m_qu2;
while (m_qu1.size() > 1)
{
m_qu2.push(m_qu1.front());
m_qu1.pop();
}
m_qu1 = m_qu2;
}
int top()
{
queue<int> m_qu2;
while (m_qu1.size() > 1)
{
m_qu2.push(m_qu1.front());
m_qu1.pop();
}
int tmp = m_qu1.front();
m_qu2.push(m_qu1.front());
m_qu1 = m_qu2;
return tmp;
}
};
1.3.4 用两个栈实现队列
class MyQueue {
private:
stack<int> s1,s2;
public:
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
while(!s2.empty())
{
int temp=s2.top();
s2.pop();
s1.push(temp);
}
s1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
int res=peek();
s2.pop();
return res;
}
/** Get the front element. */
int peek() {
while(!s1.empty())
{
int temp=s1.top();
s1.pop();
s2.push(temp);
}
return s2.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return s1.empty()&&s2.empty();
}
};