近期诸事繁冗,未延续每日刷题的习惯,再打开博客已是半月之久了。学习还是需要持之以恒,罗胖说,成就=核心算法*每天重复的平方。当然,学习还是要从兴趣出发,在上下求索中不算优化,设置好学习率,切莫下山太快,也切莫下山太慢,愿诸君都能经过反复迭代,达到全局最优点。
本题为剑指offer第8题:
题目描述:
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
解析:
本题重点是获得“中序遍历”的下一个节点。
前置知识补充:中序遍历顺序为:左子树、根节点、右子树。
二叉树中不同位置的节点的下一个节点,或多或少都有不同的情况,下面一一来统计说明:
首先先构造一个测试样本二叉树,以便分析:
i) 如果传入一个空节点,则下一个节点为空,需要捕捉此类异常现象,保证函数的健壮行。
ii) 下一个节点是右子树的最左子节点的节点有:a、b、c、e
iii) 下一个节点是其父节点的有:d、f、h
iv) 根节点左子树的最右子节点的下一个节点应该是整棵树的根节点,如i
v) 还有一个特殊情况,遍历的最后一个节点g,下一个节点就是none
根据a-i这9个节点,已经把中序遍历的下一个节点的情况全部囊括了。下面来找一下它们的规律:
1. 传入空节点的情况可以作为健壮性处理,用于函数的入口。
2. 上述ii情况,如果当前的节点有有子树,那么它的下一个就在有子树的最左子节点中。
3. 上述iii情况,如果当前节点的父亲节点不为空,并且其父节点的左子节点正是这个节点,那么该节点的下一个节点正是它的父节点。
4. 上述iv情况,如果当前节点的父亲节点不为空,并且当前节点不是其父节点的左子节点(即当前节点为其父节点的右子节点),此时需要再向上一层验证,也就是当前节点的爷爷节点。这个验证需要和第3种情况结合来看,详情请看代码。简单的说一下,如果当前节点的爸爸节点是爷爷节点的左子节点,那么爷爷节点就是当前节点的下一个节点。如果不是,就再继续往上找,依次重复前面的验证条件,直到找到祖先根节点,即根节点的父亲节点为空,则下一个节点就是根节点。如i的下一个节点就是a。
5. 上述v情况,就是对4的完善,如果实在找不到,那就是none。
下面看代码:
# -*- 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
if(pNode == None):
return None
if(pNode.right != None):
res = pNode.right
while res.left:
res = res.left
return res
while pNode.next:
if(pNode.next.left == pNode):
return pNode.next
pNode = pNode.next
return None
举一反三:输出前序遍历和后续遍历的下一个节点,未完待续……