题目链接https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
如有更优的解法:欢迎提点
/*
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
*/
/*
*
* 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。
* 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
*
*中序遍历:先左子树,后根节点,再右子树
*前序遍历:先根节点,后左子树,再右子树
*后序遍历:先左子树,后右子树,再根节点。
*
*
* A
* / \
* B C
* / \ / \
* D E F G
* / \
* H I
*
* DBHEIAFCG----中序遍历
* ABDEHICFG----前序遍历
* DHIEBFGCA----后序遍历
*/
public class Solution22 {
/*
* 中序遍历 思路:
* (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;
}
public static void main(String[] args) {
TreeLinkNode A = new TreeLinkNode("A");
TreeLinkNode B = new TreeLinkNode("B");
TreeLinkNode C = new TreeLinkNode("C");
TreeLinkNode D = new TreeLinkNode("D");
TreeLinkNode E = new TreeLinkNode("E");
TreeLinkNode F = new TreeLinkNode("F");
TreeLinkNode G = new TreeLinkNode("G");
TreeLinkNode H = new TreeLinkNode("H");
TreeLinkNode I = new TreeLinkNode("I");
A.next = null;
A.left = B;
A.right = C;
B.next = A;
B.left = D;
B.right = E;
D.next = B;
D.left = D.right = null;
E.next = B;
E.left = H;
E.right = I;
H.next = E;
H.left = H.right = null;
I.next = E;
I.left = I.right = null;
C.next = A;
C.left = F;
C.right = G;
F.next = C;
F.left = F.right = null;
G.next = C;
G.left = G.right = null;
// * DBHEIAFCG----中序遍历
// * ABDEHICFG----前序遍历
// * DHIEBFGCA----后序遍历
// try {
// Solution22 s22 = new Solution22();
// TreeLinkNode p1 = s22.GetNext(A);
// System.out.println("p1=="+p1.val);
// TreeLinkNode p2 = s22.GetNextbyFirst(I);
// System.out.println("p2=="+p2.val);
// } catch (Exception e2) {
// System.out.println("null");
// }
Solution22 s22 = new Solution22();
TreeLinkNode p2 = s22.GetNextbyLast(D);
// System.out.println(""+p2);
while (p2 != null) {
try {
System.out.println("p2==" + p2.val);
p2 = s22.GetNextbyLast(p2);
} catch (Exception e2) {
// TODO: handle exception
System.out.println("null");
}
}
}
}