一、算法描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
数据范围:0≤n≤15000≤n≤1500,树上每个节点的val满足 ∣val∣<=1500∣val∣<=1500
要求:空间复杂度:O(n),时间复杂度:O(n)
示例1
输入:{1,2,3,#,#,4,5}
返回值:[[1],[3,2],[4,5]]
说明:如题面解释,第一层是根节点,从左到右打印结果,第二层从右到左,第三层从左到右。
二、解题思路
这个算法基本上和普通的层次遍历算法类似,只是在遍历每一层的节点时,根据奇偶性选择不同的顺序将子节点加入下一层的栈中,从而实现按之字形顺序打印二叉树的效果。
三、C++代码实现
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
// 定义二叉树的节点结构
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
// 按之字形顺序打印二叉树的算法
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
// 创建一个vector,用于存储结果
vector<vector<int>> res;
// 如果二叉树为空,直接返回结果
if (root == nullptr) {
return res;
}
// 创建两个栈,一个用于存储奇数层的节点,一个用于存储偶数层的节点
stack<TreeNode*> s1, s2;
// 将根节点加入奇数层的栈
s1.push(root);
// 遍历每一层的节点
while (!s1.empty() || !s2.empty()) {
vector<int> level;
// 如果奇数层的栈不为空
if (!s1.empty()) {
// 遍历奇数层的所有节点,并将其左右子节点加入偶数层的栈中
while (!s1.empty()) {
// 取出栈顶的节点
TreeNode* node = s1.top();
// 将节点的值加入当前层的结果中
level.push_back(node->val);
// 将节点的左右子节点加入偶数层的栈中
if (node->left != nullptr) {
s2.push(node->left);
}
if (node->right != nullptr) {
s2.push(node->right);
}
// 弹出栈顶的节点
s1.pop();
}
}
// 如果偶数层的栈不为空
else if (!s2.empty()) {
// 遍历偶数层的所有节点,并将其左右子节点加入奇数层的栈中
while (!s2.empty()) {
// 取出栈顶的节点
TreeNode* node = s2.top();
// 将节点的值加入当前层的结果中
level.push_back(node->val);
// 将节点的左右子节点加入奇数层的栈中
if (node->right != nullptr) {
s1.push(node->right);
}
if (node->left != nullptr) {
s1.push(node->left);
}
// 弹出栈顶的节点
s2.pop();
}
}
// 将当前层的结果加入最终结果中
res.push_back(level);
}
return res;
}
int main() {
// 构建二叉树
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(7);
// 调用按之字形顺序打印二叉树的函数
vector<vector<int>> res = zigzagLevelOrder(root);
// 输出结果
for (int i = 0; i < res.size(); i++) {
cout << "Level " << i + 1 << ": ";
for (int j = 0; j < res[i].size(); j++) {
cout << res[i][j] << " ";
}
cout << endl;
}
return 0;
}