找出 二叉树的下一个节点?
这是一道来自于 《剑指 Offer》 的题目,题目信息:
给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示。
起初第一眼看到这道题,感觉不就是中序遍历下整棵树,然后就能找到了嘛,诶呀,轻轻松松~
但是呢,事情发生了微妙的转变,是因为根本就不知道树的根节点,没法遍历,啊~
import java.util.*; |
那这就只能根据中序遍历的特点来做题了啊。
简单回顾下中序遍历:先递归访问左子树,再访问自身,再递归访问右子树。简单记为左中右。那么就可以考虑下使用到这个特性了。啊哈,坐好车,我们要出发了~
思考如下的一种情况:
如果一个节点有右子树,那么该节点的下一个节点就是它的右子树的最左子结点了。举个例子,上图中的节点b
的下一个节点是节点h
,节点a
的下一个节点是f
。
这种情况的代码实现:
// 情况一:pNode 右子树不为空,下一个节点即为右子树的最左节点 |
接着来思考:
如果一个节点没有右子树呢?如果该节点是其父节点的左子结点,那么它的下一个节点就是它的父节点了。举个例子,上图中的节点d
的下一个节点是节点b
,节点f
的下一个节点是节点c
。
那如果一个节点既没有右子树,并且它还是其父节点的右子节点呢?这种情形就比较复杂了,我们需要将这种情况化归到上述的的情况,也就是该节点是其父节点的左子结点
的情况。如何做到呢?我们可以沿着指向父节点的指针一直向上遍历,直到找到一个节点,该节点是它父节点的左子结点。如果我们找到了这样的节点,那么这个节点的父节点就是我们要找的下一个节点。
我们来看一个例子,找到上图中节点i
的下一个节点,我们可以沿着指向父节点的指针,先到达节点e
,但是节点e
是它父节点b
的右节点,继续向上遍历到达节点b
,节点b
是它父节点a
的左子结点,因此节点b
的父节点a
就是节点i
的下一个节点。同理我们可以找到节点g
的下一个节点,结果为空,也就是节点g
没有下一个节点。
上述过程需要对二叉树中序遍历有充分的理解。
这两种情况的代码实现:
// 情况二:pNode 右子树为空,但是其父节点的左节点,下一个节点即为其父节点 |
至此,我们就分析完了这道题。这道题还是需要对二叉树中序遍历有深入的理解才能够实现的。平时我们可以多画画图,举一些例子,找出规律,来帮助我们解题。
完整代码:
import java.util.*; |