代码随想录算法训练营第12天 | Python | 二叉树的前序遍历、中序遍历、后序遍历、层序遍历

二叉树理论基础

链接:https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

种类

  1. 满二叉树:满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。请添加图片描述
  2. 完全二叉树:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。
    请添加图片描述
  3. 二叉搜索树:有序数,左孩子<根节点<右孩子
    请添加图片描述
  4. 平衡二叉搜索树/AVL(Adelson-Velsky and Landis)树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。请添加图片描述

遍历方式

  1. 深度优先遍历

前序遍历:中左右

在每个节点前面画点,先碰到点的数字先输出

请添加图片描述
中序遍历:左中右

在每个节点底下画点,先碰到点的数字先输出
请添加图片描述
后序遍历:左右中

在每个节点后面画点,先碰到点的数字先输出
请添加图片描述
2. 广度优先遍历

层序遍历:一层一层输出

5, 4, 6, 1, 2, 7, 8

定义

class TreeNode:
    def __init__(self, val, left = None, right = None):
        self.val = val
        self.left = left
        self.right = right

二叉树的递归遍历

LeetCode 144. 二叉树的前序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        def dfs(root):
            if root:
                res.append(root.val)
                dfs(root.left)
                dfs(root.right)
        dfs(root)
        return res

LeetCode 94. 二叉树的中序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        def dfs(root):
            if root:
                dfs(root.left)
                res.append(root.val)
                dfs(root.right)
        dfs(root)
        return res

LeetCode 145. 二叉树的后序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        def dfs(root):
            if root:
                dfs(root.left)
                dfs(root.right)
                res.append(root.val)
        dfs(root)
        return res

二叉树的迭代遍历

使用栈结构:深度遍历需要先按一个方向遍历到底,其他方向的信息暂时压入栈,之后再取出。

不可以用队列:不满足其他方向信息暂存,因为先压入的信息一定会先出。

LeetCode 144. 二叉树的前序遍历

前序遍历:中左右

把右孩子压入栈 -> 左孩子压入栈(这样可以先出左孩子,再出右孩子) -> 出栈记录val

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return 
        stack = [root]
        res = []
        while stack:
            node = stack.pop()
            res.append(node.val)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return res

LeetCode 94. 二叉树的中序遍历

中序遍历:左中右

【比较难】

把自己和左孩子压入栈 -> 直到没有左孩子,开始pop,并压入右孩子

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return
        stack = []
        res = []
        node = root
        while stack or node:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            res.append(node.val)
            node = node.right
        return res

LeetCode 145. 二叉树的后序遍历

在这里插入图片描述
[1,2,4,6,5] -> [1,2,4,6,5] -> [5,6,4,2,1]

前序遍历先压入左孩子,后压入右孩子 -> res[::-1]

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

二叉树的统一迭代遍历

在压入自己时加入标记符null,遇到null则直接输出自己

LeetCode 144. 二叉树的前序遍历

前序遍历:中左右
压入顺序:右左中

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return
        stack = [root]
        res = []
        while stack:
            node = stack.pop()
            if not node:
                node = stack.pop()
                res.append(node.val)
            elif node.left or node.right:
                if node.right:
                    stack.append(node.right)
                if node.left:
                    stack.append(node.left)
                stack.append(node)
                stack.append(None)
            else:
                res.append(node.val)
        return res

LeetCode 94. 二叉树的中序遍历

中序遍历:左中右
压入顺序:右中左

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return
        stack = [root]
        res = []
        while stack:
            node = stack.pop()
            if not node:
                node = stack.pop()
                res.append(node.val)
            elif node.left or node.right:
                if node.right:
                    stack.append(node.right)
                stack.append(node)
                stack.append(None)
                if node.left:
                    stack.append(node.left)
            else:
                res.append(node.val)
        return res

LeetCode 145. 二叉树的后序遍历

后序遍历:左右中
压入顺序:中右左

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return
        stack = [root]
        res = []
        while stack:
            node = stack.pop()
            if not node:
                node = stack.pop()
                res.append(node.val)
            elif node.left or node.right:
                stack.append(node)
                stack.append(None)
                if node.right:
                    stack.append(node.right)
                if node.left:
                    stack.append(node.left)
            else:
                res.append(node.val)
        return res

二叉树的层序遍历

LeetCode 102. 二叉树的层序遍历

用队列结构保存信息。

利用队列长度区分不同层:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:
            return 
        queue = collections.deque()
        queue.append(root)
        res = []
        while queue:
            level = []
            for _ in range(len(queue)):
                node = queue.popleft()
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(level)
        return res

迭代法,核心就是按顺序扩充每层:

def traverse(node, level):
	res[level].append(node.val)
	traverse(node.left, level + 1)
	traverse(node.right, level + 1)

再加上一些辅助条件,保证程序顺利运行:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:
            return
        res = []

        def traverse(node, level):
            if not node:
                return
            if len(res) == level:
                res.append([])
            
            res[level].append(node.val)
            traverse(node.left, level + 1)
            traverse(node.right, level + 1)

        traverse(root, 0)
        return res        

LeetCode 107. 二叉树的层序遍历 II

把res反转即可

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def levelOrderBottom(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:
            return
        queue = collections.deque()
        queue.append(root)
        res = []
        while queue:
            level = []
            for _ in range(len(queue)):
                node = queue.popleft()
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(level)
        return res[::-1]

LeetCode 199. 二叉树的右视图

只保留每层的最后一个数

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def rightSideView(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return
        queue = collections.deque()
        queue.append(root)
        right_view = []
        while queue:
            queue_len = len(queue)
            for i in range(queue_len):
                node = queue.popleft()
                if i == queue_len-1:
                    right_view.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return right_view

LeetCode 637. 二叉树的层平均值

每层求平均,注意level要写成0.0,默认float

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def averageOfLevels(self, root):
        """
        :type root: TreeNode
        :rtype: List[float]
        """
        if not root:
            return 
        queue = collections.deque()
        queue.append(root)
        res = []
        while queue:
            level = 0.0
            queue_len = len(queue)
            for _ in range(queue_len):
                node = queue.popleft()
                level += node.val
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(level/queue_len)
        return res

LeetCode 429. N 叉树的层序遍历

把孩子依次存入队列

"""
# Definition for a Node.
class Node(object):
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: Node
        :rtype: List[List[int]]
        """
        if not root:
            return 
        queue = collections.deque()
        queue.append(root)
        res = []
        while queue:
            level = []
            for _ in range(len(queue)):
                node = queue.popleft()
                level.append(node.val)
                for children in node.children:
                    queue.append(children)
            res.append(level)
        return res

LeetCode 515. 在每个树行中找最大值

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def largestValues(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return 
        queue = collections.deque()
        queue.append(root)
        res = []
        while queue:
            max_num = float('-inf')
            for _ in range(len(queue)):
                node = queue.popleft()
                max_num = max(max_num, node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(max_num)
        return res

LeetCode 116. 填充每个节点的下一个右侧节点指针

"""
# Definition for a Node.
class Node(object):
    def __init__(self, val=0, left=None, right=None, next=None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""

class Solution(object):
    def connect(self, root):
        """
        :type root: Node
        :rtype: Node
        """
        if not root:
            return 
        queue = collections.deque()
        queue.append(root)
        while queue:
            cur = None
            queue_len = len(queue)
            for i in range(queue_len):
                node = queue.popleft()
                if cur:
                    cur.next = node
                cur = node
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

LeetCode 117. 填充每个节点的下一个右侧节点指针 II

"""
# Definition for a Node.
class Node(object):
    def __init__(self, val=0, left=None, right=None, next=None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""

class Solution(object):
    def connect(self, root):
        """
        :type root: Node
        :rtype: Node
        """
        if not root:
            return 
        queue = collections.deque()
        queue.append(root)
        while queue:
            cur = None
            queue_len = len(queue)
            for i in range(queue_len):
                node = queue.popleft()
                if cur:
                    cur.next = node
                cur = node
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root
        

LeetCode 104. 二叉树的最大深度

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        queue = collections.deque()
        queue.append(root)
        depth = 0
        while queue:
            for _ in range(len(queue)):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            depth += 1
        return depth

LeetCode 111. 二叉树的最小深度

当左右孩子都为空时,说明遍历到最低点了

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        queue = collections.deque()
        queue.append(root)
        depth = 0
        while queue:
            depth += 1
            for _ in range(len(queue)):
                node = queue.popleft()
                if not node.left and not node.right:
                    return depth
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            
        return depth
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值