二叉树遍历

一、递归法

1、前序

	vector<int> res;
    void dfs(TreeNode* root){
        if(root == nullptr)
            return;
        res.push_back(root->val);
        dfs(root->left);
        dfs(root->right);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        dfs(root);
        return res;
    }

2、中序

	vector<int> res;
    void dfs(TreeNode* root){
        if(root == nullptr)
            return;
        dfs(root->left);
        res.push_back(root->val);
        dfs(root->right);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        dfs(root);
        return res;
    }

3、后序

	vector<int> res;
    void dfs(TreeNode* root){
        if(root == nullptr)
            return;
        dfs(root->left);
        dfs(root->right);
        res.push_back(root->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        dfs(root);
        return res;
    }

二、迭代法

1、前序

	vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> stk;
        vector<int> res;
        stk.push(root);
        while(!stk.empty()){
            auto node = stk.top();
            stk.pop();
            if(node != nullptr){
                res.push_back(node->val);
                stk.push(node->right);//栈先进后出,所以右孩子先进栈
                stk.push(node->left);
            }
        }
        return res;
    }

2、中序

 	vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> stk;
        vector<int> result;
        TreeNode* cur = root;
        //循环结束的条件为:树节点遍历完了,即cur为空且栈也为空
        while(cur != nullptr || !stk.empty()) {
            if(cur != nullptr) {//当cur非空,将此节点入栈,继续深度遍历
                stk.push(cur);
                cur = cur->left;  //按照中序遍历的顺序:左中右
            }
            else {//cur为空,说明遍历到叶子节点了,从栈中取最后一个节点存入result中
                cur = stk.top();
                stk.pop();
                result.push_back(cur->val);
                cur = cur->right;  //若右孩子为空,则从栈中取双亲节点
            }
        }
        return result;
    }

3、后序

	vector<int> postorderTraversal(TreeNode* root) {
        //后序为“左右中”,先按照前序“中左右”的反序“中右左”遍历,再将结果反转
        vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> stk;
        vector<int> res;
        stk.push(root);
        while(!stk.empty()){
            TreeNode* node = stk.top();
            stk.pop();
            if(node != nullptr){
                res.push_back(node->val);
                stk.push(node->left);//因为按“中右左”遍历,所以左孩子先进栈
                stk.push(node->right);
            }
        }
        reverse(res.begin(), res.end());//将结果反转
        return res;
    }

4、层序

方法一:先判断是否为空节点,再入队列。

	vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que; //借用队列
        if(root != nullptr) que.push(root);
        vector<vector<int>> res;
        while(!que.empty()) {
            int n = que.size();
            vector<int> temp;
            for(int i = 0; i < n; i++) {
                TreeNode* node = que.front();
                que.pop();
                temp.push_back(node->val);
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            res.push_back(temp);//因为先判断是否为空节点,所以temp一定不为空
        }
        return res;
    }

方法二:先入队列,再判断是否为空节点(注意最后一层需先判断temp是否为空再push_back)

	vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que; //借用队列
        que.push(root);
        vector<vector<int>> res;
        while(!que.empty()) {
            int n = que.size();
            vector<int> temp;
            for(int i = 0; i < n; i++) {
                TreeNode* node = que.front();
                que.pop();
                if(node != nullptr){
                	temp.push_back(node->val);
                	que.push(node->left);
                	que.push(node->right);
                }
            }
            if(!temp.empty())//此处需要注意!!!
                res.push_back(temp);
        }
        return res;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值