-------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