队列和双端队列在二叉树层序遍历中的应用 简单示例
LeetCode -103题二叉树的锯齿形层序遍历
题目要求:给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
按照层序遍历,使用队列来管理遍历的元素
第一层 3
第二层 9 20
第3层 15 7
但是输出要求是
3
20 9
15 7
从输出要求可以看出
在第二层输出元素与遍历的顺序相反,本来想用一个标记进行处理,执行之后发现只能通过部分用例;
1、观察输出与遍历顺序的差异后,发现可以用双端队列deque进行管理,在遍历第二层的时候,依次遍历 9 20,在deque的头部插入9 20,这样取出来后为20 9
2、在遍历第3层的时候,依次遍历15 7,在deque的尾部插入15 7,取出来后为15 7
3、总结规律:在遍历时,前一次使用双端队列的尾部插入元素,后一次使用双端队列的头部插入元素,再使用双端队列的尾部插入元素,依次遍历二叉树
代码如下:
#include <iostream>
#include <vector>
#include <queue>
#include <deque>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root)
{
vector<vector<int>> result;
queue<TreeNode*> q;
if (root != nullptr) {
q.emplace(root);
}
bool isInOrder = true;
while (!q.empty()) {
deque<int> deq;
int size = q.size();
for (int i = 0; i < size; i++) {
TreeNode *node = q.front();
q.pop();
if (isInOrder) {
// 尾部插入
deq.emplace_back(node->val);
} else {
// 头部插入
deq.emplace_front(node->val);
}
// 该节点二叉树的左节点添加到队列中
if (node->left) {
q.emplace(node->left);
}
// 该节点二叉树的右节点添加到队列中
if (node->right) {
q.emplace(node->right);
}
}
vector<int> vec;
for (auto item : deq) {
vec.emplace_back(item);
}
result.emplace_back(vec);
// 上一层遍历完成后, 下一层需要改变双端队列的插入部位(头还是尾)
isInOrder = !isInOrder;
}
return result;
}
};
执行结果: