二叉树的遍历(先序,中序,后序,层序)

总结一下二叉树的遍历,利用模板的写法来写。

二叉树的遍历分两种:

DFS:先序,中序,后续 ---->利用栈stack

BFS:层序  ---->利用队列queue

144. 二叉树的前序遍历                                        前序遍历解答

94. 二叉树的中序遍历                                          中序遍历解答

145. 二叉树的后序遍历                                        后序遍历解答

层序遍历比较简单,LeetCode没有专门的题目,简单说就是一个queue往里面添加节点,其实就是宽度优先搜索。

这里只为了面试的方便,三序遍历采用模板的形式写出。面试时候要考非递归自己乱写还是容易出错,老老实实根据模板背下来,反正遇到复杂题目也不会用非递归,应试吧!

模板形式:

if(p){
  ...
}
else{
  ...
}

总结一下:解答别人已经写得非常详细了。我就写一点怎么记下来的应试吧。。。

  1. 先序遍历的顺序:根-左-右。所以在if{...}中间肯定要先把当前访问的节点p给添加到vector中。同时添加到stack中,并且去访问p->left(去访问左侧的节点),然后在else{...}中就直接去访问右节点才对,但是此时p已经是NULL,所以要从栈中取出栈顶s.top(),然后去访问其右侧节点就可以了。
  2. 中序遍历的顺序:左-根-右。所以在if{...}中间要一直向左去找下去,并且把每一个都添加到stack中(root,root->left,...),在else{...}中,则表示现在已经找到最左侧了,但是此时p又成NULL了,所以要取出栈顶元素,p = s.top()。然后再去找右侧的节点。
  3. 后续遍历顺序:左-右-根,但是如果你按照根-右-左的顺序访问,每次把新得到值插入vector最前面就可以了(使用insert)。额....画个图就能理解了。跟先序遍历一样。
  4. 写完了之后仔细想想这个模板跟递归法的写法差不多?就好像先序,除去其它的压栈弹栈操作,不就是:先访问了当前的p->val,再访问左节点p=p->left,再去访问右节点p = p->right。其它的自己类比下吧。。。
  5. 一个非常重要的点,这种写法的循环条件:while(p || !s.empty())不用先存入一个root结点到stack s中。

前序遍历

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        if(!root)   return {};
        stack<TreeNode*> s;//不用先存入一个root结点到s中
        vector<int> res;
        TreeNode* p = root;
        while(p || !s.empty()){
            if(p){
                res.push_back(p->val);
                s.push(p);
                p = p->left;
            }
            else{
                p = s.top();
                s.pop();
                p = p->right;
            }
        }
        return res;
    }
};

中序遍历

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        if(!root)   return {};
        stack<TreeNode*> s;
        vector<int> res;
        TreeNode* p = root;
        while(p || !s.empty()){
            if(p){
                s.push(p);
                p = p->left;
            }
            else{
                p = s.top();
                s.pop();
                res.push_back(p->val);
                p = p->right;
            }
        }
        return res;
    }
};

后序遍历

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        if(!root)   return {};
        stack<TreeNode*> s;
        vector<int> res;
        TreeNode* p = root;
        while(p || !s.empty()){
            if(p){
                res.insert(res.begin(),p->val);
                s.push(p);
                p=p->right;
            }
            else{
                p = s.top();
                s.pop();
                p = p->left;
            }
        }
        return res;
    }
};

层序遍历:

class Solution {
public:
    vector<int> levelOrder(TreeNode* root) {
        if (!root) return {};
        vector<int> res;
        queue<TreeNode*> q;q.push(root);
        while (!q.empty()) {
                TreeNode *t = q.front(); q.pop();
                res.push_back(t->val);
                if (t->left) q.push(t->left);
                if (t->right) q.push(t->right);
            }
        }
        return res;
    }
};

剑指offer第60题:分层打印二叉树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值