zoukankan      html  css  js  c++  java
  • 二叉树的所有操作

    #include<iostream>
    #include<stdio.h>
    #include<malloc.h>
    using namespace std;
    #define MaxSize 100
    #define MaxWidth 40
    typedef char ElemType;
    typedef struct Node2
    {
        char data;//数据域        
        struct Node2*lchild,*rchild;//左指针域,右指针域
    }BTNode;
    void CreateBTNode(BTNode *&b,char *str)//由str串创建二叉链
    {
        BTNode *St[MaxSize],*p=NULL;
        int top=-1,k,j=0;
        char ch;
        b=NULL;//建立二叉链初始时为空
        ch=str[j];
        while(ch!='\0')//str未扫描完时循环
        {
            switch(ch)
            {
            case'(':top++;St[top]=p;k=1;break;//为左结点
            case')':top--;break;
            case',':k=2;break;//为右结点
            default:p=(BTNode *)malloc(sizeof(BTNode));
                p->data=ch;
                p->lchild=p->rchild=NULL;
                if(b==NULL)//p指向二叉树的根结点
                    b=p;
                else//已建立二叉树根结点
                {
                    switch(k)
                    {
                    case 1:St[top]->lchild=p;break;
                    case 2:St[top]->rchild=p;break;
                    }
                }
            }
            j++;
            ch=str[j];
        }
    }
    void createbitree(BTNode *&T)//先序产生二叉树
    {
        char ch;
        scanf("%c",&ch);
        if(ch==' ')T=NULL;
        else
        {
            T=(BTNode*)malloc(sizeof(BTNode));
            T->data=ch;
            createbitree(T->lchild);
            createbitree(T->rchild);
        }
    }
    BTNode *CreateBT1(char *pre,char *in,int n)//由先序和中序遍历序列构造二叉树
    {
        BTNode *s;
        char *p;
        int k;
        if(n<=0)return NULL;
        s=(BTNode *)malloc(sizeof(BTNode));//创建二叉树结点*s
        s->data=*pre;
        for(p=in;p<in+n;p++)//在中序序列中找等于*pre的位置k
            if(*p==*pre)
                break;
            k=p-in;
            s->lchild=CreateBT1(pre+1,in,k);
            s->rchild=CreateBT1(pre+k+1,p+1,n-k-1);
            return s;
    }
    BTNode *CreateBT2(char *post,char *in,int n,int m)//由中序和后序遍历序列构造二叉树
    {
        BTNode *s;
        char *p,*q,*maxp;
        int maxpost,maxin,k;
        if(n<=0)return NULL;
        maxpost=-1;
        for(p=in;p<in+n;p++)//求in的全部字符中在post最右边的那个字符
            for(q=post;q<post+m;q++)//在in中用maxp指向这个字符,用maxin标志它在in中的下标
                if(*p==*q)
                {
                    k=q-post;
                    if(k>maxpost)
                    {
                        maxpost=k;
                        maxp=p;
                        maxin=p-in;
                    }
                }
        s=(BTNode *)malloc(sizeof(BTNode));//创建二叉树结点*s
        s->data=post[maxpost];
        s->lchild=CreateBT2(post,in,maxin,m);
        s->rchild=CreateBT2(post,maxp+1,n-maxin-1,m);
        return s;
    }
    void DispLeaf(BTNode *b)
    //输出一颗给二叉树放入所有叶子结点
    {
        if(b!=NULL)
        {
            if(b->lchild==NULL&&b->rchild==NULL)
                printf("%c",b->data);
            else
            {
                DispLeaf(b->lchild);
                DispLeaf(b->rchild);
            }
        }
    }
    BTNode*InsertLeftNode(BTNode *p,char x)//左结点插入
    {
        BTNode *s,*t;
        if(p==NULL)
            return NULL;
        t=p->lchild;
        s=(BTNode*)malloc(sizeof(BTNode));
        s->data=x;
        s->lchild=t;
        s->rchild=NULL;
        p->lchild=s;
        return p->lchild;
    }
    BTNode*InsertRightNode(BTNode *p,char x)//右结点插入   
    {
        BTNode *s,*t;
        if(p==NULL)
            return NULL;
        t=p->rchild;
        s=(BTNode*)malloc(sizeof(BTNode));
        s->data=x;
        s->rchild=t;
        s->lchild=NULL;
        p->rchild=s;
        return p->rchild;
    }
    BTNode *DleteLeaftTree(BTNode *p)//删除左结点
    {
        BTNode *q;
        if(p==NULL||p->lchild==NULL)
            return NULL;
        q=p->lchild;
        p->lchild=NULL;
        free(q);
        q=NULL;
        return p;
    }
    BTNode *DleteRightTree(BTNode *p)//删除右结点
    {
        BTNode *q;
        if(p==NULL||p->rchild==NULL)
            return NULL;
        q=p->rchild;
        p->rchild=NULL;
        free(q);
        q=NULL;                                                                                                                                                                                                        
        return p;
    }
    BTNode *SearchNode(BTNode *b,char x)//查找结点
    {
        BTNode *p;
        if(b==NULL)
            return NULL;
        else if (b->data==x) return b;
        else
        {
            p=SearchNode(b->lchild,x);
            if(p!=NULL)
                return p;
            else
                return SearchNode(b->rchild,x);
        }
    }
    BTNode *lchildNode(BTNode *p)//查找左子树结点
    {
        return p->lchild;
    }
    BTNode *RchildNode(BTNode *p)//查找右子树结点
    {
        return p->rchild;
    }
    int BiTreeDepth(BTNode *b)//求高度
    {
        int lchilddep,rchilddep;
        if(b==NULL)return 0;
        else
        {
            lchilddep=BiTreeDepth(b->lchild);
            rchilddep=BiTreeDepth(b->rchild);
            return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);
        }
    }
    void DispBiTree(BTNode *b)//输出二叉树
    {
        if(b!=NULL)
        {
            printf("%c",b->data);
            if(b->lchild!=NULL||b->rchild!=NULL)
            {
                printf("(");
                DispBiTree(b->lchild);
                if(b->rchild!=NULL)
                {
                    printf(",");
                    DispBiTree(b->rchild);
                }
                printf(")");
            }
        }
    }
    void DispBTNode1(BTNode *b)//以凹入表示法输出一颗二叉树
    {
        BTNode *St[MaxSize],*p;
        int level[MaxSize][2],top=-1,n,i,width=4;
        char type;
        if(b!=NULL)
        {
            top++;
            St[top]=b;//根结点入栈
            level[top][0]=width;
            level[top][1]=2;//2表示是根
            while(top>-1)
            {
                p=St[top];//退桟并凹入显示该结点值
                n=level[top][0];
                switch(level[top][1])
                {
                case 0:type='L';break;//左结点之后输出(L)
                case 1:type='R';break;//右结点之后输出(R)
                case 2:type='B';break;//根结点之后输出(B)
                }
                for(i=1;i<=n;i++)//其中n为显示场宽,字符以右对齐显示
                    printf(" ");
                printf("%c(%c)",p->data,type);
                for(i=n+1;i<=MaxWidth;i+=2)
                    printf("--");
                printf("\n");
                top--;
                if(p->rchild!=NULL)
                {
                    top++;//将右子树根结点入栈
                    St[top]=p->rchild;
                    level[top][0]=n+width;//显示场宽增width
                    level[top][1]=1;//1表示是右子树
                }
                if(p->lchild!=NULL)
                {
                    top++;//将左子树根结点入栈
                    St[top]=p->lchild;
                    level[top][0]=n+width;//显示场宽增width
                    level[top][1]=0;//0表示是左子树
                }
            }
        }
    }
    void PreOrder(BTNode *p)//先序遍历二叉树
    {
        if(p!=NULL)
        {
            printf("%c",p->data);
            PreOrder(p->lchild);
            PreOrder(p->rchild);
        }
    }
    void PreOrder1(BTNode *b)//先序遍历的非递归算法
    {
        BTNode *St[MaxSize],*p;
        int top=-1;
        if(b!=NULL)
        {
            top++;//根结点入栈
            St[top]=b;
            while(top>-1)//桟不为空时循环
            {
                p=St[top];//退桟并访问该结点
                top--;
                printf(" %c ",p->data);
                if(p->rchild!=NULL)//右孩子入桟
                {
                    top++;
                    St[top]=p->rchild;
                }
                if(p->lchild!=NULL)//左孩子入桟
                {
                    top++;
                    St[top]=p->lchild;
                }
            }
            printf("\n");
        }
    }
    void InOrder(BTNode *p)//中序遍历二叉树
    {
        if(p!=NULL)
        {
            InOrder(p->lchild);
            printf("%c",p->data);
            InOrder(p->rchild);
        }
    }
    void InOrder1(BTNode *b)//中序遍历的非递归算法
    {
        BTNode *St[MaxSize],*p;
        int top=-1;
        if(b!=NULL)
        {
            p=b;
            while(top>-1||p!=NULL)
            {
                while(p!=NULL)
                {
                    top++;
                    St[top]=p;
                    p=p->lchild;
                }
                if(top>-1)
                {
                    p=St[top];
                    top--;
                    printf(" %c ",p->data);
                    p=p->rchild;
                }
            }
            printf("\n");
        }
    }
    void PostOrder(BTNode *p)//后序遍历二叉树
    {
        if(p!=NULL)
        {
            PostOrder(p->lchild);
            PostOrder(p->rchild);
            printf("%c",p->data);
        }
    }
    void PostOrder1(BTNode *b)//后序遍历的非递归算法
    {
        BTNode *St[MaxSize],*p;
        int flag,top=-1;//桟指针初值
        if(b!=NULL)
        {
            do
            {
                while(b!=NULL)//将b的所有左结点入桟
                {
                    top++;
                    St[top]=b;
                    b=b->lchild;
                }
                p=NULL;//p指向当前结点的前一个访问的结点
                flag=1;//设置b的访问标记为已访问过
                while(top!=-1&&flag)
                {
                    b=St[top];//取出当前的桟顶元素
                    if(b->rchild==p)//右子树不存在或已被访问,访问之
                    {
                        printf(" %c ",b->data);//访问*b结点
                        top--;
                        p=b;//p指向刚被访问的结点
                    }
                    else
                    {
                        b=b->rchild;//指向右子树
                        flag=0;//设置未被访问的标记
                    }
                }
            }while(top!=-1);
            printf("\n");
        }
    }
    void TravLevel(BTNode *b)//层次遍历
    {
        BTNode *Qu[MaxSize];//定义顺序循环队列
        int front,rear;//定义队首和队尾指针
        front=rear=0;//置队列为空队列
        if(b!=NULL)
            printf(" %c ",b->data);
        rear++;//结点指针进入队列
        Qu[rear]=b;
        while(rear!=front)//队列不为空
        {
            front=(front+1)%MaxSize;
            b=Qu[front];
            if(b->lchild!=NULL)//队头出队列
            {
                printf(" %c ",b->lchild->data);//输出左孩子,并入队列
                rear=(rear+1)%MaxSize;
                Qu[rear]=b->lchild;
            }
            if(b->rchild!=NULL)//输出右孩子,并入队列
            {
                printf(" %c ",b->rchild->data);
                rear=(rear+1)%MaxSize;
                Qu[rear]=b->rchild;
            }
        }
        printf("\n");
    }
    void InTongji(BTNode *t,int &m,int &n)//中序遍历的方法求叶子结点的个数
    {
        if(t!=NULL)
        {
            InTongji(t->lchild,m,n);
            printf("%c",t->data);
            m++;//结点计数
            if((t->lchild==NULL)&&(t->rchild==NULL))
                n++;//叶子结点计数
            InTongji(t->rchild,m,n);
        }
    }
    int CountLeaf(BTNode *T)//返回二叉树所有叶子结点个数
    {
        int m,n;
        if(!T)return 0;
        if(!T->lchild&&!T->rchild)return 1;
        else
        {
            m=CountLeaf(T->lchild);
            n=CountLeaf(T->rchild);
            return m+n;
        }
    }
    int Count(BTNode *T)//返回二叉树所有结点个数
    {
        int m,n;
        if(!T)
            return 0;
        //if(!T->lchild&&!T->rchild)return 1;
        else
        {
            m=Count(T->lchild);
            n=Count(T->rchild);
            return m+n+1;
        }
    }
    BTNode *GetTreeNode(char item,BTNode*lptr,BTNode *rptr)
    //其数据域为item,左指针域为lptr,右指针域为rptr
    {
        BTNode *T;
        T=new BTNode;
        T->data=item;
        T->lchild=lptr;
        T->rchild=rptr;
        return T;
    }
    BTNode *CopyTree(BTNode *T)
    {
        BTNode *newlptr,*newrptr,*newT;
        if(!T)return NULL;
        if(T->lchild)
            newlptr=CopyTree(T->lchild);//复制左子树
        else
            newlptr=NULL;
        if(T->rchild)
            newrptr=CopyTree(T->rchild);
        else
            newrptr=NULL;
        newT=GetTreeNode(T->data,newlptr,newrptr);//复制右子树
        return newT;
    }
    BTNode*DestoryTree(BTNode *&T)
    {
        if(T==NULL)return 0;
        DestoryTree(T->lchild);
        DestoryTree(T->rchild);
        delete(T);
        T=NULL;
        return 0;
    }
    void output()
    {
        int i;
        for(i=0;i<10;i++)
            printf(" ");
        for(i=0;i<32;i++)
            printf("*");
        printf("\n");
    }
    void mainpp()
    {
        int i;
        output();
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("1.构建一颗二叉树");
        for(i=0;i<10;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("2.先序输出二叉树");
        for(i=0;i<10;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("3.中序输出二叉树");
        for(i=0;i<10;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("4.后序输出二叉树");
        for(i=0;i<10;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("5.层序输出二叉树");
        for(i=0;i<10;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("6.求二叉树的高度");
        for(i=0;i<10;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("7.输出二叉树叶结点");
        for(i=0;i<8;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("8.以括号形式输出所有结点");
        for(i=0;i<2;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("9.输出二叉树所有结点总数");
        for(i=0;i<2;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("10.删除二叉树");
        for(i=0;i<13;i++)printf(" ");printf("*");printf("\n");
        for(i=0;i<10;i++)printf(" ");printf("*    ");
        printf("0.退            出");
        for(i=0;i<8;i++)printf(" ");printf("*");printf("\n");
        output();
    }
    int main()
    {
        int m=0,n=0,k=1,t;
        BTNode*root=NULL;
        mainpp();
        t=0;
        while(k)
        {
            printf("请选择0--10:  ");
            scanf("%d",&m);
            getchar();
            switch(m)
            {
            case 0:return 0;
            case 1:printf("输入字符,构建二叉树:\n");createbitree(root);break;
            case 2:printf("先序输出二叉树各结点:\n");
                printf("递归算法:\n");PreOrder(root);printf("\n");
                printf("非递归算法:\n");PreOrder1(root);printf("\n");break;
            case 3:printf("中序输出二叉树各结点:  ");
                printf("递归算法:\n");InOrder(root);printf("\n");
                printf("非递归算法:\n");InOrder1(root);printf("\n");break;
            case 4:printf("后序输出二叉树各结点:  ");
                   printf("递归算法:\n");PostOrder(root);printf("\n");
                printf("非递归算法:\n");PostOrder1(root);printf("\n");break;
            case 5:printf("层序输出二叉树各结点:\n");
                TravLevel(root);printf("\n");break;
            case 6:t=BiTreeDepth(root);printf("二叉树的高度=%3d\n",t);break;
            case 7:printf("输出一颗给定二叉树的所有叶子结点:");
                DispLeaf(root);
                n=CountLeaf(root);printf("\n叶子结点总数:  n=%3d\n",n);break;
            case 8:printf("以嵌套形式输出所有结点:\n");
                DispBiTree(root);
                printf("\n");
                break;
            case 9:printf("输出二叉树所有结点总数%3d\n",Count(root));
                break;
            case 10:printf("删除二叉树结点");
                DestoryTree(root);
                break;
            default:return 0;
    
            }
            printf("继续运行吗Y(1)/N(0):  ");
            scanf("%d",&k);
            if(!k)return 0;
        }
        return 0;
    }
  • 相关阅读:
    FLASH开发[00]
    slickedit使用小技巧
    网络编程[34]
    网络编程[39]
    网络编程[41]
    网络编程[37]
    网络编程[32]
    网络编程[35]
    Apache安装和配置
    网络编程[40]
  • 原文地址:https://www.cnblogs.com/heqinghui/p/2755249.html
Copyright © 2011-2022 走看看