这个共同祖先像不像那道找shared链表算法真题!不过真题答案只找到了公共值结点就算后边一致,万一后边不是共同后缀呢,感觉还得用栈,从最后一个元素开始弹出!
代码思路:找路径(分别到u,v停止)
然后相当于那道真题,弹出第一个相同元素的是LCA
真的太顺利了,运行一次就全对!
#include<iostream>
#include<stack>
using namespace std;
int in[10003],pre[10003],u,v;
struct node{
int data;
node *left,*right;
};
void create_tree(node* &root,int l1,int l2,int len){ //前序中序建树
if(len==0) return;
root=new node;
root->data=pre[l1];
if(len==1) return;
int i;
for(i=l2;i<l2+len;i++){
if(in[i]==pre[l1]) break;
}
create_tree(root->left,l1+1,l2,i-l2);
create_tree(root->right,l1+len-lr,i+1,len-i+l2-1);
}
bool searchNode(node *root,int x ,stack<node*> &s) { //找路径
if(root == NULL) return false;
s.push(root);
if(root->data == x) return true;
bool b = false;
if(root->left != NULL) b = searchNode(root->left,x,s);
if(!b && root->right != NULL) b = searchNode(root->right,x,s);
if(!b) s.pop();
return b;
}
void print_LCA(node* p,stack<node*> su,stack<node*> sv){
if(!su.size()&&!sv.size()){
cout<<"ERROR: "<<u<<" and "<<v<<" are not found."<<endl;return;
}
else if(!sv.size()){
cout<<"ERROR: "<<v<<" is not found."<<endl; return;
}
else if(!su.size()){
cout<<"ERROR: "<<u<<" is not found."<<endl; return;
}
else{
if(su.size()>sv.size()){ //使路径长度相等时再从后往前弹出,想象两条shared链表
while(su.size()!=sv.size()) su.pop();
}
else{
while(su.size()!=sv.size()) sv.pop();
}
node *x=su.top(),*y=sv.top();
while(su.size()>0&&x->data!=y->data){
su.pop();
sv.pop();
x=su.top();
y=sv.top();
}
if(x->data==y->data){
if(x->data==u)
cout<<u<<" is an ancestor of "<<v<<"."<<endl;
else if(y->data==v)
cout<<v<<" is an ancestor of "<<u<<"."<<endl;
else{
node* p=su.top();
cout<<"LCA of "<<u<<" and "<<v<<" is "<<p->data<<"."<<endl;
}
}
}
}
int main(){
int m,n;
cin>>m>>n;
for(int i=0;i<n;i++) cin>>in[i];
for(int i=0;i<n;i++) cin>>pre[i];
node* root;
create_tree(root,0,0,n);
for(int i=0;i<m;i++){
stack<node*> su,sv;
cin>>u>>v;
searchNode(root,u,su);
searchNode(root,v,sv);
print_LCA(root,su,sv);
}
return 0;
}
注意:误以为用栈实现先序遍历,并找到给定结点为止可以得到一条由跟结点到该结点的路径,结果确实差不多可以,但是栈中会少了一个给定结点的父结点。
void preorder(node* p,int x,stack<node*> &temp,int t){
while(p!=NULL||temp.size()>0){
while(p!=NULL){
temp.push(p);
if(p->data==x&&t==1){
tagu=1;return;
}
else if(p->data==x&&t==2){
tagv=1;return;
}
p=p->left;
}
p=temp.top();
temp.pop();
p=p->right;
}
}