题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
/*
* 中序遍历 思路:
* (1) 若该节点存在右子树:则下一个节点为右子树最左子节点(如图节点 B )
* (2) 若该节点不存在右子树:这时分两种情况:
* 2.1 该节点为父节点的左子节点,则下一个节点为其父节点(如图节点 D )
* 2.2该节点为父节点的右子节点,则沿着父节点向上遍历,直到找到一个节点的父节点的左子节点为该节点, 则该节点的父节点下一个节点(如图节点 I,沿着父节点一直向上查找找到 B ( B 为其父节点的左子节点),则 B 的父节点 A 为下一个节点)。
*/
public TreeLinkNode GetNext(TreeLinkNode pNode) {
// 该节点为空节点
if (pNode == null) {
return null;
}
// 该节点有右子树,下一节点为右子树最左节点
if (pNode.right != null) {
// 指向右子树的根节点
pNode = pNode.right;
// 查找最左子树
while (pNode.left != null) {
pNode = pNode.left;
}
return pNode;
}
// 该节点无右子树,
while (pNode.next != null) {
TreeLinkNode proot = pNode.next;
// 该节点是父节点的左子节点,返回父节点
if (proot.left == pNode) {
return proot;
}
// 改节点是父节点的右子树,向上继续找到直到该节点是父节点的左子节点
if (proot.right == pNode) {
pNode = proot;
}
}
// 直到为根节点时,则返回null
return null;
}
/**
* 前序遍历
* 1.只有根节点时,节点为空时(节点A)
* 2.有左子节点时,直接返回左子节点
* 3.无左子节点时,向上遍历父节点知道得到右子节点
* 这里有一个特殊情况,就是当该节点本身就是右子节点时,需要保存自身,在往上遍历
*
* */
public TreeLinkNode GetNextbyFirst(TreeLinkNode pNode) {
if (pNode == null) {
return null;
}
// 只有根节点的情况(节点A)
if (pNode.next == null && pNode.left == null && pNode.right == null) {
return null;
}
// 如果有左子节点,直接返回(节点BCE)
if (pNode.left != null) {
return pNode.left;
}
// 标记当前节点
TreeLinkNode p = pNode;
// 当前节点无左子节点时,
while (pNode != null) {
// 如果有右子节点,则返回右子节点,否则往上找父节点的兄弟
if (pNode.right != p && pNode.right != null) {
return pNode.right;
} else {
p = pNode;
pNode = pNode.next;
}
}
return null;
}
/**
* 后序遍历--左右根
*
*
*
* */
public TreeLinkNode GetNextbyLast(TreeLinkNode pNode) {
if (pNode == null || pNode.next == null) {
return null;
}
// 该节点为右子树上的节点,且该节点无子节点,则后序遍历的下一个节点是该节点的父节点
if (pNode.left == null && pNode.right == null) {
// 该节点为父节点的左子节点
if (pNode.next.left == pNode) {
// 该节点无右兄弟
if (pNode.next.right == null) {
return pNode.next;
}
// 该节点有右兄弟子树
else {
// 找到最左子节点
pNode = pNode.next.right;
while (pNode != null) {
// 左子节点不为空
if (pNode.left != null) {
pNode = pNode.left;
}
// 左子节点为空,右子节点不为空
else if (pNode.right != null) {
pNode = pNode.right;
}
// 左右子节点都为空
else {
return pNode;
}
}
}
}
}
// 该节点为父节点的左子节点
if (pNode.left != null && pNode.right != null
&& pNode.next.left == pNode) {
// 该节点无右兄弟
if (pNode.next.right == null) {
return pNode.next;
}
// 该节点有右兄弟子树
else {
// 找到最左子节点
pNode = pNode.next.right;
while (pNode != null) {
// 左子节点不为空
if (pNode.left != null) {
pNode = pNode.left;
}
// 左子节点为空,右子节点不为空
else if (pNode.right != null) {
pNode = pNode.right;
}
// 左右子节点都为空
else {
return pNode;
}
}
}
}
// 该节点为父节点的右子节点,则返回父节点,节点I,
if (pNode.next.right == pNode) {
return pNode.next;
}
return pNode;
}