LintCode笔记(4)——二叉树的层次遍历II

给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历)

样例

给出一棵二叉树 {3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

按照从下往上的层次遍历为:

[
  [15,7],
  [9,20],
  [3]
]
/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
 
 
class Solution {
    /**
     * @param root : The root of binary tree.
     * @return : buttom-up level order a list of lists of integer
     */
public:
    vector<vector<int>> levelOrderBottom(TreeNode *root) {
        // write your code here
        TreeNode *p = root;
        vector<vector<int>> result;//最终结果,保存各层的值,每个vector为一层
        vector<queue<TreeNode*>> nodes;//保存各层节点,每个queue为同一层的节点
        //如果树为空,则返回空队列
        if(p == NULL)
            return result;
        //使用队列queue类型,保存第一层的节点,即根节点
        queue<TreeNode*> node;
        node.push(p);
        nodes.push_back(node);
        //保存第一层节点的值,即根节点的值
        vector<int> lay0;
        lay0.push_back(p->val);
        result.push_back(lay0);
        
        int i = 1;
        while(1)
        {
            vector<int> lay;
            queue<TreeNode*> node;
            nodes.push_back(node);
            //提出上一层的节点队列,遍历其中节点的左孩子和右孩子并保存到本层节点队列中
            while(!nodes[i-1].empty())
            {
                if(nodes[i-1].front()->left != NULL)
                {
                    nodes[i].push(nodes[i-1].front()->left);
                    lay.push_back(nodes[i-1].front()->left->val);
                }
                if(nodes[i-1].front()->right != NULL)
                {
                    nodes[i].push(nodes[i-1].front()->right);
                    lay.push_back(nodes[i-1].front()->right->val);
                }
                nodes[i-1].pop();
            }
            i++;
            //如果本层节点队列为空,则遍历结束,退出
            if(lay.size() == 0)
                break;
            result.insert(result.begin(),lay);
            
        }
        return result;
    }
};

实现代码如上所示,这里用queue的原因是保证每次先出的是最先进队列的元素,保证了遍历是从左向右进行的。使用stack也可以实现功能,但有时候会出现从右向左遍历的情况。

由于stack和queue用的都比较少,在这里总结一下。

1、stack模版

stack模版类的定义在<stack>中,有两个参数,一个是元素类型,一个是容器类型。这里元素类型是必须要有的,一般容器类型参数可以忽略。

stack模版类对象的定义方法如下:

stack<int> intStack;//int类型的栈
stack<TreeNode*> nodes;//上面用到的树的节点指针类型的栈
stack是数据结构中的栈,有后进先出的原则,stack中常用的函数为:

s.top() 返回栈顶元素,即最新入栈的元素;

s.push(x) 元素入栈;

s.pop() 栈顶元素出栈;

s.size() 返回栈中元素的数目;

s.empty() 判断栈中是否为空,如果空则返回true;


2、queue模版

queue模版是数据结构中的队列,有先进先出的原则,同样也有两个参数,元素类型和容器类型,同样,容器类型可是可忽略的。

queue对象的定义方式与stack相似,这里不再赘述。

常用的queue函数为:

q.push(x) 入队,即将元素放在队尾;

q.pop(x) 出队,即将队头元素出队;

q.front() 返回的是队头元素;

q.back() 返回的是队尾元素;

q.size() 、q.empty()与stack相似,不再赘述




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值