获得二叉树中两个节点的所有公共祖先

来源:互联网 发布:广联达软件配置要求 编辑:程序博客网 时间:2024/05/21 18:41

核心算法:首先使用递归方式获得最低公共祖先,然后使用队列特性,先进后出的特性使用广度搜索优先算法,按照广度进行填充在队列中,然后获得最低公共祖先元素的深度,然后我们需要遍历该队列中的所有元素,只要大于等于目标元素的深度,就可以将该元素在队列中去除,剩下的就是所有公共祖先的所有祖先了

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


0 0
原创粉丝点击