其他分享
首页 > 其他分享> > 二叉树——前序、中序、后序、层序(递归&非递归)

二叉树——前序、中序、后序、层序(递归&非递归)

作者:互联网

二叉树——前序、中序、后序、层序(递归&非递归)

二叉树——前序遍历(中——左——右)

递归

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        # 递归
        res = []
        def preoder(root):
            if not root: return 
            res.append(root.val)
            preoder(root.left)
            preoder(root.right)
        preoder(root)
        return res

非递归

使用栈结构辅助输出结果,栈的特点是先进后出,那就需要先压入右边再压入左边。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:

        # 非递归
        res, stack = [], [root]
        while stack:
            node = stack.pop()
            if node:
                res.append(node.val)
                stack.append(node.right)
                stack.append(node.left)
        return res

二叉树——中序遍历(左——中——右)

递归

先递归遍历左子树,然后加入根节点,再遍历右子树。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        # 递归
        res = []
        def inorder(root):
            if not root:
                return 
            inorder(root.left)
            res.append(root.val)
            inorder(root.right)
        inorder(root)
        return res

非递归

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        # 非递归
        res, stack = [], []
        while root or stack:
            if root:
                stack.append(root)
                root = root.left
            else:
                node = stack.pop()
                res.append(node.val)
                root = node.right
        return res

二叉树——后序遍历(左——右——中)

递归

先遍历左子树,再遍历右子树,最后把根节点加入。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        def postorder(root):
            if not root:
                return 
            postorder(root.left)
            postorder(root.right)
            res.append(root.val)
        postorder(root)
        return res

非递归

原后序遍历是左——右——中,那我们就可以构建中——右——左的结构;又因为非递归使用栈作为辅助,我们需要像前序遍历一样,把左右进行对调,先压入左边,再压入右边。最后将列表进行翻转。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        # 非递归
        res, stack = [], [root]
        while stack:
            node = stack.pop()
            if node:
                res.append(node.val)
                stack.append(node.left)
                stack.append(node.right)
        return res[::-1]

二叉树——层序遍历

层序遍历也可称为宽度优先遍历,先访问树的第一层节点,再访问树的第二层节点,依次遍历。在同一层节点中,以左到右的顺序依次访问。

递归

递归是需要自己写一个函数或调用函数的。 首先我们先遍历根节点,然后用列表[层].append(节点值)的形式保存当前层的节点值。若该节点有左右节点,则以该(左/右)节点作为根节点,来遍历该层的节点值。

注意:有一种特例,若当前层(level)与返回列表的长度(len(res))相等,意味着这是全新的一层(与之前相比),需要在原始列表中创建一个列表。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        # 递归
        res = []
        def helper(node, level):
            if not node: return []
            if len(res) == level:
                res.append([])
            res[level].append(node.val)
            helper(node.left, level + 1)
            helper(node.right, level + 1)
        helper(root, 0)
        return res

非递归

方法一比较简单,使用的是列表生成式。不太能理解的是for kid in (n.left, n.right),最初的理解是:在第n层,kid要属于n的左边或者n的右边。

方法二使用的是队列,也可以修改为双端队列的方式。使用collections.deque()就可以了,然后cur = queue.pop(0)可以改为cur = queue.popleft(),这句的作用是删除第一个元素。然后,删除的cur节点的值放入当前层的temp(暂时列表中),若该cur节点还有左右节点,同样放入队列中进行遍历。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        # 非递归(方法一)
        # ans, level = [], [root]
        # while any(level):
        #     ans.append([node.val for node in level])
        #     level = [kid for n in level for kid in (n.left, n.right) if kid]
        # return ans

        # 非递归(方法二)
        if not root: return []
        res, queue = [], [root]
        while queue:
            temp = []
            for _ in range(len(queue)):
                cur = queue.pop(0)
                temp.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            res.append(temp)
        return res

参考:链接

标签:node,right,val,递归,前序,二叉树,root,self,left
来源: https://blog.csdn.net/mary_0830/article/details/119892593