zoukankan      html  css  js  c++  java
  • 二叉树的遍历

    参考链接:https://segmentfault.com/a/1190000016674584

    前言

    二叉树的前中后序遍历是面试考察中一个重要的点。而递归方法是最简单实现的,所以要信手拈来。非递归方法更要加以掌握。前序就是根-左-右,中序是左-根-右,后序是左-右-根。
    有两种通用的遍历树的策略:
    深度优先搜索(DFS)
    在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。
    深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为前序遍历,中序遍历和后序遍历。
    宽度优先搜索(BFS)
    我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。

    层次遍历

    题目链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/

    非递归,用队列实现(其实自己想了会能不能用递归结果自己不会。。。

    看了下题解,它的递归实现其实用了深度优先。

    class Solution:
        def levelOrder(self, root: TreeNode) -> List[List[int]]:
            if root==None:
                return []
            result = [[root.val]]
            quene = [(root,1)]
            while(quene):
                root,count = quene.pop(0)
                if root.left:
                    quene.append((root.left,count+1))
                    if count+1>len(result):
                        result.append([root.left.val])
                    else:
                        result[count].append(root.left.val)
                if root.right:
                    quene.append((root.right,count+1))
                    if count+1>len(result):
                        result.append([root.right.val])
                    else:
                        result[count].append(root.right.val)
            return result
    

    前序遍历

    题目描述:链接 https://leetcode-cn.com/problems/binary-tree-preorder-traversal/description/?utm_source=LCUS&utm_medium=ip_redirect_q_uns&utm_campaign=transfer2china

    然鹅,很简单的递归算法我自己实现的时候都会出错。。。还是太太菜

    class Solution:
        def preorderTraversal(self, root: TreeNode) -> List[int]:
            list = []
            self.preorderHelp(list,root)
            return list
        def preorderHelp(self,list,root):
            if root==None:
                return None
            else:
                list.append(root.val)
                self.preorderHelp(list,root.left)
                self.preorderHelp(list,root.right)
    

    非递归,使用栈。先压右子树再压左子树

    class Solution:
        def preorderTraversal(self, root: TreeNode) -> List[int]:
            result = []
            stack = [root,]
            if root==None:
                return result
            while(stack):
                root = stack.pop()
                result.append(root.val)
                if root.right!=None:
                    stack.append(root.right)
                if root.left!=None:
                    stack.append(root.left)
            return result
    

    中序遍历

    链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

    递归方法:

    class Solution:
        def inorderTraversal(self, root: TreeNode) -> List[int]:
            result = []
            self.inordefHelper(result,root)
            return result
        def inordefHelper(self,result,root):
            if root==None:
                return
            self.inordefHelper(result,root.left)
            result.append(root.val)
            self.inordefHelper(result,root.right)

     非递归采用两层循环:按照根节点左子树顺序压栈,然后再改变指针,对右子树采用同样的方法

    class Solution:
        def inorderTraversal(self, root: TreeNode) -> List[int]:
            result = []
            stack = []
            if root==None:
                return []
            while(stack or root!=None):
                while(root!=None):
                    stack.append(root)
                    root = root.left
                root = stack.pop()
                result.append(root.val)
                root = root.right
            return result
    

    后序遍历:

    链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/submissions/

    递归写法

    class Solution:
        def postorderTraversal(self, root: TreeNode) -> List[int]:
            result = []
            if root==None:
                return result
            self.postHelper(result,root)
            return result
        def postHelper(self,result,root):
            if root==None:
                return
            self.postHelper(result,root.left)
            self.postHelper(result,root.right)
            result.append(root.val)
    

    非递归写法:(对已经访问过的右子树做标记,根据后续的特点,若访问过右子树肯定根节点的右节点是刚被访问过的,用指针添加新的节点),不明白的话看参考链接哦

    class Solution:
        def postorderTraversal(self, root: TreeNode) -> List[int]:
            result = []
            stack = []
            pre = None
            if root==None:
                return result
            while(stack or root!=None):
                while(root!=None):
                    stack.append(root)
                    root = root.left
                root = stack[-1]
                if root.right==None or root.right==pre:
                    root = stack.pop()
                    result.append(root.val)
                    pre = root
                    root = None
                else:
                    root = root.right
            return result
    

    针对后序遍历还有个简化方法

    双栈法
    前序遍历比较简单,因为是先访问根
    1.用一个栈实现 根->右->左 的遍历
    2.用另一个栈将遍历顺序反过来,使之变成 左->右->根
    实现代码:

    class Solution:
        def postorderTraversal(self, root: TreeNode) -> List[int]:
            result = []
            stack1 = [root,]
            stack2 = []
            if root == None:
                return []
            while(stack1):
                root = stack1.pop()
                stack2.append(root)
                if root.left!=None:
                    stack1.append(root.left)
                if root.right!=None:
                    stack1.append(root.right)
            while(stack2):
                root = stack2.pop()
                result.append(root.val)
            return result

    双栈简化:直接每次插入时将元素插入到头部class Solution:

        def postorderTraversal(self, root: TreeNode) -> List[int]:
            result = []
            stack1 = [root,]
            stack2 = []
            if root == None:
                return []
            while(stack1):
                root = stack1.pop()
                result.insert(0,root.val)
                if root.left!=None:
                    stack1.append(root.left)
                if root.right!=None:
                    stack1.append(root.right)
            return result
  • 相关阅读:
    02-MySQL的安装和管理
    01-pymysql模块的安装
    异常处理
    USACO 2015 Feb Censoring
    玄武密码(bzoj4327)(JSOI2012)
    浅谈AC自动机
    Equation
    JOI五子棋
    浅谈Tarjan
    年轮蛋糕JOI2014Final
  • 原文地址:https://www.cnblogs.com/ditingz/p/12114681.html
Copyright © 2011-2022 走看看