您的位置:首页 > 其它

树---求二叉树两个节点的距离

2015-11-01 10:42 471 查看
一、问题描述

二叉树两节点距离是指从一个节点到达另一个节点需要的最少边数。如图:



二、问题求解

假设root是二叉树的根节点;n1和n2是给定二叉树的两个节点的数值。

lca是n1和n2的最小公共祖先;Dist(n1, n2)为n1和n2之间的距离。

因此,两节点距离的计算公式为:

Dist(n1, n2) = Dist(root, n1) + Dist(root, n2) - 2*Dist(root, lca)


三、代码

时间复杂度: O(n)

#include<iostream>
using namespace std;

typedef int KeyType;
typedef struct BinaryTreeNode
{
KeyType key;
struct BinaryTreeNode *left;
struct BinaryTreeNode *right;
}BTNode, *BiTree;
//创建二叉树节点
BTNode *CreateBTNode(KeyType key)
{
BTNode *node = new BTNode;
node->key = key;
node->left = node->right = NULL;
return node;
}
//对于给定的树中两节点n1和n2,返回两者lca的指针
BTNode *findLCA(BTNode *root, KeyType n1, KeyType n2)
{
if(root == NULL) return NULL;

//(1)n1,n2中的一个是另一个的父节点,即为LCA
if(root->key==n1 || root->key==n2)
return root;
//(2)n1,n2没有父子关系,这时又存在两种情况:
//case1:同在一个子树。case2:分别在两个子树。
BTNode *left_lca=findLCA(root->left, n1, n2);
BTNode *right_lca=findLCA(root->right, n1, n2);
//都为真,说明两边子树都能找到n1或n2,这是case2的情况
if(left_lca && right_lca)
return root;//当n1,n2分别在两个子树时lca即为根节点
//case1的情况
return (left_lca != NULL)?left_lca:right_lca;
}

//返回key节点在root中的第几层,-1表示没有在root子树下找到
int findLevel(BTNode *root, KeyType key, int level)
{
if(root==NULL)
return -1;
if(root->key==key)
return level;
//递归查找左子树
int lev=findLevel(root->left, key, level+1);
if(lev==-1)//左子树没有找到则到右子树查找
return findLevel(root->right, key, level+1);
else
return lev;
}
//利用公式Dist(n1, n2)=Dist(root, n1)+Dist(root, n2)-2*Dist(root, lca)
int NodesDistance(BTNode *root, KeyType n1, KeyType n2)
{
BTNode *lca = findLCA(root, n1, n2);
int dis_lca = findLevel(root, lca->key, 0);
int dis_n1 = findLevel(root, n1, 0);
int dis_n2 = findLevel(root, n2, 0);
//计算n1和n2的距离
int dis_n1_n2 = dis_n1 + dis_n2 - 2*dis_lca;
return dis_n1_n2;

}
int main()
{
BTNode *root = CreateBTNode(1);
root->left = CreateBTNode(2);
root->right = CreateBTNode(3);
root->left->left = CreateBTNode(4);
root->left->right = CreateBTNode(5);
root->right->left = CreateBTNode(6);
root->right->right = CreateBTNode(7);
root->right->left->right = CreateBTNode(8);
cout <<"Distance(4, 5): "<<NodesDistance(root, 4, 5)<<endl;
cout <<"Distance(4, 6): "<<NodesDistance(root, 4, 6)<<endl;
cout <<"Distance(3, 4): "<<NodesDistance(root, 3, 4)<<endl;
cout <<"Distance(2, 4): "<<NodesDistance(root, 2, 4)<<endl;
cout <<"Distance(8, 5): "<<NodesDistance(root, 8, 5)<<endl;
return 0;
}


结果:

Distance(4, 5): 2
Distance(4, 6): 4
Distance(3, 4): 3
Distance(2, 4): 1
Distance(8, 5): 5

Process returned 0 (0x0)   execution time : 0.158 s
Press any key to continue.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树