二叉树的遍历

扫码查看

1 递归遍历

写法类似于回溯,前序 中序 后序遍历的套路一样,只是保存元素的位置不同.层序遍历的关键是要添加level参数,用于记录节点所在的层数.

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
# 经典的递归法
from typing import List
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        result_pre = []
        result_in = []
        result_bac = []
        def recursion(root):
            # 如果遍历到一个分支的底了,则为空节点,返回True,继续遍历
            if root == None:
                return
            # 前序遍历
            result_pre.append(root.val)
            recursion(root.left)
            # 中序遍历
            result_in.append(root.val)
            recursion(root.right)
            # 后序遍历
            result_bac.append(root.val)
        recursion(root)
        print(result_pre)
        print(result_in)
        print(result_bac)

# 这里的层序遍历是dfs,深度优先遍历
class Solution:
    def levelOrder(self, root):
        levels = []
        # 如果为空节点,直接返回[]
        if not root:
            return levels
        def helper(node, level):
            # 如果相等了,说明是新加的层,则添一个[]
            if len(levels) == level:
                levels.append([])
            # 将节点存入相应的层
            levels[level].append(node.val)
            # 注意必须是先左后右,这样才能保证每层是按从左往右顺序存储的
            if node.left:
                helper(node.left, level + 1)
            if node.right:
                helper(node.right, level + 1)
        helper(root, 0)
        return levels

if __name__ == '__main__':
    duixiang = Solution()
    root = TreeNode(8)
    a = TreeNode(4)
    b = TreeNode(9)
    root.left = a
    root.right = b

    al = TreeNode(3)
    ar = TreeNode(6)
    a.left = al
    a.right = ar

    arl = TreeNode(5)
    arr = TreeNode(7)
    ar.left = arl
    ar.right = arr

    a = duixiang.levelOrder(root)
    print(a)
View Code

2 迭代遍历

中序和后序遍历比前序遍历思路一样,只不过多了对节点的记录,没有遍历过标记为1,等待遍历,遍历过的标记为0.

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
# 前序遍历的迭代法
class Solution:
    def preorder(self, root):
        res = []
        if root is None:
            return []
        stack = []
        stack.append(root)
        # 只有前序遍历可以这样写,因为前序遍历先存储中间的节点值,是中 左 右的顺序遍历
        # 而中序和后序遍历需要从最左边开始,而我们是从最上面的节点开始遍历的,所以需要记录节点是否被遍历过
        while stack:
            x = stack.pop()
            res.append(x.val)
            if x.right:
                stack.append(x.right)
            if x.left:
                stack.append(x.left)
        return res
# 层序遍历的迭代法
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        results = []
        stack_next = []
        if not root:
            return []
        stack_next.append(root)
        # stack_next用于记录下一层的节点,stack用于遍历当前层
        while stack_next:
            stack = stack_next
            # 记录节点前先清空
            stack_next = []
            res = []
            while stack:
                # 由于每一层都是从左往右依次保存,故这里用队列
                k = stack.pop(0)
                # 注意这里的顺序
                if k.left:
                    stack_next.append(k.left)
                if k.right:
                    stack_next.append(k.right)
                res.append(k.val)
            # 下次循环res被赋值为空了,为新的引用,故不用深拷贝也行
            results.append(res)
        return results
# 中序后序遍历的迭代法
class Solution:
    def levelOrder(self, root):
        res = []
        stack = []
        stack.append((root,1))
        while stack:
            x,sign = stack.pop()
            if x is None:
                continue
            # 这里用0标记被遍历过了,1表示没有遍历,如遍历过了则存储
            # 否则继续遍历,一直朝左找到底
            if sign:
                # 中序遍历
                stack.append((x.right, 1))
                stack.append((x, 0))
                stack.append((x.left,  1))
                ## 后序遍历
                # stack.append((x, 0))
                # stack.append((x.right, 1))
                # stack.append((x.left,  1))
            else:
                res.append(x.val)
        return res
if __name__ == '__main__':
    duixiang = Solution()
    root = TreeNode(8)
    a = TreeNode(4)
    b = TreeNode(9)
    root.left = a
    root.right = b

    al = TreeNode(3)
    ar = TreeNode(6)
    a.left = al
    a.right = ar

    arl = TreeNode(5)
    arr = TreeNode(7)
    ar.left = arl
    ar.right = arr

    a = duixiang.levelOrder(root)
    print(a)
View Code
12-26 01:53
查看更多