参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:在中序遍历中,求二叉树的下一个节点
给定一棵二叉树和其中的一个节点,如何找出中序遍历顺序的下一个节点?树中的结点除了有两个分别指向左右子节点的指针以外,还有一个指向父节点的指针。
主要思路:
分三种情况:
1.该节点的右子树非空:它的下一节点就是右子树的最左节点。
2.该节点的右子树为空,但是它是其父节点的左节点:下一节点就是其父节点。
3.该节点的右子树为空,但是它是其父节点的右节点:沿着指向父节点的指针一直向上遍历,直到找到一个节点A,A是其父节点的左节点(A==A.parent.left),那么A.parent(A的父节点)就是所求的下一个节点。
若三种情况都不满足,则下一个节点为空。
关键点:中序遍历的特点:先左节点,再父节点,最后右节点
时间复杂度:O(树高度)
public class NextTreeNode
{
public static void main(String[] args)
{
// 10
// /
// 6
// /\
// 4 8
TreeLinkNode node8 = getTree();
TreeLinkNode next = getNextNodeFromInorder(node8);
System.out.println(next.val); //10
}
private static TreeLinkNode getTree()
{
TreeLinkNode root = new TreeLinkNode(10);
TreeLinkNode node6 = new TreeLinkNode(6);
TreeLinkNode node4 = new TreeLinkNode(4);
TreeLinkNode node8 = new TreeLinkNode(8);
root.left = node6;
node6.parent = root;
node6.left = node4;
node4.parent = node6;
node6.right = node8;
node8.parent = node6;
return node8;
}
/**
* 二叉树的下一个结点(中序遍历)
* @param pNode
* @return
*/
public static TreeLinkNode getNextNodeFromInorder(TreeLinkNode pNode)
{
if (pNode == null) return null;
//当前节点右子树非空,则查找右子树的最左子节点
if (pNode.right != null)
{
return rightIsNotNull(pNode);
} else if (pNode.parent != null) //右子树为空,父节点非空
{
return rightIsNull(pNode);
}
return null;
}
//右子树非空
private static TreeLinkNode rightIsNotNull(TreeLinkNode pNode)
{
TreeLinkNode right = pNode.right;
//查找最左子节点
while (right.left != null)
{
right = right.left;
}
return right;
}
//右子树为空,父节点非空
private static TreeLinkNode rightIsNull(TreeLinkNode pNode)
{
TreeLinkNode current = pNode;
TreeLinkNode parent = pNode.parent;
//沿着指向父节点的指针一直向上遍历,直到找到一个节点current,
//current是其父节点的左节点(current==parent.left),则退出循环
while (parent != null && current == parent.right)
{
current = parent;
parent = parent.parent;
}
return parent;
}
}
class TreeLinkNode
{
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode parent = null; //父节点
TreeLinkNode(int val)
{
this.val = val;
}
}