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

文章目录

  • 前言
  • 前置知识
  • 练习题
    • 二叉树的遍历
      • 问题描述
      • 问题分析
      • 代码实现
    • 二叉树的最大深度
      • 问题描述
      • 问题分析
      • 代码实现
    • 对称二叉树
      • 问题描述
      • 问题分析
      • 代码实现
    • 平衡二叉树
      • 问题描述
      • 问题分析
      • 代码实现
    • 重建二叉树
      • 问题描述
      • 问题分析
      • 代码实现

前言

二叉树是数据结构中一个非常重要的数据结构,他以节点之间凌乱的关系与图在数据结构中称霸一方。
掌握了树你就掌握了数据结构的左膀右臂。
那么问题来了:
如何创建二叉树呢?
如何搜索二叉树中的节点呢?
如何计算二叉树的最大深度?
如何判断平衡二叉树?
如何判断对称二叉树?
如何重建二叉树?
你也许一头雾水,你也许脑子中很快有了思路。
不妨先看一看如下几个练习题以巩固你对二叉树知识的掌握情况。
哦!二叉树好像还可以线索化,线索化是什么?如何线索化?
本章咱就不谈线索化了,感兴趣的小伙伴可以自己尝试一下。
或者在未来的不久,咱就出一期关于二叉树线索化的文章呢。
tips:大家一定要弄清二叉树的基本结构之后再来写下面几道题呀。
接下来咱们一块以学辅练,以练固学。迎接来自二叉树的冲击吧。

花非花树非树,希望对大家有帮助!【Python 百练成钢】二叉树合集:关于二叉树的夺命连环问,你能抗住几问?_第1张图片

前置知识

树天生就是一种递归结构,所以使用递归的方法会使他的问题得到大大的简化。
二叉树是树的一个重要分支,二叉树中节点的子节点个数不超过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],
【Python 百练成钢】二叉树合集:关于二叉树的夺命连环问,你能抗住几问?_第2张图片
返回它的最大深度 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]))

你可能感兴趣的:(Python从入门到精通,数据结构与算法,python,有关二叉树的练习题,遍历二叉树,数据结构与算法)