首页 > 代码库 > 二叉树求两节点最低公共祖先,求随意两节点距离

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

-------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,只是前者这样写更easy理解 } 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



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