题目分析:
- 给定一棵二叉树,自顶向下,按照Z字形分层遍历。即如果本层是自左向右,则下一层是自右向左。
解题思路:
分析
此题本质函数二叉树的层次遍历,不同是输出每层信息存在方向。使用两个队列实现节点的分层访问。同时设置标志来决定每层节点输出方向。
非递归实现
利用队列实现,具体方法如下:
1)若树节点非空,则入队1;
2)定义队列2,队列1元素依次出队,并判断是否存在左右子节点,存在让其进入队列2,并将当前层信息保存到临时变量中;
3)当队列1中所有元素均出队后,判断当前层访问的方向,依据访问的方向,调整临时变量中存放当前层节点信息的顺序,同时设置下一层节点的访问方向;
4)将临时变量中存放的当前层节点元素放入到输出结果变量中,并清空临时变量;
5)利用队列2更新队列1,然后循环执行步骤2)、3)、4)和5),直到访问完整棵树的所有节点。
注意:需要一个变量记录每层节点的输出方向,从而实现z字形的分层遍历。
实现程序
//二叉树的Z字形遍历 vector< vector<int> > zigzagLevelOrder(TreeNode *root) { vector< vector<int> > result; // 空树的处理 if (root == NULL) return result; vector<int> res; // 创建队列 queue<TreeNode *> que1; TreeNode *temp = root; int flag = 0; // 根节点压栈 que1.push(temp); while (!que1.empty()) { // 定义另一个队列,用于存放下一层节点信息 queue<TreeNode *> que2; // 遍历当前层所有队列元素 while (!que1.empty()) { temp = que1.front(); // 出队 que1.pop(); // 判断其左右子树是否存在,存在则入下一层节点队列 if (temp->left) que2.push(temp->left); if (temp->right) que2.push(temp->right); // 将当前出队节点信息保存到临时结果中 res.push_back(temp->val); } // 判断遍历方向,并根据具体情况进行元素逆转,同时确定下一层遍历的方向 if (flag == 1) { reverse(res.begin(), res.end()); flag = 0; } else flag = 1; // 将当前层元素信息保存到结果中 result.push_back(res); // 临时存储当前层节点信息置空,用于下一层信息临时存储 res.clear(); // 更新队列1信息 que1 = que2; } }