代码随想录算法训练营第三期day14-二叉树01

目录

1.T144/94/145:二叉树的递归遍历

代码实现

C++

Java

2.二叉树的迭代遍历

代码实现

C++

Java

3.二叉树的统一迭代

代码实现

C++

Java


1.T144/94/145:二叉树的递归遍历

代码实现

C++

//前序遍历
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root, res);
        return res;
    }
private:
    void traversal(TreeNode* cur, vector<int>& res) {
        if (cur == nullptr) return;
        res.push_back(cur->val);
        traversal(cur->left, res);
        traversal(cur->right, res);
    }
};

//中序遍历
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root, res);
        return res;
    }
private:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == nullptr) return;
        traversal(cur->left, vec);
        vec.push_back(cur->val);
        traversal(cur->right, vec);
    }
};

//后序遍历
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root, &res);
        return res;
    }
private:
    void traversal(TreeNode* cur, vector<int>* res) {
        if (cur == nullptr) return;
        traversal(cur->left, res);
        traversal(cur->right, res);
        res->push_back(cur->val);
    }
};

Java

//前序遍历
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        traversal(root, list);
        return list;
    }
    private void traversal(TreeNode cur, List<Integer> list) {
        if (cur == null) return;
        list.add(cur.val);
        traversal(cur.left, list);
        traversal(cur.right, list);
    }
}

//中序遍历
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        traversal(root, res);
        return res;
    }
    private void traversal(TreeNode cur, List<Integer> list) {
        if (cur == null) return;
        traversal(cur.left, list);
        list.add(cur.val);
        traversal(cur.right, list);
    }
}

//后序遍历
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        traversal(root, res);
        return res;
    }
    private void traversal(TreeNode cur, List<Integer> list) {
        if (cur == null) return;
        traversal(cur.left, list);
        traversal(cur.right, list);
        list.add(cur.val);
    }
}

2.二叉树的迭代遍历

递归遍历很简单,但有的时候会需要尽量避免递归(由于递归错误不好排查等原因),迭代也是一个不错的选择

代码实现

C++

    //前序遍历
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> st;
        if (root == nullptr) 
            return res;
        st.push(root);
        while (!st.empty()) {
            // TreeNode* cur = st.pop();//1、有别于Java
            TreeNode* cur = st.top();
            st.pop();
            res.push_back(cur->val);
            
            // st.push(cur->right);//2、空节点不入栈
            if (cur->right) st.push(cur->right);//2、空节点不入栈
            if (cur->left) st.push(cur->left);
        }
        return res;
    }

    //中序遍历
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while (cur || !st.empty()) {//非空判断合并于此
            if (cur) {
                st.push(cur);
                cur = cur->left;
            } else {
                cur = st.top();
                st.pop();
                res.push_back(cur->val);
                cur = cur->right;
            }
        }
        return res;
    }

    //后序遍历
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        if (root == nullptr) return res;//1、一定不能漏!
        stack<TreeNode*> st;
        TreeNode* cur = root;
        st.push(root);
        while (!st.empty()) {
            cur = st.top();
            st.pop();
            res.push_back(cur->val);
            if (cur->left) st.push(cur->left);
            if (cur->right) st.push(cur->right);
        }
        // reverse(res, res.begin(), res.end());
        reverse(res.begin(), res.end());
        return res;
    }

Java

    //前序遍历
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        if (root == null) return res;
        Deque<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode top = stack.removeFirst();
            res.add(top.val);
            if (top.right != null) stack.addFirst(top.right);
            if (top.left != null) stack.offerFirst(top.left);
        }
        return res;
    }

    //中序遍历
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        TreeNode cur = root;
        Stack<TreeNode> stack = new Stack<>();
        while (cur != null || !stack.isEmpty()) {
            if (cur != null) {
                stack.push(cur);
                cur = cur.left;
            } else {
                cur = stack.pop();
                res.add(cur.val);
                cur = cur.right;
            }
        }
        return res;
    }

    //后序遍历
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        if (root == null) return res;
        Deque<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        TreeNode cur = null;
        while (!stack.isEmpty()) {
            cur = stack.pop();
            res.add(cur.val);
            if (cur.left != null) stack.addFirst(cur.left);
            if (cur.right != null) stack.offerFirst(cur.right);
        }
        Collections.reverse(res);
        return res;
    }    

3.二叉树的统一迭代

如上题所见,二叉树不同遍历方式的迭代写法大相径庭,能不能用一种统一的写法,对于不同的遍历方式,只要修改一小段就行?

——当然可以!

代码实现

C++

    //中序遍历
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if (root == nullptr) return res;
        stack<TreeNode*> st;
        st.push(root);
        TreeNode* node = root;
        while (!st.empty()) {
            node = st.top();// 中节点访问过
            // st.pop();
            if (node) {
                st.pop();// 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
                if (node->right) st.push(node->right);
                st.push(node);
                st.push(nullptr);//访问过,但还没有处理,加入空节点做为标记。
                if (node->left) st.push(node->left);
            } else {// 只有遇到空节点的时候,才将下一个节点放进结果集
                st.pop();
                node = st.top();
                st.pop();
                res.push_back(node->val);
            }
        }
        return res;
    }

    //后序遍历
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        if (root == nullptr) return res;
        stack<TreeNode*> st;
        st.push(root);
        TreeNode* node;
        // while (node || !st.empty()) {
        while (!st.empty()) {
            node = st.top();
            if (node) {//就这段有区别
                st.pop();
                st.push(node);
                st.push(nullptr);
                if (node->right) st.push(node->right);
                if (node->left) st.push(node->left);
            } else {
                st.pop();
                node = st.top();
                st.pop();
                res.push_back(node->val);
            }
        }
        return res;
    }

    //前序遍历
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if (root == nullptr) return res;
        stack<TreeNode*> st;
        st.push(root);
        TreeNode* code = nullptr;
        while (!st.empty()) {
            code = st.top();
            if (code) {
                st.pop();
                if (code->right) st.push(code->right);                
                if (code->left) st.push(code->left);
                st.push(code);
                st.push(nullptr);            
            } else {
                st.pop();
                code = st.top();
                st.pop();
                res.push_back(code->val);
            }
        }
        return res;
    }

Java

    //中序遍历
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        if (root == null) return res;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        TreeNode node;
        while (!stack.isEmpty()) {
            node = stack.pop();
            if (node != null) {
                if (node.right != null) stack.push(node.right);
                stack.push(node);
                stack.push(null);
                if (node.left != null) stack.push(node.left);
            } else {
                node = stack.pop();
                res.add(node.val);
            }
        }
        return res;
    }

    //后序遍历
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        if (root == null) return res;
        Deque<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        TreeNode cur = null;
        while (!stack.isEmpty()) {
            cur = stack.pop();
            if (cur != null) {
                stack.push(cur);
                stack.push(null);
                if (cur.right != null) stack.addFirst(cur.right);
                if (cur.left != null) stack.offerFirst(cur.left);
            } else {
                cur = stack.remove();
                res.add(cur.val);
            }
        }
        return res;
    }

    //前序遍历
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        if (root == null) return res;
        Deque<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        TreeNode cur;
        while (!stack.isEmpty()) {
            cur = stack.poll();
            if (cur != null) {
                if (cur.right != null) stack.offerFirst(cur.right);
                if (cur.left != null) stack.offerFirst(cur.left);
                stack.addFirst(cur);
                stack.push(null);
            } else {
                cur = stack.pop();
                res.add(cur.val);
            }
        }
        return res;
    }

个人比较喜欢递归(简单)和统一迭代(好记)~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值