树的基础算法

本文详细介绍了二叉树的各种操作,包括创建、遍历(先序、中序、后序、层次)以及非递归遍历,还有求树的高度、宽度、公共祖先、完全二叉树判断等算法。此外,还包括了二叉树的构造、节点查找、删除、相似性判断等高级操作。
摘要由CSDN通过智能技术生成
#include<bits/stdc++.h>
using namespace std;

//定义
typedef struct BiNode
{
    char data;
    BiNode *lchild,*rchild;
}BiNode,*BiTree;

//创建
BiNode* Creat()
{
    BiNode *bt;
    char ch;
    cin>>ch;
    if(ch=='#')
    {
        bt=NULL;
    }
    else
    {
        bt=(BiNode*)malloc(sizeof(BiNode));
        bt->data=ch;
        bt->lchild=Creat();
        bt->rchild=Creat();
    }
    return bt;
}

//递归先序遍历
void PreOrder(BiTree bt)
{
    if(bt==NULL)
    {
        return;
    }
    else
    {
        cout<<bt->data<<" ";
        PreOrder(bt->lchild);
        PreOrder(bt->rchild);
    }
}

//递归中序遍历
void InOrder(BiTree bt)
{
    if(bt==NULL)
    {
        return;
    }
    else
    {
        InOrder(bt->lchild);
        cout<<bt->data<<" ";
        InOrder(bt->rchild);
    }
}

//递归后序遍历
void PostOrder(BiTree bt)
{
    if(bt==NULL)
    {
        return;
    }
    else
    {
        PostOrder(bt->lchild);
        PostOrder(bt->rchild);
        cout<<bt->data<<" ";
    }
}

//非递归先序遍历
void PreOrder2(BiTree bt)
{
    BiTree s[100];
    int top=-1;
    BiTree p=bt;
    while(p||top!=-1)
    {
        if(p)
        {
            cout<<p->data<<" ";
            top++;
            s[top]=p;
            p=p->lchild;
        }
        else
        {
            p=s[top];
            top--;
            p=p->rchild;
        }
    }
}

//非递归中序遍历
void InOrder2(BiTree bt)
{
    BiTree s[100];
    int top=-1;
    BiTree p=bt;
    while(p||top!=-1)
    {
        if(p)
        {
            top++;
            s[top]=p;
            p=p->lchild;
        }
        else
        {
            p=s[top];
            top--;
            cout<<p->data<<" ";
            p=p->rchild;
        }
    }
}

//非递归后序遍历
typedef struct
{
    BiTree t;
    int tag;
}sstack; //tag为0表示左子女被访问,tag为1表示右子女被访问
void PostOrder2(BiTree bt)
{
   sstack s[100];
   int top=-1;
   BiTree p=bt;
   while(p||top!=-1)
   {
       if(p)//一路访问左子树并入栈
       {
           top++;
           s[top].t=p;
           s[top].tag=0;
           p=p->lchild;
       }
       if(s[top].tag==0)//若没访问右子树,就去访问右子树并入栈
       {
           s[top].tag=1;
           p=p->rchild;
       }
       else//若访问了右子树,则出栈
       {
           p=s[top].t;
           p--;
           cout<<p->data<<" ";
           p=NULL;
       }
   }
}

//层次遍历
void LevelOrder(BiTree bt)
{
    BiTree q[100];
    int fro=-1,rear=-1;
    BiTree p=bt;
    rear++;
    q[rear]=p;
    while(fro!=rear)
    {
        fro++;
        p=q[fro];
        cout<<p->data<<" ";
        if(p->lchild!=NULL)
        {
            rear++;
            q[rear]=p->lchild;
        }
        if(p->rchild!=NULL)
        {
            rear++;
            q[rear]=p->rchild;
        }

    }
}

//递归求树的高度
int Hight(BiTree bt)
{
    if(bt==NULL)
    {
        return 0;
    }
    int lhight=Hight(bt->lchild);
    int rhight=Hight(bt->rchild);
    if(lhight>rhight)
    {
        return lhight+1;
    }
    else
    {
        return rhight+1;
    }
}

//非递归求树的高度(层次遍历的应用)
void Hight2(BiTree bt)
{
    int fro=-1,rear=-1;
    int last=0,level=0;
    BiTree q[100];
    BiTree p=bt;
    rear++;
    q[rear]=p;
    while(fro!=rear)
    {
        fro++;
        p=q[fro];
        if(p->lchild)
        {
            rear++;
            q[rear]=p->lchild;
        }
        if(p->rchild)
        {
            rear++;
            q[rear]=p->rchild;
        }
        if(fro==last)
        {
            level++;
            last=rear;
        }
    }
    cout<<"高度为"<<level<<endl;
}

//求树的宽度、每层节点的个数(层次遍历的应用)
void Width(BiTree bt)
{
    BiTree q[100];
    int fro=-1,rear=-1;
    BiTree p=bt;
    int level[100];
    rear++;
    q[rear]=p;
    level[rear]=1;
    while(rear!=fro)
    {
        fro++;
        p=q[fro];
        int k=level[fro];
        if(p->lchild)
        {
            rear++;
            q[rear]=p->lchild;
            level[rear]=k+1;
        }
        if(p->rchild)
        {
            rear++;
            q[rear]=p->rchild;
            level[rear]=k+1;
        }
    }
    int k=1,i=0,maxx=0;
    while(i<=rear)
    {
        int n=0;
        while(i<=rear&&level[i]==k)
        {
            i++;
            n++;
        }
        cout<<"第"<<k<<"层有"<<n<<"个节点"<<endl;
        k=level[i];
        if(n>maxx)
            maxx=n;
    }
    cout<<"宽度为"<<maxx<<endl;
}

//判断是否是完全二叉树
bool Iscomplete(BiTree bt)
{
    BiTree q[100];
    int rear=-1,fro=-1;
    BiTree p=bt;
    rear++;
    q[rear]=p;
    while(rear!=fro)
    {
        fro++;
        p=q[fro];
        if(p)
        {
            rear++;
            q[rear]=p->lchild;
            rear++;
            q[rear]=p->rchild;
        }
        else
        {
            while(rear!=fro)
            {
                fro++;
                p=q[fro];
                if(p)
                    return 0;
            }
        }
    }
    return 1;
}

//顺序存储的树找公共祖先
//非递归
int SqFindFather(char T[],int i,int j)
{
    if(T[i]!='#'&&T[j]!='#')
    {
        while(i!=j)
        {
            if(i>j)
            {
                i=i/2;
            }
            else
            {
                j=j/2;
            }
        }
        return T[i];
    }
}
//递归
int SqFindFather2(char T[],int i,int j)
{
    if(i==j)
        return T[i];
    if(i>j)
        SqFindFather2(T,i/2,j);
    else
        SqFindFather2(T,i,j/2);
}

//链式存储寻找公共祖先(后序遍历的应用)
void FindFather(BiTree bt,char a,char b)
{
    BiTree p=bt;
    sstack s[100],s1[100];
    int top=-1;
    while(p||top!=-1)
    {
        if(p)
        {
            top++;
            s[top].t=p;
            s[top].tag=0;
            p=p->lchild;
        }
        int top1;
        while(s[top].tag==1&&top!=-1)
        {
            if(s[top].t->data==a)
            {
                for(int i=0;i<=top;i++)
                {
                    s1[i]=s[i];
                    top1=top;
                }
            }
            if(s[top].t->data==b)
            {
                for(int i=top;i>=0;i--)
                {
                    for(int j=top1;j>=0;j--)
                    {
                        if(s1[j].t==s[i].t)
                        {
                            cout<<s[i].t->data<<endl;
                            break;
                        }
                    }
                }
            }
             top--;
        }
        if(s[top].tag==0)
        {
            s[top].tag=1;
            p=p->rchild;
        }
    }

}

//求值为x的所有祖先
void FindAllFather(BiTree bt,char ch)
{
    sstack s[100];
    int top=-1;
    BiTree p=bt;
    while(p||top!=-1)
    {
        if(p)
        {
            top++;
            s[top].t=p;
            s[top].tag=0;
            p=p->lchild;
        }
        while(top!=-1&&s[top].tag==1)
        {
            if(p->data==ch)
            {
                for(int i=top;i>=0;i++)
                {
                    cout<<s[i].t->data<<" ";
                }
            }
            top--;
        }
        if(top!=-1)
        {
            s[top].tag=1;
            p=s[top].t->rchild;
        }
    }
}


//给先序和中序序列,建树
BiTree PreInCreat(char A[],char B[],int l1,int h1,int l2,int h2)//l1,h1数组A的起始和终止位置
{
    BiTree bt=(BiTree)malloc(sizeof(BiNode));
    bt->data=A[l1];
    int i;
    for(i=l2;i!=bt->data;i++);
    int llen=i-l2;
    int rlen=h2-i;
    if(llen)
    {
        bt->lchild=PreInCreat(A,B,l1+1,l1+llen,l2,l2+llen-1);
    }
    else
    {
        bt->lchild=NULL;
    }
    if(rlen)
    {
        bt->rchild=PreInCreat(A,B,h1-rlen+1,h1,h2-rlen+1,h2);
    }
    else
    {
        bt->rchild=NULL;
    }
    return bt;
}

//求双分支节点个数
int FenzhiNum(BiTree bt)
{
    if(bt==NULL)
        return 0;
    if(bt->lchild!=NULL&&bt->rchild!=NULL)
    {
        return FenzhiNum(bt->lchild)+FenzhiNum(bt->rchild)+1;
    }
    else
    {
        return FenzhiNum(bt->lchild)+FenzhiNum(bt->rchild);
    }
}

//交换所有左右子树
void Swap(BiTree bt)
{
    if(bt)
    {
        Swap(bt->lchild);
        Swap(bt->rchild);
        BiTree temp=bt->lchild;
        bt->lchild=bt->rchild;
        bt->rchild=temp;
    }
}

//前序遍历第k个节点
char Findk(BiTree bt,int i,int k)
{
    if(bt==NULL)
        return -1;
    if(i==k)
    {
        return bt->data;
    }
    i++;
    char ch;
    ch=Findk(bt->lchild,i,k);
    if(ch!='#')
       return ch;
    ch=Findk(bt->rchild,i,k);
    if(ch!='#')
       return ch;
}

//找到所有值为x的节点,删除它和它的子树
void DeleteTree(BiTree &bt)
{
    if(bt)
    {
        DeleteTree(bt->lchild);
        DeleteTree(bt->rchild);
        free(bt);
    }
}
void Findx(BiTree bt,char x)
{
    if(bt)
    {
        if(bt->data==x)
        {
            DeleteTree(bt);
        }
        Findx(bt->lchild,x);
        Findx(bt->rchild,x);
    }
}

//判断两树相似
int Similar(BiTree a,BiTree b)
{
    if(a==NULL&&b==NULL)
    {
        return 1;
    }
    else if(a==NULL||b==NULL)
    {
        return 0;
    }
    else
    {
        int lefts=Similar(a->lchild,b->lchild);
        int rights=Similar(a->rchild,b->rchild);
        return lefts&&rights;
    }
}

int main()
{
    BiTree bt;
    bt=Creat();
    PreOrder(bt);
    cout<<endl;
    InOrder(bt);
    cout<<endl;
    PostOrder(bt);
    cout<<endl;
    PreOrder2(bt);
    cout<<endl;
    InOrder2(bt);
    cout<<endl;
    PostOrder(bt);
    cout<<endl;
    LevelOrder(bt);
    cout<<endl;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值