核心算法:首先使用递归方式获得最低公共祖先,然后使用队列特性,先进后出的特性使用广度搜索优先算法,按照广度进行填充在队列中,然后获得最低公共祖先元素的深度,然后我们需要遍历该队列中的所有元素,只要大于等于目标元素的深度,就可以将该元素在队列中去除,剩下的就是所有公共祖先的所有祖先了
struct Node
{
int val;
Node* left;
Node* right;
Node():val(0),left(NULL),right(NULL){}
};
Node* head=NULL;
Node* t1=NULL;
Node* t2=NULL;
void createNode(int value)
{
Node* cur=head;
if(NULL==cur)
{
head=new Node();
head->val=value;
return;
}
while(NULL!=cur)
{
if(cur->val<value)
{
//应该放在右子树上
if(NULL==cur->right)
{
cur->right=new Node();
cur->right->val=value;
if(value==80)
{
t1=cur->right;
}
if(value==58)
{
t2=cur->right;
}
break;
}
else
{
//右子树是空的,那么
cur=cur->right;
}
}
else
{
//应该放在左子树上
if(NULL==cur->left)
{
cur->left=new Node();
cur->left->val=value;
if(value==80)
{
t1=cur->left;
}
if(value==58)
{
t2=cur->left;
}
break;
}
else
{
cur=cur->left;
}
}
}
}
Node* getCommonAnce(Node* root,Node* t,Node* q)
{
if(NULL==root)
{
return NULL;
}
if(root==t||root==q)
{
return root;
}
Node* pLeft=getCommonAnce(root->left,t,q);
Node* pRight=getCommonAnce(root->right,t,q);
if(NULL==pLeft&&pRight!=NULL)
{
//左子树中没有找到,那么均在右子树中
return pRight;
}
if(NULL==pRight&&pLeft!=NULL)
{
//右子树中没有找打,则均在左子树中
return pLeft;
}
//都不为空,则root即为最低公共祖先
return root;
}
bool getPath(Node* head,Node* t,List<Node*>*& path)
{
if(NULL==head||NULL==t)
return false;
if(head==t)
return true;
bool found=false;
path->push_back(head);
found=getPath(head->left,t,path);
if(!found)
found=getPath(head->right,t,path)
if(!found)
path->pop_back(head);
return found;
}
deque<Node*>* getAllAnce(Node* root,Node* t)
{
if(NULL==root)
{
return NULL;
}
deque<Node*>* que=new deque<Node*>();
Node* cur=root;
que->push_back(cur);
deque<Node*>::iterator itr=que->begin();
while(true)
{
if(itr!=que->end())
{
itr++;
if(itr==que->end())
break;
}
else
{
break;
}
Node* tmp=*itr;
if(tmp==t)
break;
if(tmp->left)
{
que->push_back(tmp->left);
}
if(tmp->right)
{
que->push_back(tmp->right);
}
}
return que;
}
int getNodeDepth(Node* head,Node* t)
{
if(NULL==head)
return 0;
if(head==t)
return 1;
int lDepth=getNodeDepth(head->left,t);
int rDepth=getNodeDepth(head->right,t);
return lDepth>rDepth?lDepth+1:rDepth+1;
}
void EraseBroth(deque<Node*>*& que,int depth)
{
//我们在队列中找到,去除掉高度为depth的节点,从后向前开始
if(que==NULL)
return ;
deque<Node*>::iterator itr=que->begin();
for(;itr!=que->end();itr++)
{
if(getNodeDepth(head,*itr)>=depth)
{
que->erase(itr);
}
}
}
int main()
{
int a=0;
while(cin>>a&&a!=-1)
{
createNode(a);
}
//利用递归方式求得两者最低公共祖先
Node* lowAnce=getCommonAnce(head,t1,t2);
if(NULL!=lowAnce)
{
cout<<"最低祖先是:"<<lowAnce->val<<endl;
}
//获得最低祖先之后可以根据从根节点到lowAnce之间的路径确定t1和t2节点之间的路径,获得t1和t2的所有共同祖先
List<Node*>AllPath;
if(getPath(head,lowAnce,&AllPath))
{
cout<<"找到了路径\n";
List<Node*>::iterator itr=AllPath.begin();
for(;itr!=AllPath.end();itr++)
{
cout<<(*itr)->val<<endl;
}
}
}