我GitHub上的:剑指offer题解
题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
例子:
分析:分几种情况
1.有右子树的,它的下一个是右子树的最左子节点。(一直沿着指向左子结点的指针找到的叶子节点即为下一个节点)
2.没有右子树的,且如果它是它父节点的左子节点的话,它的下一个是它的父节点
3.没有右子树的,且它是它父节店的右子节点的话,它的情况比较复杂,要沿着它父节点上去,直到找到它是它父节点的左子节点为止,那么下一个就是这个父节点。
public class GetNext {
/**
* 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。
* 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
* @param pNode
* @return
*/
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;//指向的父节点
TreeLinkNode(int val) {
this.val = val;
}
}
/*
* 分析:分几种情况
* 1.有右子树的,它的下一个是右子树的最左子节点。(一直沿着指向左子结点的指针找到的叶子节点即为下一个节点)
* 2.没有右子树的,且如果它是它父节点的左子节点的话,它的下一个是它的父节点
* 3.没有右子树的,且它是它父节店的右子节点的话,它的情况比较复杂,要沿着它父节点上去,直到找到它是它父节点的左子节点为止,那么下一个就是这个父节点。
*/
public static TreeLinkNode getNext(TreeLinkNode pNode)
{
if(pNode == null) {
return null;
}
//第1种情况
if(pNode.right != null) {
pNode = pNode.right;
while(pNode.left != null) {
pNode = pNode.left;
}
return pNode;
}
//第2\3种情况
while(pNode.next != null) {
TreeLinkNode proot = pNode.next;
//第2种情况
if(proot.left == pNode) {
return proot;
}
//如果第2种情况还没达到,就继续向上遍历
pNode = pNode.next;
}
//如果向上遍历到了根节点后,上一个就是尾节点了。
return null;
}
public static void main(String[] args) {
//给定一个二叉树
GetNext getNext = new GetNext();
TreeLinkNode a = getNext.new TreeLinkNode(1);
TreeLinkNode b = getNext.new TreeLinkNode(2);
TreeLinkNode c = getNext.new TreeLinkNode(3);
TreeLinkNode d = getNext.new TreeLinkNode(4);
TreeLinkNode e = getNext.new TreeLinkNode(5);
TreeLinkNode f = getNext.new TreeLinkNode(6);
TreeLinkNode g = getNext.new TreeLinkNode(7);
TreeLinkNode h = getNext.new TreeLinkNode(8);
TreeLinkNode i = getNext.new TreeLinkNode(9);
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = h;
e.right = i;
c.left = f;
c.right = g;
b.next = a;
c.next = a;
d.next = b;
e.next = b;
h.next = e;
i.next = e;
f.next = c;
g.next = c;
TreeLinkNode aLinkNode = getNext(d);
System.out.println(aLinkNode.val);
}
}