二叉树总结(c++)

先写着备忘,以后再解释!

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <queue>
#include <list>
#include <cstdlib>

//#define LOCAL

using namespace std;
typedef char Elemtype;


//二叉树节点的定义
class BinaryTreeNode
{
public:
    BinaryTreeNode(Elemtype _data='#',BinaryTreeNode *_lchild=NULL,BinaryTreeNode *_rchild=NULL):data(_data),lchild(_lchild),rchild(_rchild){}
    void Set_data(Elemtype item)
    {
        data=item;
    }
    Elemtype Get_data()const
    {
        return data;
    }

    void Set_lchild(BinaryTreeNode *_lchild)
    {
        lchild=_lchild;
    }
    BinaryTreeNode *Get_lchild()const
    {
        return lchild;
    }

    void Set_rchild(BinaryTreeNode *_rchild)
    {
        rchild=_rchild;
    }
    BinaryTreeNode *Get_rchild()const
    {
        return rchild;
    }

private:
    Elemtype data;
    BinaryTreeNode *lchild,*rchild;
};

class BinaryTreeFun
{
public:
    BinaryTreeFun(BinaryTreeNode *t=NULL):root(t){}
    ~BinaryTreeFun(){delete root;}

    void Set_root(BinaryTreeNode *item)
    {
        root=item;
    }
    BinaryTreeNode *Get_root()const
    {
        return root;
    }

    //先序创建二叉树
    BinaryTreeNode *Createtree();
    //先序,中序,后序遍历二叉树
    void Preorder(BinaryTreeNode *t)const;
    void Inorder(BinaryTreeNode *t)const;
    void Postorder(BinaryTreeNode *t)const;
    //层次遍历
    void Leveltraversal(BinaryTreeNode *t)const;
    //求节点个数
    int GetNodeNum(BinaryTreeNode *t)const;
    //求树的深度
    int GetDepth(BinaryTreeNode *t)const;
    //求叶子节点个数
    int GetLeafNum(BinaryTreeNode *t)const;
    //求第k层节点的个数
    int GetKNum(BinaryTreeNode *t,int k)const;
    //求二叉树的镜像
    void Mirror(BinaryTreeNode *t);
    //根据先序,中序遍历重建二叉树
    BinaryTreeNode *Pre_RebuildTree(char pre[],char in[],int pre_s,int pre_e,int in_s,int in_e);
    //根据后序,中序遍历重建二叉树
    BinaryTreeNode *Pos_RebuildTree(char pos[],char in[],int pos_s,int pos_e,int in_s,int in_e);
    //寻找位置
    int Find(char in[],char ch,int in_s,int in_e);
    //判断一个节点是否在树种
    bool Is_Tree_Node(BinaryTreeNode *r,BinaryTreeNode *nt)const;

    //求两个节点的最近公共祖先(递归求解)
    BinaryTreeNode *Get_Comment_Parent(BinaryTreeNode *r,BinaryTreeNode *p1,BinaryTreeNode *p2);
    //求两个节点的最近公共祖先(非递归求解)
    BinaryTreeNode *GetCommentParent(BinaryTreeNode *r,BinaryTreeNode *p1,BinaryTreeNode *p2);
    //求根节点到某一节点的路径
    bool GetNodePath(BinaryTreeNode *r,BinaryTreeNode *nt,list<BinaryTreeNode*>&p);
    //判断二叉树是不是完全二叉树
    bool Is_CompleteBinaryTree(BinaryTreeNode *r)const;
    //判断二叉树是否为平衡二叉树
    bool Is_AVL(BinaryTreeNode *t,int &height)const;
    //求二叉树节点间的最大距离
    int MostDistance(BinaryTreeNode *r,int &ldis,int &rdis);

private:
    BinaryTreeNode *root;
};

//函数实现
BinaryTreeNode* BinaryTreeFun::Createtree()
{
    char item;
    BinaryTreeNode *t,*tl,*tr;
    cin>>item;
    if(item!='#')
    {
        BinaryTreeNode *temp=new BinaryTreeNode(item);
        t = temp;
        tl = Createtree();
        t->Set_lchild(tl);
        tr=Createtree();
        t->Set_rchild(tr);
        return t;
    }
    else
    {
        t=NULL;
        return t;
    }
}

void BinaryTreeFun::Preorder(BinaryTreeNode *t)const
{
    if(t!=NULL)
    {
        cout<<t->Get_data()<<" ";
        Preorder(t->Get_lchild());
        Preorder(t->Get_rchild());
    }
}
void BinaryTreeFun::Inorder(BinaryTreeNode *t)const
{
    if(t!=NULL)
    {
        Inorder(t->Get_lchild());
        cout<<t->Get_data()<<" ";
        Inorder(t->Get_rchild());
    }
}
void BinaryTreeFun::Postorder(BinaryTreeNode *t)const
{
    if(t!=NULL)
    {
        Postorder(t->Get_lchild());
        Postorder(t->Get_rchild());
        cout<<t->Get_data()<<" ";
    }
}

void BinaryTreeFun::Leveltraversal(BinaryTreeNode *t)const
{
    if(t==NULL) return;
    queue<BinaryTreeNode*>que;
    que.push(t);
    while(!que.empty())
    {
        BinaryTreeNode *temp=que.front();
        que.pop();
        cout<<temp->Get_data()<<" ";
        if(temp->Get_lchild()!=NULL)
            que.push(temp->Get_lchild());
        if(temp->Get_rchild()!=NULL)
            que.push(temp->Get_rchild());
    }
}

int BinaryTreeFun::GetNodeNum(BinaryTreeNode *t)const
{
    if(t==NULL)
        return 0;
    int lnum=GetNodeNum(t->Get_lchild());
    int rnum=GetNodeNum(t->Get_rchild());
    return lnum+rnum+1;
}

int BinaryTreeFun::GetDepth(BinaryTreeNode *t)const
{
    if(t==NULL)
        return 0;
    int lnum=GetDepth(t->Get_lchild());
    int rnum=GetDepth(t->Get_rchild());
    return (lnum>rnum)?(lnum+1):(rnum+1);
}

int BinaryTreeFun::GetLeafNum(BinaryTreeNode *t)const
{
    if(t==NULL)
        return 0;
    if(t->Get_lchild()==NULL && t->Get_rchild()==NULL)
        return 1;
    int lnum=GetLeafNum(t->Get_lchild());
    int rnum=GetLeafNum(t->Get_rchild());
    return lnum+rnum;
}

int BinaryTreeFun::GetKNum(BinaryTreeNode *t,int k)const
{
    if(t==NULL || k<1)
        return 0;
    if(k==1)
        return 1;
    int lnum=GetKNum(t->Get_lchild(),k-1);
    int rnum=GetKNum(t->Get_rchild(),k-1);
    return lnum+rnum;
}

void BinaryTreeFun::Mirror(BinaryTreeNode *t)
{
    if(t==NULL)
        return ;
    BinaryTreeNode *temp=t->Get_lchild();
    t->Set_lchild(t->Get_rchild());
    t->Set_rchild(temp);

    Mirror(t->Get_lchild());
    Mirror(t->Get_rchild());
}

int BinaryTreeFun::Find(char in[],char ch,int in_s,int in_e)
{
    int i;
    for(i=in_s;i<=in_e;i++)
        if(in[i] == ch)
            return i;
}

BinaryTreeNode* BinaryTreeFun::Pre_RebuildTree(char pre[],char in[],int pre_s,int pre_e,int in_s,int in_e)
{
    if(in_s>in_e) return NULL;
    BinaryTreeNode *temp;
    temp=new BinaryTreeNode(pre[pre_s]);
    int mid=Find(in,pre[pre_s],in_s,in_e);
    temp->Set_lchild(Pre_RebuildTree(pre,in,pre_s+1,pre_s+mid-in_s,in_s,mid-1));
    temp->Set_rchild(Pre_RebuildTree(pre,in,pre_s+mid-in_s+1,pre_e,mid+1,in_e));
    return temp;
}

BinaryTreeNode* BinaryTreeFun::Pos_RebuildTree(char pos[],char in[],int pos_s,int pos_e,int in_s,int in_e)
{
    if(in_s>in_e) return NULL;
    BinaryTreeNode *temp;
    temp = new BinaryTreeNode(pos[pos_e]);
    int mid=Find(in,pos[pos_e],in_s,in_e);
    temp->Set_lchild(Pos_RebuildTree(pos,in,pos_s,pos_s+mid-in_s-1,in_s,mid-1));
    temp->Set_rchild(Pos_RebuildTree(pos,in,pos_s+mid-in_s,pos_e-1,mid+1,in_e));
    return temp;
}

bool BinaryTreeFun::Is_Tree_Node(BinaryTreeNode *r,BinaryTreeNode *nt)const
{
    if(r == NULL)
        return false;
    else if(r == nt)
        return true;
    else
    {
        bool temp=false;
        if(r->Get_lchild()!=NULL)
            temp=Is_Tree_Node(r->Get_lchild(),nt);
        if(!temp && r->Get_rchild()!=NULL)
            temp=Is_Tree_Node(r->Get_rchild(),nt);
        return temp;
    }
}

BinaryTreeNode* BinaryTreeFun::Get_Comment_Parent(BinaryTreeNode *r,BinaryTreeNode *p1,BinaryTreeNode *p2)
{
    if(Is_Tree_Node(r->Get_lchild(),p1))
    {
        if(Is_Tree_Node(r->Get_rchild(),p2))
            return r;
        else return Get_Comment_Parent(r->Get_lchild(),p1,p2);
    }
    else
    {
        if(Is_Tree_Node(r->Get_lchild(),p2))
            return r;
        else return Get_Comment_Parent(r->Get_rchild(),p1,p2);
    }
}


bool BinaryTreeFun::GetNodePath(BinaryTreeNode *r,BinaryTreeNode *nt,list<BinaryTreeNode*>&p)
{
    if(r == NULL)
        return false;
    if(r == nt)
    {
        p.push_back(r);
        return true;
    }
    p.push_back(r);
    bool temp=false;
    temp=GetNodePath(r->Get_lchild(),nt,p);
    if(!temp)
        temp=GetNodePath(r->Get_rchild(),nt,p);
    if(!temp)
        p.pop_back();
    return temp;
}

BinaryTreeNode* BinaryTreeFun::GetCommentParent(BinaryTreeNode *r,BinaryTreeNode *p1,BinaryTreeNode *p2)
{
    if(r == NULL || p1 == NULL || p2 == NULL)
        return NULL;
    list<BinaryTreeNode*>path1;
    bool res1=GetNodePath(r,p1,path1);
    list<BinaryTreeNode*>path2;
    bool res2=GetNodePath(r,p2,path2);

    if(!res1 || !res2)
        return NULL;

    BinaryTreeNode *pres=NULL;

    list<BinaryTreeNode*>::const_iterator ite1 = path1.begin();
    list<BinaryTreeNode*>::const_iterator ite2 = path2.begin();
    while(ite1!=path1.end() && ite2!=path2.end())
    {
        if(*ite1 == *ite2)
            pres=*ite1;
        else break;
        ite1++;
        ite2++;
    }
    return pres;
}

bool BinaryTreeFun::Is_CompleteBinaryTree(BinaryTreeNode *r)const
{
    if(r == NULL)
        return false;
    queue<BinaryTreeNode*>que;
    que.push(r);
    bool result(true);
    bool nullchild(false);
    while(!que.empty())
    {
        BinaryTreeNode *temp=que.front();
        que.pop();
        if(nullchild)
        {
            if(temp->Get_lchild()!=NULL || temp->Get_rchild()!=NULL)
                return false;
        }
        else
        {
            if(temp->Get_lchild()!=NULL && temp->Get_rchild()!=NULL)
            {
                que.push(temp->Get_lchild());
                que.push(temp->Get_rchild());
            }
            else if(temp->Get_lchild()!=NULL && temp->Get_rchild()==NULL)
            {
                que.push(temp->Get_lchild());
                nullchild=true;
            }
            else if(temp->Get_lchild()==NULL && temp->Get_rchild()!=NULL)
                return false;
            else nullchild=true;
        }
    }
    return result;
}

bool BinaryTreeFun::Is_AVL(BinaryTreeNode *r,int &height)const
{
    if(r == NULL)
    {
        height=0;
        return true;
    }
    int lh;
    bool lres=Is_AVL(r->Get_lchild(),lh);
    int rh;
    bool rres=Is_AVL(r->Get_rchild(),rh);
    if(lres && rres && abs(lh-rh)<=1)
    {
        height=max(lh,rh)+1;
        return true;
    }
    else
    {
        height=max(lh,rh)+1;
        return false;
    }
}


int BinaryTreeFun::MostDistance(BinaryTreeNode *r,int &ldis,int &rdis)
{
    if(r == NULL)
    {
        ldis=rdis=0;
        return 0;
    }
    int maxll,maxlr,maxrl,maxrr;
    int maxldis,maxrdis;
    if(r->Get_lchild()!=NULL)
    {
        maxldis=MostDistance(r->Get_lchild(),maxll,maxlr);
        ldis=max(maxll,maxlr)+1;
    }
    else
        maxldis=ldis=0;
    if(r->Get_rchild()!=NULL)
    {
        maxrdis=MostDistance(r->Get_rchild(),maxrl,maxrr);
        rdis=max(maxrl,maxrr)+1;
    }
    else
        maxrdis=rdis=0;
    return max(max(maxldis,maxrdis),ldis+rdis);
}

int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif // LOCAL


    BinaryTreeFun t;

    cout<<"请输入二叉树的前序序列,“#”表示节点为空:"<<endl;
    BinaryTreeNode *tt=t.Createtree();
    t.Set_root(tt);
    cout<<endl<<endl;

    int l,r;
    int dis=t.MostDistance(tt,l,r);
    cout<<"最大距离为:"<<dis<<endl<<endl;

    BinaryTreeNode *p1=t.Get_root()->Get_rchild()->Get_lchild();
    BinaryTreeNode *p2=t.Get_root()->Get_rchild()->Get_rchild();

    BinaryTreeNode *temp=t.GetCommentParent(t.Get_root(),p1,p2);

    cout<<p1->Get_data()<<"和"<<p2->Get_data()<<"的最近公共祖先是:"<<temp->Get_data()<<endl<<endl;

    int h;
    bool ch=t.Is_AVL(tt,h);
    if(ch) cout<<"该二叉树是平衡二叉树"<<endl<<endl;
    else cout<<"该二叉树不是平衡二叉树"<<endl<<endl;
    cout<<"深度为:"<<h<<endl<<endl;

    cout<<"前序遍历的结果:";
    t.Preorder(tt);
    cout<<endl<<endl;

    cout<<"中序遍历的结果:";
    t.Inorder(tt);
    cout<<endl<<endl;

    cout<<"后序遍历的结果:";
    t.Postorder(tt);
    cout<<endl<<endl;

    cout<<"层次遍历的结果:";
    t.Leveltraversal(tt);
    cout<<endl<<endl;

    cout<<"节点个数为:";
    int num1=t.GetNodeNum(tt);
    cout<<num1<<endl<<endl;

    cout<<"树的深度为:";
    int num2=t.GetDepth(tt);
    cout<<num2<<endl<<endl;

    cout<<"叶子节点个数为:";
    int num3=t.GetLeafNum(tt);
    cout<<num3<<endl<<endl;

    cout<<"输入您要查询的层数:    ";
    int k;
    cin>>k;
    cout<<endl<<"第"<<k<<"层节点个数为:";
    int num4=t.GetKNum(tt,k);
    cout<<num4<<endl<<endl;

    cout<<"二叉树的镜像先序遍历:";
    t.Mirror(tt);
    t.Preorder(tt);
    cout<<endl<<endl;
    cout<<"二叉树的镜像中序遍历:";
    t.Inorder(tt);
    cout<<endl<<endl;
    cout<<"二叉树的镜像后序遍历:";
    t.Postorder(tt);
    cout<<endl<<endl;


    char pos[100],in[100];
    cout<<"输入所要创建的二叉树的后序遍历序列:";
    scanf("%s",pos);
    cout<<"输入所要创建的二叉树的中序遍历序列:";
    scanf("%s",in);
    int len=strlen(pos);
    BinaryTreeNode *tttt=t.Pos_RebuildTree(pos,in,0,len-1,0,len-1);
    cout<<"重建二叉树的前序遍历:";
    t.Preorder(tttt);
    cout<<endl<<endl;


    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值