求两个树结点的最低公共祖先(Again)

题目:输入两个树结点,求它们的最低公共祖先。

http://www.gocalf.com/blog/least-common-ancestor.html

http://m.blog.csdn.net/blog/huoyaotl123/42155067 (二叉树中两个树结点的最低公共祖先)

事实上,这是一组题目,

情况一:此树为二叉树,且为二叉搜索树;

二叉搜索树是排过序的,位于左子树的结点都比父节点小;位于右子树的结点都比右子树大,我们只需要从树的根节点开始和两个输入的结点进行比较,如果当前结点的值比两个结点的值都要大,那么最低公共父节点一定在当前结点的左子树中,于是下一步遍历当前结点的左子树。如果当前结点的值比两个结点的值都小,那么最低公共父节点一定在当前结点的右子树中,于是下一步遍历当前结点的右子树结点。这样在树中从上到下找到的第一个在两个输入结点的值之间的结点,就是最低的公共祖先。

struct node *least_common_parent(bstree *root,struct node *a,struct node *b)
{
        if (root==NULL || a==NULL || b==NULL)
            return NULL;
        while (root != NULL) {
            if (root->key > a->key && root->key > b->key)
                root = root->lchild;
            else if (root->key < a->key && root->key < b->key)
                root = root->rchild;
            else 
                return root;
        }
        return NULL;
}

情况二:此树就是普通的树时;

struct  TreeNode
{
	int val;
	vector<TreeNode*> children;
};//多叉树结构

bool GetNodePath(TreeNode* root, TreeNode* node, list<TreeNode*>& path)
{ //用来得到从根节点到node结点的路径,路径保存在path中
	if (root == node)
		path.push_back(node);
	bool found = false;
	vector<TreeNode*>::iterator it = root->children.begin();
	while (!found && it != root->children.end())
	{
		found = GetNodePath(*it, node, path);
		++it;
	}
	if (!found)
		path.pop_back();
	return found;
}
TreeNode* GetLastCommonNode(const list<TreeNode*>& path1, const list<TreeNode*>& path2)
{ //求两个路径的最后一个公共结点
	list<TreeNode*>::const_iterator it1 = path1.begin();
	list<TreeNode*>::const_iterator it2 = path2.begin();
	TreeNode* res = NULL;
	while (it1 != path1.end() && it2 != path2.end())
	{
		if (*it1==*it2)
		    res = *it1;
		it1++;
		it2++;
	}
	return res;
}
TreeNode* GetLastCommonParent(TreeNode* root, TreeNode* node1, TreeNode* node2)
{
	if (root == NULL || node1 == NULL || node2 == NULL)
		return NULL;
	list<TreeNode*> path1;
	GetNodePath(root, node1, path1);
	list<TreeNode*> path2;
	GetNodePath(root, node2, path2);
	return GetLastCommonNode(path1, path2);

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值