【Python 百练成钢】二叉树合集:关于二叉树的夺命连环问,你能抗住几问?

简介: 【Python 百练成钢】二叉树合集:关于二叉树的夺命连环问,你能抗住几问?

👾前言👾


二叉树是数据结构中一个非常重要的数据结构,他以节点之间凌乱的关系与图在数据结构中称霸一方。

掌握了树你就掌握了数据结构的左膀右臂。

那么问题来了:

如何创建二叉树呢?

如何搜索二叉树中的节点呢?

如何计算二叉树的最大深度?

如何判断平衡二叉树?

如何判断对称二叉树?

如何重建二叉树?

你也许一头雾水,你也许脑子中很快有了思路。

不妨先看一看如下几个练习题以巩固你对二叉树知识的掌握情况。

哦!二叉树好像还可以线索化,线索化是什么?如何线索化?

本章咱就不谈线索化了,感兴趣的小伙伴可以自己尝试一下。

或者在未来的不久,咱就出一期关于二叉树线索化的文章呢。

tips:大家一定要弄清二叉树的基本结构之后再来写下面几道题呀。

接下来咱们一块以学辅练,以练固学。迎接来自二叉树的冲击吧。


花非花树非树💦,希望对大家有帮助!


972aed534bf64f1b90ba38588605108b.jpg


🍁前置知识🍁


树天生就是一种递归结构,所以使用递归的方法会使他的问题得到大大的简化。

二叉树是树的一个重要分支,二叉树中节点的子节点个数不超过2个(并且有顺序左、右)

前置知识呢就说这么多。其他的相信大家都已经会了。🤡


🤺练习题🤺


🌺二叉树的遍历🌺


💗问题描述💗


二叉树总共有四种遍历方式:


  • 前序遍历:先遍历根节点然后遍历左子树、右子树
  • 中序遍历:先遍历左子树在遍历根节点最后遍历右子树
  • 后序遍历:先遍历左子树然后右子树最后根节点
  • 层序遍历:使用队列一层一层向下遍历


💗问题分析💗


一般我们对树进行递归遍历,操作方式如下


💗代码实现💗


class myTree:
    def __init__(self,data):
        self.data=data
        self.left=None
        self.right=None
    def setLeft(self,p):
        self.left=p
    def setRight(self,p):
        self.right=p
    def getLeft(self):
        return self.left
    def getRight(self):
        return self.right
    def setData(self,data):
        self.data=data
    def getData(self):
        return self.data
def creatTree(mytree):
    n=input("请输入该节点左子树数据(如果没有数据输入-1):")
    if n=='-1':
        return
    mytree.left=myTree(int(n)) 
    creatTree(mytree.left)
    n=input("请输入该节点右子树数据(如果没有数据输入-1):")
    if n=='-1':
        return
    mytree.right=myTree(int(n)) 
    creatTree(mytree.right)
def lookTree1(mytree):
    if mytree!=None:
        print(mytree.data,end="") 
        lookTree1(mytree.left)
        lookTree1(mytree.right)
    else:
        return 
def lookTree2(mytree):
    if mytree!=None:
        lookTree2(mytree.left)
        print(mytree.data,end="") 
        lookTree2(mytree.right)
    else:
        return 
def lookTree3(mytree):
    if mytree!=None:
        lookTree3(mytree.left)
        lookTree3(mytree.right)
        print(mytree.data,end="") 
    else:
        return 
# 根节点
mTree=myTree(0)
# 建树
creatTree(mTree)
# 前序遍历
print("前序遍历:",end="")
lookTree1(mTree)
print()
# 中序遍历
print("中序遍历:",end="")
lookTree2(mTree)
print()
# 后续遍历
print("后续遍历:",end="")
lookTree3(mTree)
print()


🌺二叉树的最大深度🌺



💗问题描述💗


力扣104题

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],


5ca3525fed0f46818092339694adb76b.png


返回它的最大深度 3 。


💗问题分析💗


返回他最大深度的话咱们先思考以下几个问题:

  • 父子节点之间深度有什么关系
  • 两个子树深度不同应该如何选择

思考完这两个问题咱们看代码实现


💗代码实现💗


class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if root==None:
            return 0
        return max(self.maxDepth(root.left),self.maxDepth(root.right))+1


🌺对称二叉树🌺



💗问题描述💗


给你一个二叉树的根节点 root , 检查它是否轴对称。

输入:root = [1,2,2,3,4,4,3]

输出:true

输入:root = [1,2,2,null,3,null,3]

输出:false


💗问题分析💗


判断树是否哦对称,咱们应该判断对应位置的数据是否相同

我们首先想到的就是使用队列,因为只有队列才能保证访问节点的顺序

入队的时候应该先进行判断,如果有一个对应位置的节点为空一个不为空则肯定不对称

两个位置都为空的时候不用处理,然后将子节点成对放入队列中。每次循环取出一对节点进行判断

每次判断完将其左右子节点分别对应放入队列中。不对称就返回false,在筛选过程中只要有一个

false那么最终的结果就是false,类似于树的层序遍历。


💗代码实现💗


class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if root==None or root.left==None and root.right==None:
            return True
        ls=[]
        ls.append(root.left)
        ls.append(root.right)
        while ls:
            t1=ls.pop()
            t2=ls.pop()
            if t1 and t2 and t1.val==t2.val:
                if t1.left==None and t2.right!=None or t1.left!=None and t2.right==None:
                    return False
                if t2.left!=None and t1.right==None or t2.left==None and t1.right!=None:
                    return False
                if t1.left!=None and t2.right!=None:
                    ls.append(t1.left)
                    ls.append(t2.right)
                if t1.right!=None and t2.left!=None:
                    ls.append(t2.left)
                    ls.append(t1.right)
            else:
                return False
        return True


🌺平衡二叉树🌺


💗问题描述💗


题目110

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

输入:root = [3,9,20,null,null,15,7]

输出:true

输入:root = [1,2,2,3,3,null,null,4,4]

输出:false

输入:root = []

输出:true


💗问题分析💗


判断是否平衡,就需要判断左子树右子树的深度,在第二个小练习中已经知道了怎么求二叉树的深度,所以我们可以进行求解左右子树的深度然后加以判断,将得到的深度进行返回,每次返回的还是最大深度

如果左右子树深度相差大于1,就返回-1,并加入判定条件如果某节点返回-1,那么接下来的返回结果均为-1

在第一次调用函数的地方进行判断返回值是不是-1得到结果。

下面给了两个解题方法:

第一个比较浪费空间时间不推荐使用,思想是每次判断该节点的左右子树深度是否符合规范,然后将判断的结果返回到上一层

第二个直接进行递归判断(只需要递归一次,判断是否符合要求即可。)


💗代码实现💗


# 先计算树的深度再计算左右子树的差值
# 重复进行了很多次计算
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if root==None:
            return True
        def maxdep(root):
            if root==None:
                return 0
            return max(maxdep(root.left),maxdep(root.right))+1
        return abs(maxdep(root.left)-maxdep(root.right))<=1 and self.isBalanced(root.left) and self.isBalanced(root.right)
#直接计算树是不是平衡二叉树
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if root==None:
            return True
        def maxdep(root):
            if root==None:
                return 0
            left=maxdep(root.left)
            right=maxdep(root.right)
            if left==-1 or right==-1:
                return -1
            if abs(left-right)>1:
                return -1
            return max(left,right)+1
        return maxdep(root)!=-1


🌺重建二叉树🌺



💗问题描述💗


给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历,

inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

输出: [3,9,20,null,null,15,7]

输入: preorder = [-1], inorder = [-1]

输出: [-1]


💗问题分析💗


二叉树有许多性质,如果给出他的前序遍历与中序遍历,那么可以建出这个树,并且得到后续遍历

给出后续遍历与中序遍历也是如此

利用的思想就是,前序遍历第一个顶点肯定是根节点

然后接下来一段是左子树,然后是右子树

中序遍历中左子树在根节点左边,右子树在其右边。

根据这个关系我们可以写出以下递归。


💗代码实现💗


# 树体结构
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
# 后序遍历
def pTree(root):
    if root.left!=None:
        pTree(root.left)
    if root.right!=None:
        pTree(root.right)
    print(root.val,end="")
# 重建二叉树
def buildTree(preorder: list[int], inorder: list[int]) -> TreeNode:
    if not preorder and not inorder:
        return None
    root=TreeNode()
    root.val=preorder[0]
    t=inorder.index(preorder[0])
    root.left=buildTree(preorder[1:t+1],inorder[:t])
    root.right=buildTree(preorder[t+1:],inorder[t+1:])
    return root
pTree(buildTree([3,9,20,15,7],[9,3,15,20,7]))



目录
相关文章
|
7月前
|
存储 算法 Python
python算法(三)——树、二叉树、AVL树
python算法(三)——树、二叉树、AVL树
36 0
|
7月前
|
算法 Python
Python算法——二叉树遍历
Python算法——二叉树遍历
88 0
|
13天前
|
机器学习/深度学习 Python 算法
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
|
18天前
|
C++ Python Java
Java每日一练(20230501) 路径交叉、环形链表、被围绕的区域
Java每日一练(20230501) 路径交叉、环形链表、被围绕的区域
40 0
Java每日一练(20230501) 路径交叉、环形链表、被围绕的区域
|
13天前
|
关系型数据库 测试技术 Python
2024年最新【Python 百练成钢】快速上手并查集(2),Python面试简历模板
2024年最新【Python 百练成钢】快速上手并查集(2),Python面试简历模板
|
16天前
|
Python
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交
|
16天前
|
存储 算法 Python
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交(2)
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交(2)
|
16天前
|
存储 算法 Python
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交(1)
【Python 百练成钢】高精度加法、阶乘计算、矩阵幂运算、矩阵面积交(1)
|
18天前
|
Python
使用python写一个二叉树
使用python写一个二叉树
28 1
|
18天前
|
Python 人工智能
讯飞星火、文心一言和通义千问同时编“贪吃蛇”游戏,谁会胜出?
讯飞星火、文心一言和通义千问同时编“贪吃蛇”游戏,谁会胜出?
55 1
讯飞星火、文心一言和通义千问同时编“贪吃蛇”游戏,谁会胜出?