代码随想录算法训练营第十三天

1 二叉树的理论基础

文章链接:代码随想录

视频链接:关于二叉树,你该了解这些!| 二叉树理论基础一网打尽,二叉树的种类、二叉树的存储方式、二叉树节点定义、二叉树的遍历顺序_哔哩哔哩_bilibili

1.1 二叉树的种类

  1. 满二叉树

所有节点处的值都排满了,没有空的

  1. 完全二叉树

只有在最后一层的时候,从左至右是顺序存储,且空的位置只能在右边,左边不能有空的

  1. 二叉搜索树

这种就是满足左边数值中满足所有数值都小于根节点数,右边的数值满足所有数值都大于根节点数

  1. 平衡二叉搜索树

满足二叉搜索树的基本要求后,其左右节点的高度差不超过1

1.2 二叉树的存储方式

链式存储和顺序存储

  1. 链式存储

这种方式就是相当于之前学的链表一样,每一个值拥有左指针和右指针,最后一层的左右指针指向空位置即可

  1. 顺序存储

就相当于数组的存储,先存储父节点,然后在存储子节点,一步一步下来

1.3 二叉树的遍历方式

深度遍历和广度遍历

  1. 深度遍历

这种是先向下遍历;这个分为三种:前序遍历,中序遍历和后续遍历;前序遍历是中左右,中序遍历是左中右,后续遍历是左右中;这个前后的顺序其实是指中节点在哪个位置

  1. 广度遍历

这种方式就是横着遍历的,就可以使用了

1.4 二叉树的定义方式

这个定义就是需要定义一个值,和左右节点,即指针即可

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

2 二叉树的递归遍历

文章链接:代码随想录

视频链接:每次写递归都要靠直觉? 这次带你学透二叉树的递归遍历!| LeetCode:144.前序遍历,145.后序遍历,94.中序遍历_哔哩哔哩_bilibili

自己的思路:害,这种题真的就是,一看就会,一做就废

2.1 递归算法的三部曲

  1. 确定递归函数的参数和返回值
  2. 确定终止条件
  3. 确定单层递归的逻辑

2.2 递归的三道题

每次添加的值都是中序的值,其他的就向下遍历

思考:为什么不是左的值和右的值?

因为左和右的值她的下面还有下一层值,无限循环,,,

2.2.1 前序遍历

题目链接:144. 二叉树的前序遍历 - 力扣(LeetCode)

前序的顺序是中左右,所以先添加中序的值,遇到左右继续遍历

# 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: Optional[TreeNode]) -> List[int]:
        result = []
        def res(node):
            if node == None:
                return
            result.append(node.val)
            res(node.left)
            res(node.right)
        res(root)
        return result
2.2.2 中序遍历

题目链接:94. 二叉树的中序遍历 - 力扣(LeetCode)

中序遍历是左中右的顺序,按照这个往下写就行

# 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: Optional[TreeNode]) -> List[int]:
        result = []
        def dfs(node):
            if node == None:
                return
            dfs(node.left)
            result.append(node.val)
            dfs(node.right)
        dfs(root)
        return result
2.2.3 后序遍历

题目链接:145. 二叉树的后序遍历 - 力扣(LeetCode)

后序遍历过程中,其内部的结构为左右中

# 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: Optional[TreeNode]) -> List[int]:
        result = []
        def dfs(node):
            if node == None:
                return
            dfs(node.left)
            dfs(node.right)
            result.append(node.val)
        dfs(root)
        return result

2.3 本题小结

  1. 从这道题来理解的话,会发现递归不难,但是自己去写逻辑还是有转不过来的时候
  2. 主要就是函数调用的时候会很吃力,不知道为什么

3 二叉树的层序遍历思路

文章链接:代码随想录

视频链接:讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历_哔哩哔哩_bilibili

3.1 层序遍历的解题思路

  1. 首先判断整个结尾有没有空,空的话就返回一个空列表
  2. 对其进行层序遍历,首先是将其值全部存储到队列中,然后一个个弹出,增加现在的位置的值,最终进行值返回

3.2 leetcode102.二叉树的层序遍历

题目链接:102. 二叉树的层序遍历 - 力扣(LeetCode)

3.2.1 队列的方法
import collections
# 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: Optional[TreeNode]) -> List[List[int]]:
        if root == None:
            return []
        queue = collections.deque([root])
        result =[]
        while queue:
            level =[]
            for _ in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            result.append(level)
        return result
3.2.2 递归的方法
import collections
# 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: Optional[TreeNode]) -> List[List[int]]:
        if root == None:
            return []
        result =[]
        
        def dfs(node,level):
            if node ==None:
                return
            if len(result)==level:
                result.append([])
            result[level].append(node.val)
            dfs(node.left,level+1)
            dfs(node.right,level+1)
        dfs(root,0)
        return result

3.3 leetcode 107二叉树的层序遍历 II

题目链接:107. 二叉树的层序遍历 II - 力扣(LeetCode)

3.2.1 队列的方法

其实将上一道题进行一个倒序就好了

import collections
# 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 levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root == None:
            return []
        queue = collections.deque([root])
        result = []
        while queue:
            level = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            result.append(level)
        return result[::-1]
3.2.2 递归的方法
import collections
# 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 levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root == None:
            return []
        
        result = []
        def dfs(node,level):
            if node == None:
                return
            if len(result) == level:
                result.append([])
            result[level].append(node.val)
            dfs(node.left,level+1)
            dfs(node.right,level+1)
        dfs(root,0)
        return result[::-1]

4 今日小结

  1. 怎么说呢,感觉今天的题,学起来很容易,就是一学就会,但是一做就废
  2. 内容上理解挺容易的,但是感觉因为队列掌握不是很好,其实做就没这么容易了
posted @ 2024-10-30 13:01  小方呀0524  阅读(6)  评论(0编辑  收藏  举报