二叉树求两节点最低公共祖先,求任意两节点距离

-------1.求最低公共祖先LCA( Lowest Common Ancestor )

         什么是最低公共祖先?如下图,2与3的LCA是1;1与4的LCA是1;4与5的LCA是2。




      那么给定两个节点n1和n2,现在要找出它们的LCA,如何找?首先分析一下,n1和n2有几种情况?第一种,n1和n2分别在一个节点的左右子树中,比如4和5,LCA就是2,5和6,LCA就是1,2和3,LCA就是1;第二种,n1和n2都在左子树或右子树,比如2和4,LCA就是2,1和4,LCA就是1。一共这两种情况,其实一点也不难,看代码实现吧。

/* 只用一次遍历解决LCA */
#include <iostream>
using namespace std;

struct Node
{
    Node *left, *right;
	int key;
};

Node* newNode(int key)
{
	Node *temp = new Node;
	temp->key = key;
	temp->left = temp->right = nullptr;
	return temp;
}

// 返回n1和n2的LCA的指针
Node * findLCA(Node* root, int n1, int n2)
{
	if (root == nullptr)
		return nullptr;

	if (root->key == n1 || root->key == n2)
		return root;

	Node * left = findLCA(root->left, n1, n2);
	Node * right = findLCA(root->right, n1, n2);

	if (left&&right)//如果n1和n2分别在左右子树中
		return root;

	return (left != nullptr ? left : right);
}

//测试
int main()
{
	// 构造上面图中的树
	Node * root = newNode(1);
	root->left = newNode(2);
	root->right = newNode(3);
	root->left->left = newNode(4);
	root->left->right = newNode(5);
	root->right->left = newNode(6);
	root->right->right = newNode(7);
	cout << "LCA(4, 5) = " << findLCA(root, 4, 5)->key;
	cout << "\nLCA(4, 6) = " << findLCA(root, 4, 6)->key;
	cout << "\nLCA(3, 4) = " << findLCA(root, 3, 4)->key;
	cout << "\nLCA(2, 4) = " << findLCA(root, 2, 4)->key;
	cout << endl;
	return 0;
}

------2.求任意两节点距离:

        对于普通的二叉树,如何找到两个给定节点之家的距离?距离是指连接两个节点需要的最小的边的条数。例如下面的二叉树:



代码如下:

#include <iostream>
using namespace std;

struct Node
{
    Node *left, *right;
	int key;
};

Node* newNode(int key)
{
	Node *temp = new Node;
	temp->key = key;
	temp->left = temp->right = nullptr;
	return temp;
}

int FindLevel(Node * _root, int node)//返回node节点在root中的第几层,-1代表在子树下未找到node
{
	if (_root == nullptr)
		return -1;

	if (_root->key == node)
		return 0;

	int level = FindLevel(_root->left, node);//先在左子树找

	if (level == -1)//如果左子树没找到,在右子树找
		level = FindLevel(_root->right, node);

	if (level != -1)//在找到node的时候,递归一个一个结束,逐渐加一
		return level + 1;

	return -1;
}

Node * findLCA(Node* root, int n1, int n2)//找到n1和n2的LCA(已在上部分讲过如何求解LCA的问题)
{
	if (root == nullptr)
		return nullptr;

	if (root->key == n1 || root->key == n2)
		return root;

	Node * left = findLCA(root->left, n1, n2);
	Node * right = findLCA(root->right, n1, n2);

	if (left&&right)//如果n1和n2分别在左右子树中
		return root;

	return (left != nullptr ? left : right);

}

int DistanceNodes(Node * _root, int n1, int n2)
{
	Node * lca = findLCA(_root, n1, n2);

	int lca_level = FindLevel(_root, lca->key);
	int n1_level = FindLevel(_root, n1);
	int n2_level = FindLevel(_root, n2);

	return (n1_level - lca_level) + (n2_level - lca_level);//也就是n1_level+n2_level-2*lca_level,不过前者这样写更容易理解
}

int main()
{
	Node * root = newNode(1);
	root->left = newNode(2);
	root->right = newNode(3);
	root->left->left = newNode(4);
	root->left->right = newNode(5);
	root->right->left = newNode(6);
	root->right->right = newNode(7);
	root->right->left->right = newNode(8);

	cout << "Dist(8,7) = " << DistanceNodes(root, 8, 7) << endl;
	cout << "Dist(8,3) = " << DistanceNodes(root, 8, 3) << endl;
	cout << "Dist(8,2) = " << DistanceNodes(root, 8, 2) << endl;

	return 0;
}

运行如下:



二叉树----第一篇(构造,遍历,求节点,求叶子)参考链接:http://blog.csdn.net/laojiu_/article/details/50196823

参考自:http://www.acmerblog.com/distance-between-given-keys-5995.html



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值