特别是 求两个结点的最低公共祖先最低公共祖先 O(n)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//定义节点
typedef struct node
{
struct node *lchild;
struct node *rchild;
string data;
}BNode, *BTree;
string str;
//按照前序顺序建立二叉树
void createBiTree(BTree &T)
{
string tstr="O";
char c;
cin >> c;
if('#' == c) //当遇到 #时,令树的根节点为NULL,从而结束该分支的递归
T = NULL;
else
{
T = new BNode;
tstr[0]=c;
T->data=tstr;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
}
//前序遍历二叉树并打印
void preTraversePrint(BTree T)
{
if(T)
{
cout<<T->data<<" ";
preTraversePrint(T->lchild);
preTraversePrint(T->rchild);
}
}
//中序遍历
void midTraverse(BTree T,string a1,BTree & p1,string a2, BTree & p2)
{
if(T)
{
midTraverse(T->lchild,a1,p1,a2,p2);
if(T->data==a1) p1=T;
if(T->data==a2) p2=T;
midTraverse(T->rchild,a1,p1,a2,p2);
}
}
//7 判断两棵二叉树是否结构相同
bool treeCompare(BTree T1,BTree T2)
{
if(T1==NULL && T2==NULL)
{
return true;
}else if(T1!=NULL&&T2==NULL||T1==NULL&&T2!=NULL)
{
return false;
}else if(T1!=NULL && T2!=NULL)
{
return treeCompare(T1->lchild,T2->lchild) && treeCompare(T1->rchild,T2->rchild);
}
}
//求两个结点的最低公共祖先最低公共祖先,即 LCA(Lowest Common Ancestor)//
//复杂性和 n 同样数量级
BTree FindLCA(BTree T, BTree target1, BTree target2)
{
if (T == NULL)
return NULL;
//cout<<"vist"<<T->data<<endl;
if (T == target1 || T == target2)
return T;
BTree left = FindLCA(T->lchild, target1, target2);
BTree right = FindLCA(T->rchild, target1, target2);
if (left && right) // 分别在左右子树
return T;
return left ? left : right; // 都在左子树或右子树
}
//10 求任意两结点距离
//首先找到两个结点的 LCA,然后分别计算 LCA 与它们的距离,最后相加即可。
int FindLevel(BTree node, BTree target)
{
if (node == NULL)
return -1;
if (node == target)
return 0;
int level = FindLevel(node->lchild, target); // 先在左子树找
if (level == -1)
level = FindLevel(node->rchild, target); // 如果左子树没找到,在右子树找
if (level != -1) // 找到了,回溯
return level + 1;
return -1; // 如果左右子树都没找到
}
int DistanceNodes(BTree node, BTree target1,BTree target2)
{
BTree lca = FindLCA(node, target1, target2); // 找到最低公共祖先结点
int level1 = FindLevel(lca, target1);
int level2 = FindLevel(lca, target2);
return level1 + level2;
}
//11 找出二叉树中某个结点的所有祖先结点
bool FindAllAncestors(BTree node, BTree target)
{
if(node==NULL)
{
return false;
}
if(node==target)
{
return true;
}
else
{
bool res=FindAllAncestors(node->lchild,target)|| FindAllAncestors(node->rchild,target);
if(res)
{
cout<<node->data<<" ";
return true;
}
else
return false;
}
}
//到叶节点的路径和为固定值
void pathsum(BTree T,int cur,int sum,int a[],int level)
{
if(T->lchild==NULL&&T->rchild==NULL)
{
cout<<cur<<" "<<T->data<<" "<<cur+T->data[0]-'0'<<endl;
if(cur+T->data[0]-'0'==sum)
{
a[level]=T->data[0]-'0';
for(int i=0;i<=level;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
}
if(T->lchild!=NULL)
{
a[level]=T->data[0]-'0';
pathsum(T->lchild,cur+a[level],sum,a,level+1);
}
if(T->rchild!=NULL)
{
a[level]=T->data[0]-'0';
pathsum(T->rchild,cur+a[level],sum,a,level+1);
}
}
int main() {
BTree root1,root2,root;
/*//判断两棵二叉树是否结构相同
createBiTree(root1); // *+a##b##*c##-#d##
createBiTree(root2); // *+a##b##*c##-##
cout<<treeCompare(root1,root1)<<endl;
cout<<treeCompare(root1,root2)<<endl;;
*/
BTree T1,p1,p2;
createBiTree(T1); // 123##45##6##7#8#9A##B##
preTraversePrint(T1);
midTraverse(T1,"5",p1,"6",p2);
cout<<endl;
root=FindLCA(T1,p1,p2);
cout<<"LCA( " +p1->data<<" , "<<p2->data<<" )=";
if(root!=NULL) cout<<root->data<<endl;
else cout<<" -1 "<<endl;
int dis=DistanceNodes(T1,p1,p2);
cout<<"节点之间距离:"<<dis<<endl;
cout<<"节点之间距离:"<<endl;
FindAllAncestors(T1,p1);
int sum=35;
int a[100];
cout<<endl<<"是否存在路径和"<<endl;
pathsum(T1,0,sum,a,0);
}