zl程序教程

您现在的位置是:首页 >  Python

当前栏目

二叉树的后一个节点(python来解答)

2023-02-18 16:34:00 时间

一个喜欢记录自己学习成长的小博主?️‍♂️?️‍♂️?️‍♂️

文章目录


前言


一、题目重述

这是一道acwing上面的中等题目。 题目的主要目的:

  1. 帮助我们巩固二叉树的左孩子,右孩子,父节点之间的关系。?
  2. 学会熟练使用while循环语句和循环结束的条件?
  3. 提高独立编写简单程序的能力,抵抗wrong answer的能力?

现在我们需要做的:

  1. 我们得给这个空白的方法体加上独创的python代码?‍?
  2. 函数参数是一个节点,但是节点的左右孩子,父节点都是知道的,所以一个节点并不影响我们解决问题。我们只需要完美的拿捏这个节点。通过一连串的使用节点的属性成员,运用迭代的方法,最后你突围成功了?‍♂️
  3. 开始调试,经过一段时间的wr,re之后最后AC?

小李跟蓝桥杯之间的唠嗑: 我:”个人感觉题目不是很难”。 蓝桥杯:“谁说不难,一天才ac一道题目,你能拿国一了吗?” 我:“这就去ac个100道”

二、解题思路

1.右孩子存在

右孩子存在的话,我们直接找到右边的最左边的一个那个节点的值。

图例演示:

中序遍历得到数组:4251637 显然1的后面一个元素是6,3的后面的一个元素是:7。

中序遍历后得到的数组:42516387 3的后面第一个元素是:8

 if q.right != None:
            tmp = q.right       #向右找到后一个元素
            while tmp.left != None:
                tmp = tmp.left
            return tmp

2.右孩子不在

右孩子不在的话,我们要找到后面的元素肯定是该节点的父节点或者父节点的父节点,甚至再往上走。 为什么呢: 因为中序遍历的遍历要求是: 规则是:左中右 原理:该节点总可以找到另外一个节点使得,该节点是另外一个节点的左子树上的的节点。但是也存在着例外,也就是它是最最最最右边的节点的时候,我们也无能为力,只能将空节点送给答案了 原理解释:相当于左中右(左中右,左中右…)一定可以找到最右边的一个节点的后一个元素就是这一小块“二叉树”的根节点

图例演示:

中序遍历后得到的数组:42516387 8的后面的一个元素是:7

中序遍历得到的数组是:425916387 9的后面的一个元素是:1

循环终止的条件:

  • 当我们找到一个节点的父节点是一个空的时候
  • 或者找到一个父节点的左孩子正好是现在的这个节点,那么该节点的父节点就是要找到的后面第一个元素
elif q.right == None:
            tmp = q.father      #找到父节点
            if tmp != None:     #向上找到后一个元素
                if tmp.left == q:
                    return tmp
                while tmp.father != None and tmp != tmp.father.left:    #退出循环的条件有两个,一个是找到根节点都没有后面的元素
                                                                        #一个是找到了后面的一个元素
                    tmp = tmp.father
                if tmp.father != None:
                    return tmp.father
                elif tmp == None:
                    return None
            elif tmp == None:
                return None

3.完整代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.father = None
class Solution(object):
    def inorderSuccessor(self, q):
        """
        :type q: TreeNode
        :rtype: TreeNode
        """
        if q.right != None:
            tmp = q.right       #向右找到后一个元素
            while tmp.left != None:
                tmp = tmp.left
            return tmp
        elif q.right == None:
            tmp = q.father      #找到父节点
            if tmp != None:     #向上找到后一个元素
                if tmp.left == q:
                    return tmp
                while tmp.father != None and tmp != tmp.father.left:    #退出循环的条件有两个,一个是找到根节点都没有后面的元素
                                                                        #一个是找到了后面的一个元素
                    tmp = tmp.father
                if tmp.father != None:
                    return tmp.father
                elif tmp == None:
                    return None
            elif tmp == None:
                return None

总结

本文从二叉树的简单定义出发,简单描述了二叉树的左孩子,右孩子,双亲节点之间的关系,再进一步运用分类的思想,将指定的节点分成两类,分别设计不同的算法来处理从而可以快速找到指定的节点的后面的一个元素。

文末小彩蛋:

这是我的半全代码写的,一些数据没有通过

if q.right != None:
            tmp = q.right       #向右找到后一个元素
            while tmp.left != None:
                tmp = tmp.left
            return tmp
        elif q.right == None:
            tmp = q.father      #找到父节点
            if tmp != None:     #向上找到后一个元素
          
                while tmp.father != None and tmp != tmp.father.left:    #退出循环的条件有两个,一个是找到根节点都没有后面的元素
                                                                        #一个是找到了后面的一个元素
                    tmp = tmp.father
                if tmp.father != None:
                    return tmp.father
                elif tmp == None:
                    return None
            elif tmp == None:
                return None

接下来,我把这个二叉树给画出来了。没想到还得让我画上两遍,,,因为第一遍的时候发现,越到后面的时候,二叉树节点之间的距离会越来越近。

画出二叉树的图形之后,我终于知道我错在哪了。于是加上了这行代码

  if q.right != None:
            tmp = q.right       #向右找到后一个元素
            while tmp.left != None:
                tmp = tmp.left
            return tmp
        elif q.right == None:
            tmp = q.father      #找到父节点
            if tmp != None:     #向上找到后一个元素
                if tmp.left == q:
                    return tmp
                while tmp.father != None and tmp != tmp.father.left:    #退出循环的条件有两个,一个是找到根节点都没有后面的元素
                                                                        #一个是找到了后面的一个元素
                    tmp = tmp.father
                if tmp.father != None:
                    return tmp.father
                elif tmp == None:
                    return None
            elif tmp == None:
                return None