程序员面试经典--二叉查找树节点的“下一个结点”

4.6问题:

设计一个算法,找出二叉树中指定的结点“下一个”结点(也即中序后继)。可以假定每个结点都含有指向父节点的链接。

思考:

回忆一下中序遍历,它会先遍历左子树,然后是当前节点,接着右子树,要解决这个问题需要非常小心。

假定我们有一个假想的结点,先是左子树,然后是当前结点,最后就是右子树,目标结点当然是在右子树,那么是右子树的哪一个呢?很简单,就是右子树的最左边的那个结点。在这种情况下,只需返回当前结点右子树的最左边的结点。有点儿绕啊。

若当前节点没有右子树又该怎么办?这种情况就比较复杂了。这时我们就需要返回到上一层结点,就是当前节点的父节点。按照中序遍历的顺序,如果当前节点是其父节点的左孩子,那么“下一个结点”就是其父节点。如果当前结点是其父节点的右孩子,那么说明它的父节点已经被访问过了,那就需要往其父结点的父结点访问,依此类推的网上需找,直至找到第一个未访问的结点,若没有。则表明当前节点就是中序遍历的最后一个结点。(全是文字描述,需要仔细分析,不是很直观)

下面就是该算法的实现代码:

public TreeNode inorderSucc(TreeNode n){
	if(n == null) return null;
	
	//找到右子结点,则返回右子树里最左边的结点。
	if(n.right != null){
		return leftMostChild(n.right);
	}else{
		TreeNode q = n;
		TreeNode x = q.parent;
		//向上直至位于左边而不是右边
		while(x != null && x.left !=q){//此处需要仔细分析
			q = x;
			x = x.parent;
		}
		return x;
	}
}

public TreeNode leftMostChild(TreeNode n){//返回当前子树的最左边结点。
	if(n == null){
		return null;
	}
	while(n.left != null){
		n=n.left;
	}
	return n;
}




猜你喜欢

转载自blog.csdn.net/Aguangg_6655_la/article/details/70360477