• 非递归遍历树的总结(前中后序)


    递归,显而易见。

    非递归,bfs,是用队列。

    而前中后序,一般都是用栈。

    一种很直观的方法是,采用一个flag,记录第几次进栈出栈,从而决定是否打印,决定下一个入栈的是左还是右子节点。

    但是下面的方法,更近精简和巧妙。

    https://discuss.leetcode.com/topic/30632/preorder-inorder-and-postorder-iteratively-summarization

    把前、中、后三种遍历都总结了,而且没有用多余的flag。采用的技巧是同时判断栈和cur节点。

    前序:

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode p = root;
        while(!stack.isEmpty() || p != null) {
            if(p != null) {
                stack.push(p);
                result.add(p.val);  // Add before going to children
                p = p.left;
            } else {
                TreeNode node = stack.pop();
                p = node.right;   
            }
        }
        return result;
    }
    View Code

    中序:

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode p = root;
        while(!stack.isEmpty() || p != null) {
            if(p != null) {
                stack.push(p);
                p = p.left;
            } else {
                TreeNode node = stack.pop();
                result.add(node.val);  // Add after all left children
                p = node.right;   
            }
        }
        return result;
    }
    View Code

    后序:

    public List<Integer> postorderTraversal(TreeNode root) {
        LinkedList<Integer> result = new LinkedList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode p = root;
        while(!stack.isEmpty() || p != null) {
            if(p != null) {
                stack.push(p);
                result.addFirst(p.val);  // Reverse the process of preorder
                p = p.right;             // Reverse the process of preorder
            } else {
                TreeNode node = stack.pop();
                p = node.left;           // Reverse the process of preorder
            }
        }
        return result;
    }
    View Code

    另外,对于后序,有一种解法,是先打印,然后再反转。

    https://discuss.leetcode.com/topic/2919/my-accepted-code-with-explaination-does-anyone-have-a-better-idea

    class Solution {
    public:
        vector<int> postorderTraversal(TreeNode *root) {
            stack<TreeNode*> nodeStack;
            vector<int> result;
            //base case
            if(root==NULL)
            return result;
            nodeStack.push(root);
        while(!nodeStack.empty())
        {
            TreeNode* node= nodeStack.top();  
            result.push_back(node->val);
            nodeStack.pop();
            if(node->left)
            nodeStack.push(node->left);
            if(node->right)
            nodeStack.push(node->right);
        }
         reverse(result.begin(),result.end());
         return result;
        
    }
    View Code

    也很巧妙。

    上面这个解法,也是针对这道题目:

    https://leetcode.com/problems/binary-tree-postorder-traversal/?tab=Description

  • 相关阅读:
    HIVE(2) 之 常用函数
    HIVE的Shell操作
    HIVE常用函数(1)聚合函数和序列函数
    版本控制系统之SVN和GIT的区别
    【PyQt5】信号与槽+装饰器定义槽函数
    【PyQt5】信号与槽+多线程
    【PyQt5】信号与槽用法进阶
    【PyQt5】信号与槽用法入门
    【python之路】【5、函数学习】带装饰器的函数作业【老男孩第2期全栈】
    【python之路】【4、文件操作】数据类型、文件操作-作业 用文件储存三级菜单并执行
  • 原文地址:https://www.cnblogs.com/charlesblc/p/6445815.html
Copyright © 2020-2023  润新知