二叉树最近公共父节点

#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
    int val;
    TreeNode*left;
    TreeNode*right;
    TreeNode(int x):
        val(x),left(NULL),right(NULL) {}
};
int k;
int x,y;
void create(TreeNode*root,int n)
{
    if(n==1)return;
    root->left=new TreeNode(root->val-pow(2,n-2));
    root->right=new TreeNode(root->val+pow(2,n-2));
    create(root->left,n-1);
    create(root->right,n-1);
}
//针对二叉排序树
TreeNode*findTreeNode(TreeNode*root,int n)
{
    if(root->val==n)return root;
    else if(root->val<n)return findTreeNode(root->right,n);
    else findTreeNode(root->left,n);
}
//方法一:针对所有二叉树结构,复杂度较高
TreeNode*findCommonParent(TreeNode*root,TreeNode*p,TreeNode*q)
{
    if(root==NULL||p==root||q==root)return root;
    TreeNode*leftNode=findCommonParent(root->left,p,q);
    TreeNode*rightNode=findCommonParent(root->right,p,q);
    if(leftNode&&rightNode)return root;
    else if(leftNode)return leftNode;
    else return rightNode;
}
//方法二:针对二叉树平排序结构,复杂度较低
TreeNode*findCommonParent1(TreeNode*root,TreeNode*p,TreeNode*q)
{
    int min,max;
    if(p->val<q->val)min=p->val,max=q->val;
    else min=q->val,max=p->val;
    while(root)
    {
        if(root->val>=min&&root->val<=max)return root;
        else if(root->val<min&&root->val<max)root=root->right;
        else root=root->left;
    }
    return NULL;
}
//获得根节点到某一节点路径
bool getNodePath(TreeNode*root,TreeNode*p,list<TreeNode*>&l)
{
    if(root==NULL||p==NULL)return false;
    l.push_back(root);
    if(root==p)return true;
    bool found=false;
    if(root->left)found=getNodePath(root->left,p,l);
    if(!found&&root->right)found=getNodePath(root->right,p,l);
    if(!found)l.pop_back();
    return found;
}
//方法三:针对所有二叉树结构,复杂度较低
TreeNode*findCommonParent2(TreeNode*root,TreeNode*p,TreeNode*q)
{
    list<TreeNode*>l1,l2;
    getNodePath(root,p,l1);
    getNodePath(root,q,l2);
    reverse(l1.begin(),l1.end());
    reverse(l2.begin(),l2.end());
    list<TreeNode*>::iterator it1=l1.begin(),it2=l2.begin();
    if(l1.size()>l2.size())
    {
        for(int i=0; i<l1.size()-l2.size(); i++)
            it1++;
    }
    else
    {
        for(int i=0; i<l2.size()-l1.size(); i++)
            it2++;
    }
    for(; it1!=l1.end()&&it2!=l2.end(); it1++,it2++)
    {
        if(*it1==*it2)
        {
            return *it1;
            break;
        }
    }
    return NULL;
}
//前序遍历
void print(TreeNode*root)
{
    if(root==NULL)return;
    cout<<root->val<<endl;
    print(root->left);
    print(root->right);
}
int main()
{
    while(cin>>k>>x>>y)
    {
        TreeNode*root=new TreeNode(pow(2,k-1));
        create(root,k);
        TreeNode*p=findTreeNode(root,x);
        TreeNode*q=findTreeNode(root,y);
        TreeNode*commonParent=findCommonParent(root,p,q);
        cout<<"方法一:"<<commonParent->val<<endl;
        TreeNode*commonParent1=findCommonParent1(root,p,q);
        cout<<"方法二:"<<commonParent1->val<<endl;
        TreeNode*commonParent2=findCommonParent2(root,p,q);
        cout<<"方法三:"<<commonParent2->val<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值