二叉树的前序遍历、中序遍历、后序遍历的代码放在我的github:
https://github.com/Penkace/Datastructure/blob/master/BinaryTreeTraversal.cpp
问题描述:
给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历)
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
例如,给出一个数组 [3,9,20,null,null,15,7]:
3 / \ 9 20 / \ 15 7
按照自底向上遍历的层次遍历为:
[ [15,7], [9,20], [3] ]
解题思路:
层次遍历,可以运用广度遍历的思想实现从上往下的逐层遍历。从头结点开始逐层遍历,开辟一个新队列,让头结点入队并计算此时的长度,然后开始循环,一直遍历到底层,判断的终止条件就是队列不为空。
循环里面,队列头出队,判断其是否有左右子结点,如果有,则入队,但此时还不需要更新队列的长度,当前队列的长度是每层的长度。当这层的长度减为0时,就说明这层的遍历结束,开始更新长度为下一层的长度。
出队的元素的值逐个压入到新开辟的vector数组中,在该层长度减为0时,除了更新下一层的长度,还要把这层的结点的值,即已经存放了该层值得vector数组,压入到结果的二维动态数组。
因为题目要求从底向上逐层遍历,所以调用vector数组的insert方法,每次都插入到数组头部,这样就会使最开始插入的,即第一层,移动为动态数组的最后,达到题目的要求。
解决代码(代码可以优化,如果有想法可以在评论交流学习):
/**
* 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>> result; //存放遍历结果的二维动态数组
if (root == NULL) return result;
queue<TreeNode *> level; //存放遍历的叶子结点
vector<int> lvalue; //存放每层遍历的叶子结点的值
level.push(root);
int l = level.size(); //初始化level及其长度
while (!level.empty()) { //当level为空,说明已经完成遍历
TreeNode *temp = level.front();//队列queue的pop()方法是没有返回值的,所以需要用到front()取值
level.pop(); //删去队列头元素,即遍历了一个结点
l--; //该层结点还需遍历结点数为l--
lvalue.push_back(temp->val); //出队的结点的值存放到存储改成结点值的动态数组中
if (temp->left != NULL) level.push(temp->left);
if (temp->right != NULL) level.push(temp->right);//如果存在左右子结点,则加入到level队列中,等到上一次层的所有结点遍历结束,即l=0。
if (l == 0) {
l = level.size();
result.insert(result.begin(), lvalue);
lvalue.clear();
} //当l=0,即该层所有结点遍历结束,更新level的长度l为下一层的长度,然后把lvalue插入到结果result数组中,每次都从头插入,保证自底向上的顺序遍历,
}
return result;
}
};