【编程算法】JZ8 二叉树的下一个结点(Python解法)

题目描述

给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示

示例:

输入:{8,6,10,5,7,9,11},8

返回:9

解析:这个组装传入的子树根节点,其实就是整颗树,中序遍历{5,6,7,8,9,10,11},根节点8的下一个节点就是9,应该返回{9,10,11},后台只打印子树的下一个节点,所以只会打印9,如下图,其实都有指向左右孩子的指针,还有指向父节点的指针,下图没有画出来

解题

非专业选手(从一个小白的角度)来作答,钻研该题花了蛮长时间,希望把我的收获和大家分享一下~

1.前言

在解题之前,有几个必须明白的点:

(1)掌握关于二叉树的基础知识,才能明白做题的步骤及逻辑,了解中序遍历的遍历方式(先访问左子树,然后根节点,最后遍历右子树),最好是在大脑中一个形象推理的过程;基础知识链接:二叉树基础知识

(2)适应牛客的网页自测IDE,一是pycharm等IDE可能不支持二叉树的操作,而且配置环境花费的时间不少;二是提前适应企业笔试;既然我们的目的是刷题和明白算法的逻辑,也就没必要纠结为什么无法在pycharm等IDE实现,而且网页自测IDE往往都把参数配置好了,直接写算法逻辑就行。

(3)本题解题的几个关键点:

pNote:也就是p结点的意思,这是本题的最重要的参数,一切的操作从它开始

pNote.right:p结点的右子结点(也有称右孩子点),也就意味着p结点存在右子树

pNote.left:p结点的左子结点,也就意味着p结点存在左子树

pNote.next:p结点的父结点,为方便理解,大家可参考标记好的下图

 以上多个参数(maybe二叉树算法的表现形式)是解本题的关键

最后加上while函数

解该题的时候才认识到while函数的强大!!

可能有点绕,但这是本文最最要的逻辑,这也是本题最大的收获

假如pNote的左结点一直存在:第一次循环判定pNote的左结点存在,pNote指代pNote的左结点,然后进行第二次循环,这次是对重新定义后的pNote(pNote.left)进行判定存在,然后依次循环,直至该结点最左的子节点。

如果这儿不是很明白,可以跳过,代码部分学习时再回头看这。

2.解题代码

解该题主要为两个步骤:

(1)如果该结点的右子树不为空,那么下个结点就是右子树里最左边的结点

因为中序遍历的逻辑是左中右,如果该结点(也就是p结点)存在右子树(也就是存在右子结点),那么遍历的下一位就到该结点的右子树上了,假如右子树没有左结点,那么答案就是它;假如有左结点,那么优先是右子树的左结点....依次循环

(2)如果该结点的右子树为空,往上找,找到的祖先结点是该祖先结点父结点的左结点!!!

第二步是往父结点方向找,因为中序遍历,该结点的父结点已经遍历过了,因此要找父结点的父结点,而且最终的父结点必须是他所在树的左结点,这个其实不难理解,只有最终的父结点是所在树的左结点,遍历才能继续下去(左中右),答案就是最终的父结点。

# -*- coding:utf-8 -*-
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None
class Solution:
    def GetNext(self, pNode):
        # write code here
        #1.如果该结点的右子树不为空,那么下个结点就是右子树里最左边的结点
        #2.如果该结点的右子树为空,往上找,找到的祖先结点是该祖先结点父结点的左结点!!!
        if pNode.right:
            tempnode = pNode.right
            while tempnode.left: #循环判定右子树的左结点!!!妙啊
                tempnode = tempnode.left
            return tempnode  #若该结点右子树的各个左结点不存在,返回该结点的右结点
        else:
            while pNode.next: 
                parent = pNode.next
                if parent.left == pNode:
                    return parent
                pNode = pNode.next #若非左结点,继续循环
        return None


总结

大家如果有疑问都可以评论提出,有不足之处请大家批评指正,希望能多结识这方面的朋友,共同学习、共同进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值