设为首页 加入收藏

TOP

求树中两个节点的最低公共祖先(一)
2015-07-24 05:57:30 来源: 作者: 【 】 浏览:16
Tags:两个节点 最低 公共 祖先

情形1:树是搜索二叉树

思路:从树的根节点开始遍历,如果根节点的值大于其中一个节点,小于另外一个节点,则根节点就是最低公共祖先。否则如果根节点的值小于两个节点的值,则递归求根节点的右子树,如果大于两个节点的值则递归求根的左子树。如果根节点正好是其中的一个节点,那么说明这两个节点在一条路径上,所以最低公共祖先则是根节点的父节点

public static BinaryTreeNode getLowestCommonAncestor(BinaryTreeNode rootParent,BinaryTreeNode root,BinaryTreeNode node1,BinaryTreeNode node2){
		if(root == null || node1 == null || node2 == null){
			return null;
		}
		if((root.value - node1.value)*(root.value - node2.value) < 0){
			return root;
		}else if((root.value - node1.value)*(root.value - node2.value) > 0){
			BinaryTreeNode newRoot = ((root.value > node1.value) && (root.value > node2.value)) ? root.leftNode : root.rightNode;
			return getLowestCommonAncestor(root,newRoot, node1, node2);
		}else{
			return rootParent;
		}
	}

复杂度:由于递归调用二叉树,所以时间复杂度是O(logn),空间复杂度是O(1)

测试:

\

public class BinaryTreeNode {
	public int value;
	public BinaryTreeNode leftNode;
	public BinaryTreeNode rightNode;
	
	public BinaryTreeNode(int value){
		this.value = value;
		leftNode = null;
		rightNode = null;
	}
}

public static void main(String[] args){
		BinaryTreeNode A = new BinaryTreeNode(4);
		BinaryTreeNode B = new BinaryTreeNode(2);
		BinaryTreeNode C = new BinaryTreeNode(6);
		BinaryTreeNode D = new BinaryTreeNode(1);
		BinaryTreeNode E = new BinaryTreeNode(3);
		BinaryTreeNode F = new BinaryTreeNode(5);
		BinaryTreeNode G = new BinaryTreeNode(7);
		A.leftNode = B;
		A.rightNode = C;
		B.leftNode = D;
		B.rightNode = E;
		C.leftNode = F;
		C.rightNode = G;
		BinaryTreeNode res1 = getLowestCommonAncestor(null, A, E, F);
		BinaryTreeNode res2 = getLowestCommonAncestor(null, A, D, E);
		BinaryTreeNode res3 = getLowestCommonAncestor(null, A, B, D);
		System.out.println("The lowest common ancestor of 3 and 5 is " +res1.value);
		System.out.println("The lowest common ancestor of 1 and 3 is " +res2.value);
		System.out.println("The lowest common ancestor of 1 and 2 is " +res3.value);
}

结果:

The lowest common ancestor of 3 and5 is 4

The lowest common ancestor of 1 and3 is 2

Thelowest common ancestor of 1 and 2 is 4


情形2:树是普通的二叉树,且树中节点有指向父节点指针

思路:两个节点如果在两条路径上,那么类似于“求两个链表的第一个公共节点”的算法题

//含有指向父节点指针的树节点
public class NewBinaryTreeNode {
	public int value;
	public NewBinaryTreeNode parentNode;
	public NewBinaryTreeNode leftNode;
	public NewBinaryTreeNode rightNode;
	
	public NewBinaryTreeNode(int value){
		this.value = value;
		parentNode = null;
		leftNode = null;
		rightNode = null;
	}
}

public static NewBinaryTreeNode  getLowestCommonAncestor1(NewBinaryTreeNode root,NewBinaryTreeNode node1,NewBinaryTreeNode node2){
		if(root == null || node1 == null || node2 == null){
			return null;
		}
		int depth1 = findTheDepthOfTheNode(root, node1, node2);
		if(depth1 == -1){
			return node2.parentNode;
		}
		int depth2 = findTheDepthOfTheNode(root, node2, node1);
		if(depth2 == -1){
			return node1.parentNode;
		}
		//p指向较深的节点q指向较浅的节点
		NewBinaryTreeNode p = depth1 > depth2 ? node1 : node2;
		NewBinaryTreeNode q = depth1 > depth2 ? node2 : node1;
		int depth =  Math.abs(depth1 - depth2);
		while(depth > 0){
			p = p.parentNode;
			depth --;
		}
		while(p != q){
			p = p.parentNode;
			q = q.parentNode;
		}
		return p;
	}
	
	//求node1的深度,如果node1和node2在一条路径上,则返回-1,否则返回node1的深度
	public static int findTheDepthOfTheNode(NewBinaryTreeNode root,NewBinaryTreeNode node1,NewBinaryTreeNode node2){
		int depth = 0;
		while(node1.p
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 1698 Just a Hook 线段树解法 下一篇POJ 3613 Cow Relays (floyd + ..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: