常见二叉树

  • 1.满二叉树
    满二叉树最大的特点: 假设深度是h,那么总节点就是2^h-1
  • 2.完全二叉树
  • 3.二叉搜索树
    二叉搜索树BST,对于树的每个节点,其左子树的每个节点都小于这个值,右子树的每个几点都大于这个节点值:左下右大

二叉树的实现方式

class TreeNode:
    def __init__(self,x,left,right)
        self.value = x
        self.left = Node
        self.right= Node

root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)

二叉树的递归遍历[DFS]


class TreeNode:
    def __init__(self,x,left,right)
        self.value = x
        self.left = Node
        self.right= Node

# 二叉树的遍历框架(DFS)
def traverse(root:TreeNode):
    if root is Node:
        return 
    # 前序位置
    traverse(root.left)
    # 中序位置
    traverse(root.right)
    # 后续位置

二叉树的层序遍历[BFS]

BFS写法1


from binaryTree.node import TreeNode

"""
  二叉树的层序遍历,又称之为BFS
"""

class Solution:
    def bfs(self, root):
        if not root:
            return []
        result = []
        queue = [root]
        while queue:
            level_values = []
            level_size = len(queue)
            for i in range(level_size):
                node = queue.pop(0)
                level_values.append(node.value)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            result.append(level_values)
        return result


if __name__ == '__main__':
    root = TreeNode(1)
    root.left = TreeNode(2)
    root.right = TreeNode(3)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(5)
    root.right.left = TreeNode(6)
    root.right.right = TreeNode(7)
    s = Solution()
    print(s.bfs(root))  # [[1], [2, 3], [4, 5, 6, 7]]

BFS写法2

def levelOrderTraverse(root):
    if root is None:
        return
    q = deque()
    q.append(root)
    while q:
        cur = q.popleft()
        # 访问 cur 节点
        print(cur.val)

        # 把 cur 的左右子节点加入队列
        if cur.left is not None:
            q.append(cur.left)
        if cur.right is not None:
            q.append(cur.right)

例题: 查找二叉树的最小深度

# 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 __init__(self):
        self.minDepthValue = 10000
        self.currentDepth = 0

    def minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        self.traverse(root)
        return self.minDepthValue

    def traverse(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        self.currentDepth += 1
        if root.left is None and root.right is None:
            self.minDepthValue = min(self.minDepthValue, self.currentDepth)
        self.traverse(root.left)
        self.traverse(root.right)
        self.currentDepth -= 1
        return self.minDepthValue

二叉树系列算法核心纲领

二叉树的解题思路

  • 是否可以通过遍历一遍二叉树得到答案?如果可以,用一个traverse函数函数陪外部变量实现,遍历的思维模式。
  • 是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值,分解问题的思维模式
    无论是哪种思维模式,都需要思考:
    如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做? 其他的节点不用操心,递归函数会在所有节点上执行相同的操作。

二叉树的重要性

比如,经典排序算法: 快速排序和归并排序,有什么理解?
快速排序就是个二叉树的前序遍历,归并排序就是二叉树的后序遍历

""""
   对于快速排序, 若在nums[lo..hi]排序,我们先找一个分界点p, 通过交换元素使得 nums[lo..p-1]都要小于等于nums[p],
   且nums[p+1..hi]都大于nums[p], 然后递归nums[lo..p-1]和nums[p+1..hi]中寻找新的分界点
"""
def sort(nums: list, lo: int, hi: int):
    if lo>= hi:
       return
    # ************************
    # 通过交换元素构建分界点 p
    p = partition(nums, lo, hi)
    sort(nums, lo, p-1)
    sort(nums, p+1, hi)


def partition(arr, low, high):
    i = (low - 1) 
    pivot = arr[high]  

    for j in range(low, high):
        if arr[j] <= pivot:
            i = i + 1
            arr[i], arr[j] = arr[j], arr[i]
    arr[i + 1], arr[high] = arr[high], arr[i + 1]
    return (i + 1)
  • 归并排序
def sort(nums: List[int], lo: int, hi: int) -> None:
    # 定义:排序 nums[lo..hi]
    mid = (lo + hi) // 2
    # 排序 nums[lo..mid]
    sort(nums, lo, mid)
    # 排序 nums[mid+1..hi]
    sort(nums, mid + 1, hi)

    # ****** 后序位置 ******
    # 合并 nums[lo..mid] 和 nums[mid+1..hi]
    merge(nums, lo, mid, hi)
    # *********************

__END__