数据结构之树的基本操作

目录

0.功能

1.预处理区

2.函数声明区

3.以先序遍历的原则输入树

4.求树的的全部节点

5.给顺序队列开辟空间

6.入队列

7.判断队列

8.退队列

9.获取队首元素

10.层序遍历的原则输出树(前面队列为层序遍历做准备)

11.以先序遍历的原则输入树

12 按照后序遍历的原则遍历树

13 按照先序遍历法遍历树

14 按照中序遍历的原则遍历

15 清空树

16 对树判空

17 如果二叉树存在,返回根结点的值

18 查找一个结点,是否存在

19 二叉树存在,e是T中某个结点,结点e赋值为value

20 若e是T的非根结点,则返回她的双亲,否则返回

21 返回左右孩子,若e无左右孩子就返回空

22 功能区

23 求树的深度

24 返回e的左兄弟,若e是T的左孩子或左孩子不存在,则返回“空

25 返回e的右兄弟,若e是T的右孩子或右孩子不存在,则返回“空

26 开辟c空间

27 根据LR为0或者1,插入c为T中p所指向结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树

28 摧毁二叉树

29 根据LR为0或1,删除T中p所指结点的左或右结点

30 求叶子结点个数

31 度数为2的结点个数

32 度数为1的结点个数

33 switch

34 全部代码


0.功能

    printf("0.退出\n");
    printf("1.建立一个树\n");
    printf("2.使用后序遍历法遍历\n");
    printf("3.使用先序遍历法遍历\n");
    printf("4.使用中序遍历法遍历\n");
    printf("5.清空这个树\n");
    printf("6.对这个树进行判空\n");
    printf("7.求这个树的深度\n");
    printf("8.求这个树的根结点\n");
    printf("9.查找元素,看是否存在\n");
    printf("10.二叉树存在,e是T中某个结点,结点e赋值为value\n");
    printf("11.若e是T的非根结点,则返回她的双亲,否则返回\n");
    printf("12.返回左孩子,若e无左孩子就返回空\n");
    printf("13.返回右孩子,若e无右孩子就返回空\n");
    printf("14.返回e的左兄弟,若e是T的左孩子或左孩子不存在,则返回“空\n");
    printf("15.返回e的右兄弟,若e是T的右孩子或右孩子不存在,则返回“空\n");
    printf("16.根据LR为0或者1,插入c为T中p所指向结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树\n");
    printf("17.摧毁二叉树\n");
    printf("18.根据LR为0或1,删除T中p所指结点的左或右结点\n");
    printf("19.求叶子结点的个数\n");
    printf("20.求度数为2的结点个数\n");
    printf("21.求度数为1的结点个数\n");
    printf("22.层序遍历\n");

1.预处理区

//define区
#define OK 1
#define ERROR 0
#define OVERFLOW -1

//typedef
typedef struct BiTNode{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef struct
{
    BiTree *base;  //基地址
    int front;  //对头
    int rear;   //队尾
    int maxsize;    //这个队中最大的可以容纳的空间
}SqQueue;

//include
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

2.函数声明区

//函数区
int  CreatTree(BiTree &T);          //以先序遍历的原则输入树
void LRDTree(BiTree T);             //按照后序遍历法遍历树
void DLRTree(BiTree T);             //按照先序遍历法遍历树
void LDRTree(BiTree T);             //按照后序遍历法遍历树
void ClearTree(BiTree &T);          //清空这个树
void TreeEmpty(BiTree T);           //对树进行判空
void Root(BiTree T);                //如果二叉树存在,返回根结点的值
BiTree FindTree(BiTree T,char e);   //查找一个结点,是否存在
int Assign(BiTree T,char &e,char value);//二叉树存在,e是T中某个结点,结点e赋值为value
BiTree Parent(BiTree T,char e);     //若e是T的非根结点,则返回她的双亲,否则返回
BiTree LReftTree(BiTree T,char e);  //返回左右孩子,若e无左右孩子就返回空
void pro();                         //功能区
int DeepthTree(BiTree T);           //求树的深度
BiTree LeftSibling(BiTree T,char e);//返回e的左兄弟,若e是T的左孩子或左孩子不存在,则返回“空
BiTree RightSibling(BiTree T,char e);//返回e的右兄弟,若e是T的右孩子或右孩子不存在,则返回“空
void CreatC(BiTree &c);             //开辟c空间
void InsertChild(BiTree &T,BiTree c,int LR,char e);//根据LR为0或者1,插入c为T中p所指向结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树
void DestoryTree(BiTree &T);        //摧毁二叉树
void DeleteChild(BiTree T,char e,int LR);//根据LR为0或1,删除T中p所指结点的左或右结点
int LeaveSum(BiTree T);             //求叶子结点个数
int D2Sum(BiTree T);                //度数为2的结点个数
int D1Sum(BiTree T);                //度数为1的结点个数
void swi(BiTree T);                 //switch
void CengXu(BiTree T);              //层序遍历的原则输出树
void InitQueue(SqQueue &Q,BiTree T);//顺序队列开辟
void EnQueue(SqQueue &Q,BiTree T);  //入队列
int IsEmptyQueue(SqQueue Q);        //判队列空
void DeQueue(SqQueue &Q);           //退队列
BiTree GetFront(SqQueue Q);         //获取队首元素

3.以先序遍历的原则输入树

//以先序遍历的原则输入树
int  CreatTree(BiTree &T)
{
    char node;
    scanf("%c,",&node);
    if(node=='#')
    {
        T=NULL;
    }else{
        if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))
            printf("树的储存空间开发失败\n");
        T->data=node;
        CreatTree(T->lchild);
        CreatTree(T->rchild);
    }
    return OK;
}

4.求树的的全部节点

//求树中全部结点
int MAX(BiTree T)
{
    int zero,one,two,shum;
    zero=LeaveSum(T);
    one=D1Sum(T);
    two=D2Sum(T);
    shum=zero+one+two;
    return shum;

}

//求叶子结点个数
int LeaveSum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if(T->lchild==NULL&&T->rchild==NULL)
            n=n+1;
        int l=LeaveSum(T->lchild);
        int r=LeaveSum(T->rchild);
        return n+l+r;
    }
}

//度数为2的结点个数
int D2Sum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if(T->lchild!=NULL&&T->rchild!=NULL)
            n=n+1;
        int l=D2Sum(T->lchild);
        int r=D2Sum(T->rchild);
        return n+l+r;
    }
}

//度数为1的结点个数
int D1Sum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if((T->lchild==NULL&&T->rchild!=NULL)||(T->lchild!=NULL&&T->rchild==NULL))
            n=n+1;
        int l=D1Sum(T->lchild);
        int r=D1Sum(T->rchild);
        return n+l+r;
    }
}

5.给顺序队列开辟空间

//顺序队列开辟
void InitQueue(SqQueue &Q,BiTree T)
{
    int MAXSIZE;
    MAXSIZE=MAX(T)+1;
    Q.base = (BiTree *)malloc(MAXSIZE * sizeof(BiTree));
    if(!Q.base)
        printf("Q->base内存分配失败\n");
    Q.front = Q.rear =0;
    Q.maxsize=MAXSIZE;
    printf("顺序队列开辟完成\n");
}

6.入队列

//入队列
void EnQueue(SqQueue &Q,BiTree T)
{
    if((Q.rear+1)%Q.maxsize==Q.front)
        printf("队列空间满\n");
    else{
        Q.base[Q.rear]=T;
        Q.rear = (Q.rear+1)%Q.maxsize;
    }
}

7.判断队列

//判队列空
int IsEmptyQueue(SqQueue Q)
{
    if(Q.front==Q.rear)
        return 0;
    else 
        return 1;
}

8.退队列

//退队列
void DeQueue(SqQueue &Q)
{   
    int e;
    BiTree T;
    T=Q.base[Q.front];
    Q.front=(Q.front+1)%Q.maxsize;
}

9.获取队首元素

//获取队首元素
BiTree GetFront(SqQueue Q)
{
    return Q.base[Q.front];
}

10.层序遍历的原则输出树(前面队列为层序遍历做准备)

void CengXu(BiTree T)
{
    SqQueue Q;
    InitQueue(Q,T);
    BiTree s;
    s=T;
    EnQueue(Q,s);
    while(IsEmptyQueue(Q))
    {
        s=GetFront(Q);
        printf("%c ",s->data);
        if(s->lchild!=NULL)
        {
            EnQueue(Q,s->lchild);
        }
        if(s->rchild!=NULL)
        {
            EnQueue(Q,s->rchild);
        }
        DeQueue(Q);
    }
}

11.以先序遍历的原则输入树

int  CreatTree(BiTree &T)
{
    char node;
    scanf("%c,",&node);
    if(node=='#')
    {
        T=NULL;
    }else{
        if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))
            printf("树的储存空间开发失败\n");
        T->data=node;
        CreatTree(T->lchild);
        CreatTree(T->rchild);
    }
    return OK;
}

12 按照后序遍历的原则遍历树

void LRDTree(BiTree T)
{
    if(T!=NULL)
    {

        LRDTree(T->lchild);
        LRDTree(T->rchild);
        printf("%c ",T->data);
    }
}

13 按照先序遍历法遍历树

void DLRTree(BiTree T)
{
   if(T!=NULL)
   {printf("%c ",T->data);
    DLRTree(T->lchild);
    DLRTree(T->rchild);
   }
  
}

14 按照中序遍历的原则遍历

void LDRTree(BiTree T)
{
    if(T!=NULL)
    {
        LDRTree(T->lchild);
        printf("%c ",T->data);
        LDRTree(T->rchild);
    }
}

15 清空树

//清空这个树
void ClearTree(BiTree &T)
{
    if(T!=NULL)
    {
        ClearTree(T->lchild);
        ClearTree(T->rchild);
        free(T);
        T=NULL;
    }
}

16 对树判空

//对树进行判空
void TreeEmpty(BiTree T)
{
    if(T==NULL)
    {
        printf("这个二叉树为空二叉树\n");
    }else{
        printf("这个二叉树不为空二叉树\n");
    }
}

17 如果二叉树存在,返回根结点的值

void Root(BiTree T)
{
    if(T==NULL)
    {
        printf("这个树为空树,不存在根\n");
    }else{
        printf("这个树的根结点是:%c\n",T->data);
    }
}

18 查找一个结点,是否存在

BiTree FindTree(BiTree T,char e)
{
    if(T->data==e)
        return T;
    BiTree p;
    p=NULL;
    if(T->lchild!=NULL)
        p=FindTree(T->lchild,e);
    if(p!=NULL)
        return p;
    if(T->rchild!=NULL)
        p=FindTree(T->rchild,e);
    if(p!=NULL)
        return p;
}

19 二叉树存在,e是T中某个结点,结点e赋值为value

int Assign(BiTree T,char &e,char value)
{
    BiTree o=NULL;
    o=FindTree(T,e);
    if(o!=NULL)
    {
        o->data=value;
        printf("替换赋值操作已经完成\n");
    }else{
        printf("没有找到这个值\n");
    }
}

20 若e是T的非根结点,则返回她的双亲,否则返回

BiTree Parent(BiTree T,char e)
{
    BiTree p;
    if(T!=NULL)
    {
        if(T->data==e)
        {
            p=NULL;
            return p;
        }else if(T->lchild!=NULL&&T->lchild->data==e){
            p=T;
            return p;
        }else if(T->rchild!=NULL&&T->rchild->data==e){
            p=T;
            return p;
        }else
            p=Parent(T->lchild,e);
            if(p!=NULL){
                return p;}
            else{
                p=Parent(T->rchild,e);
                return p;
            }
    }else{
        p=T;
        return p;
    }
}

21 返回左右孩子,若e无左右孩子就返回空

BiTree LReftTree(BiTree T,char e)
{
    BiTree p;
    p=FindTree(T,e);
    if(p!=NULL)
    {
        return p;
    }else{
        return p;
    }
}

22 功能区

void pro()
{
    printf("0.退出\n");
    printf("1.建立一个树\n");
    printf("2.使用后序遍历法遍历\n");
    printf("3.使用先序遍历法遍历\n");
    printf("4.使用中序遍历法遍历\n");
    printf("5.清空这个树\n");
    printf("6.对这个树进行判空\n");
    printf("7.求这个树的深度\n");
    printf("8.求这个树的根结点\n");
    printf("9.查找元素,看是否存在\n");
    printf("10.二叉树存在,e是T中某个结点,结点e赋值为value\n");
    printf("11.若e是T的非根结点,则返回她的双亲,否则返回\n");
    printf("12.返回左孩子,若e无左孩子就返回空\n");
    printf("13.返回右孩子,若e无右孩子就返回空\n");
    printf("14.返回e的左兄弟,若e是T的左孩子或左孩子不存在,则返回“空\n");
    printf("15.返回e的右兄弟,若e是T的右孩子或右孩子不存在,则返回“空\n");
    printf("16.根据LR为0或者1,插入c为T中p所指向结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树\n");
    printf("17.摧毁二叉树\n");
    printf("18.根据LR为0或1,删除T中p所指结点的左或右结点\n");
    printf("19.求叶子结点的个数\n");
    printf("20.求度数为2的结点个数\n");
    printf("21.求度数为1的结点个数\n");
    printf("22.层序遍历\n");
}

23 求树的深度

//求树的深度
int DeepthTree(BiTree T)
{
    if(!T)
        return 0;
    else{
        int leftdeepth,rightdeepth;
        leftdeepth = DeepthTree(T->lchild);
        rightdeepth = DeepthTree(T->rchild);
        return 1+(leftdeepth>rightdeepth?leftdeepth:rightdeepth);
    }
}

24 返回e的左兄弟,若e是T的左孩子或左孩子不存在,则返回“空

BiTree LeftSibling(BiTree T,char e)
{
    BiTree p;
    p = Parent(T,e);
    if(p->lchild->data==e||p->lchild==NULL)
    {
        p=NULL;
        return p;
    }else if(p->lchild->data!=e&&p->lchild!=NULL)
    {
        return p;
    }
}

25 返回e的右兄弟,若e是T的右孩子或右孩子不存在,则返回“空

BiTree RightSibling(BiTree T,char e)
{
    BiTree p;
    p=Parent(T,e);
    if(p->rchild->data==e||p->rchild==NULL)
    {
        p=NULL;
        return p;
    }else if(p->rchild->data!=e&&p->rchild!=NULL)
    {
        return p;
    }
}

26 开辟c空间

void CreatC(BiTree &c)
{
    c=(BiTNode *)malloc(sizeof(BiTNode));
    c->lchild=NULL;
    c->rchild=NULL;
    printf("请输入C结点中的值:");
    scanf("%c",&c->data);
    getchar();
}

27 根据LR为0或者1,插入c为T中p所指向结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树

void InsertChild(BiTree &T,BiTree c,int LR,char e)
{
    BiTree q;
    BiTree t;
    q=NULL;
    if(LR==0)
    {
        q=FindTree(T,e);
        t=q->lchild;
        q->lchild=c;
        c->rchild=t;
    }else if(LR==1)
    {
        q=FindTree(T,e);
        t=q->rchild;
        q->rchild=c;
        c->rchild=t;
    }

}

28 摧毁二叉树

void DestoryTree(BiTree &T)
{
    if(T!=NULL)
    {
        DestoryTree(T->lchild);
        DestoryTree(T->rchild);
        free(T);
        T=NULL;
    }
}

29 根据LR为0或1,删除T中p所指结点的左或右结点

void DeleteChild(BiTree T,char e,int LR)
{
    BiTree p;
    p=FindTree(T,e);
    if(LR==0)
    {
        if(p->lchild==NULL&&p->rchild==NULL)
        {
            free(p);
            p->lchild=NULL;
            p->rchild=NULL;
        }
    }
    
}

30 求叶子结点个数

int LeaveSum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if(T->lchild==NULL&&T->rchild==NULL)
            n=n+1;
        int l=LeaveSum(T->lchild);
        int r=LeaveSum(T->rchild);
        return n+l+r;
    }
}

31 度数为2的结点个数

int D2Sum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if(T->lchild!=NULL&&T->rchild!=NULL)
            n=n+1;
        int l=D2Sum(T->lchild);
        int r=D2Sum(T->rchild);
        return n+l+r;
    }
}

32 度数为1的结点个数

int D1Sum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if((T->lchild==NULL&&T->rchild!=NULL)||(T->lchild!=NULL&&T->rchild==NULL))
            n=n+1;
        int l=D1Sum(T->lchild);
        int r=D1Sum(T->rchild);
        return n+l+r;
    }
}

33 switch

void swi(BiTree T)
{
    int num;
    pro();
    printf("请输入功能数字:");
    scanf("%d",&num);
    getchar();
    while(num)
    {
        switch(num)
        {
            case 0:
                num=0;
                break;
            case 1:
                printf("请输入树内元素:");
                CreatTree(T);
                printf("元素输入操作已经完成\n");
            break;
            case 2:
                if(T==NULL)
                {
                    printf("在执行操作二之前需要执行操作一\n");
                }else{
                    LRDTree(T);
                }
            break;
            case 3:
                if(T==NULL)
                {
                    printf("在执行操作三之前需要执行操作一\n");
                }else{            
                    DLRTree(T);
                    }
            break;
            case 4:
                if(T==NULL)
                {
                    printf("在执行操作四之前需要执行操作一\n");
                }else{            
                    LDRTree(T);
                }
            break;
            case 5:
                if(T==NULL)
                {
                    printf("在执行操作五之前需要执行操作一\n");
                }else{  
                    ClearTree(T);
                }
            break;
            case 6:
                if(T==NULL)
                {
                    printf("在执行操作六之前需要执行操作一\n");
                }else{  
                    TreeEmpty(T);
                }
            break;
            case 7:
                if(T==NULL)
                {
                    printf("在执行操作七之前需要执行操作一\n");
                }else{  
                    int deepth;
                    deepth=DeepthTree(T);
                    printf("这个树的深度是:%d\n",deepth);
                }
            break;
            case 8:
                if(T==NULL)
                {
                    printf("在执行操作八之前需要执行操作一\n");
                }else{  
                    Root(T);
                    }
            break;
            case 9:
                if(T==NULL)
                {
                    printf("在执行操作九之前需要执行操作一\n");
                }else{
                    printf("请输入需要查找的元素:");
                    int e;
                    scanf("%c",&e);
                    BiTree t = FindTree(T,e);
                    if(t!=NULL)
                        printf("您所查找的%c存在\n",e);
                    else
                        printf("您所查找的%c不存在\n",e);
                }
            break;
            case 10:
                if(T==NULL)
                {
                    printf("在执行操作十之前需要执行操作一\n");
                }else{  
                    char s,value;
                    printf("请输入需要搜索(被替换)的结点:");
                    scanf("%c",&s);
                    getchar();
                    printf("请输入要换成的值:");
                    scanf("%c",&value);
                    Assign(T,s,value);
                    }
            break;
            case 11:
                if(T==NULL)
                {
                    printf("在执行操作十一之前需要执行操作一\n");
                }else{  
                    char a;
                    printf("请输入想要求什么元素的双亲\n");
                    scanf("%c",&a);
                    getchar();
                    BiTree q;
                    q=Parent(T,a);
                    if(q!=NULL)
                        printf("%c的双亲是%c\n",a,q->data);
                    else
                        printf("不存在双亲\n");
                        }
            break;
            case 12:
                if(T==NULL)
                {
                    printf("在执行操作十二之前需要执行操作一\n");
                }else{  
                    char b;
                    printf("请输入想要查找哪个元素的左孩子:");
                    scanf("%c",&b);
                    getchar();
                    BiTree x;
                    x=LReftTree(T,b);
                    if(x!=NULL)
                    {   if(x->lchild!=NULL)
                            printf("左孩子是%c\n",x->lchild->data);
                        else
                            printf("这个元素没有左孩子\n");
                    }else{
                        printf("这个元素不存在\n");
                    }
                    }
            break;            
            case 13:
                if(T==NULL)
                {
                    printf("在执行操作十三之前需要执行操作一\n");
                }else{  
                    char z;
                    printf("请输入想要查找哪个元素的右孩子:");
                    scanf("%c",&z);
                    getchar();
                    BiTree X;
                    X=LReftTree(T,z);
                    if(X!=NULL)
                    {   if(X->rchild!=NULL)
                            printf("右孩子是%c\n",X->rchild->data);
                        else
                            printf("这个元素没有右孩子\n");
                    }else{
                        printf("这个元素不存在\n");
                    }
                    }
            break;
            case 14:
                if(T==NULL)
                {
                    printf("在执行操作十四之前需要执行操作一\n");
                }else{  
                    char xx;
                    printf("请输入你想要查找什么元素的左兄弟\n");
                    scanf("%c",&xx);
                    getchar();
                    BiTree Xx;
                    Xx=LeftSibling(T,xx);
                    if(Xx!=NULL)
                    {
                        printf("%c的左兄弟是%c\n",xx,Xx->lchild->data);
                    }else{
                        printf("%c没有左兄弟",xx);
                    }
                }
            break;
            case 15:
                if(T==NULL)
                {
                    printf("在执行操作十五之前需要执行操作一\n");
                }else{  
                    char yy;
                    printf("请输入你想要查找什么元素的右兄弟\n");
                    scanf("%c",&yy);
                    getchar();
                    BiTree Xy;
                    Xy=RightSibling(T,yy);
                    if(Xy!=NULL)
                    {
                        printf("%c的右兄弟是%c\n",yy,Xy->rchild->data);
                    }else{
                        printf("%c没有右兄弟",yy);
                    }
                }
            break;
            case 16:
                if(T==NULL)
                {
                    printf("在执行操作十六之前需要执行操作一\n");
                }else{  
                    BiTree c;
                    char pp;
                    int LR;//L左R右
                    CreatC(c);
                    printf("请输入想要插入的元素的结点:");
                    scanf("%c",&pp);
                    printf("请输入LR:");
                    scanf("%d",&LR);
                    InsertChild(T,c,LR,pp);
                    printf("插入完成\n");
                }
            break;
            case 17:
                if(T==NULL)
                {
                    printf("在执行操作十七之前需要执行操作一\n");
                }else{  
                    DestoryTree(T);
                    printf("摧毁二叉树操作完成\n");
                }
            break;
            case 18:
                if(T==NULL)
                {
                    printf("在执行操作十八之前需要执行操作一\n");
                }else{  
                    printf("还未完成\n");
                }
            break;
            case 19:
                if(T==NULL)
                {
                    printf("在执行操作十九之前需要执行操作一\n");
                }else{  
                    int n;
                    n=LeaveSum(T);
                    printf("叶子结点个数是%d",n);
                    }
            break;
            case 20:
                if(T==NULL)
                {
                    printf("在执行操作二十之前需要执行操作一\n");
                }else{  
                    int l;
                    l=D2Sum(T);
                    printf("度数为2的结点为%d",l);
                    }
            break;
            case 21:
                if(T==NULL)
                {
                    printf("在执行操作二十一之前需要执行操作一\n");
                }else{  
                    int nn;
                    nn=D1Sum(T);
                    printf("度数为1的结点为%d",nn);
                }
            break;
            case 22:
                if(T==NULL)
                {
                    printf("在执行操作二十二之前需要执行操作一\n");
                }else{
                    CengXu(T);
                }
            break;
            default:
                printf("输入有误,请重新输入\n");
        }
        printf("\n\n\n");
        pro();
        printf("请输入功能数字:");
        scanf("%d",&num);
        getchar();
    }
}

34 全部代码

//define区
#define OK 1
#define ERROR 0
#define OVERFLOW -1

//typedef
typedef struct BiTNode{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef struct
{
    BiTree *base;  //基地址
    int front;  //对头
    int rear;   //队尾
    int maxsize;    //这个队中最大的可以容纳的空间
}SqQueue;

//include
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

//函数区
int  CreatTree(BiTree &T);          //以先序遍历的原则输入树
void LRDTree(BiTree T);             //按照后序遍历法遍历树
void DLRTree(BiTree T);             //按照先序遍历法遍历树
void LDRTree(BiTree T);             //按照后序遍历法遍历树
void ClearTree(BiTree &T);          //清空这个树
void TreeEmpty(BiTree T);           //对树进行判空
void Root(BiTree T);                //如果二叉树存在,返回根结点的值
BiTree FindTree(BiTree T,char e);   //查找一个结点,是否存在
int Assign(BiTree T,char &e,char value);//二叉树存在,e是T中某个结点,结点e赋值为value
BiTree Parent(BiTree T,char e);     //若e是T的非根结点,则返回她的双亲,否则返回
BiTree LReftTree(BiTree T,char e);  //返回左右孩子,若e无左右孩子就返回空
void pro();                         //功能区
int DeepthTree(BiTree T);           //求树的深度
BiTree LeftSibling(BiTree T,char e);//返回e的左兄弟,若e是T的左孩子或左孩子不存在,则返回“空
BiTree RightSibling(BiTree T,char e);//返回e的右兄弟,若e是T的右孩子或右孩子不存在,则返回“空
void CreatC(BiTree &c);             //开辟c空间
void InsertChild(BiTree &T,BiTree c,int LR,char e);//根据LR为0或者1,插入c为T中p所指向结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树
void DestoryTree(BiTree &T);        //摧毁二叉树
void DeleteChild(BiTree T,char e,int LR);//根据LR为0或1,删除T中p所指结点的左或右结点
int LeaveSum(BiTree T);             //求叶子结点个数
int D2Sum(BiTree T);                //度数为2的结点个数
int D1Sum(BiTree T);                //度数为1的结点个数
void swi(BiTree T);                 //switch
void CengXu(BiTree T);              //层序遍历的原则输出树
void InitQueue(SqQueue &Q,BiTree T);//顺序队列开辟
void EnQueue(SqQueue &Q,BiTree T);  //入队列
int IsEmptyQueue(SqQueue Q);        //判队列空
void DeQueue(SqQueue &Q);           //退队列
BiTree GetFront(SqQueue Q);         //获取队首元素


//主函数
int main()
{
    BiTree T;
    T=NULL;
    swi(T);
}

//求树中全部结点
int MAX(BiTree T)
{
    int zero,one,two,shum;
    zero=LeaveSum(T);
    one=D1Sum(T);
    two=D2Sum(T);
    shum=zero+one+two;
    return shum;

}

//顺序队列开辟
void InitQueue(SqQueue &Q,BiTree T)
{
    int MAXSIZE;
    MAXSIZE=MAX(T)+1;
    Q.base = (BiTree *)malloc(MAXSIZE * sizeof(BiTree));
    if(!Q.base)
        printf("Q->base内存分配失败\n");
    Q.front = Q.rear =0;
    Q.maxsize=MAXSIZE;
    printf("顺序队列开辟完成\n");
}

//入队列
void EnQueue(SqQueue &Q,BiTree T)
{
    if((Q.rear+1)%Q.maxsize==Q.front)
        printf("队列空间满\n");
    else{
        Q.base[Q.rear]=T;
        Q.rear = (Q.rear+1)%Q.maxsize;
    }
}

//判队列空
int IsEmptyQueue(SqQueue Q)
{
    if(Q.front==Q.rear)
        return 0;
    else 
        return 1;
}

//退队列
void DeQueue(SqQueue &Q)
{   
    int e;
    BiTree T;
    T=Q.base[Q.front];
    Q.front=(Q.front+1)%Q.maxsize;
}

//获取队首元素
BiTree GetFront(SqQueue Q)
{
    return Q.base[Q.front];
}
//层序遍历的原则输出树
void CengXu(BiTree T)
{
    SqQueue Q;
    InitQueue(Q,T);
    BiTree s;
    s=T;
    EnQueue(Q,s);
    while(IsEmptyQueue(Q))
    {
        s=GetFront(Q);
        printf("%c ",s->data);
        if(s->lchild!=NULL)
        {
            EnQueue(Q,s->lchild);
        }
        if(s->rchild!=NULL)
        {
            EnQueue(Q,s->rchild);
        }
        DeQueue(Q);
    }
}

//以先序遍历的原则输入树
int  CreatTree(BiTree &T)
{
    char node;
    scanf("%c,",&node);
    if(node=='#')
    {
        T=NULL;
    }else{
        if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))
            printf("树的储存空间开发失败\n");
        T->data=node;
        CreatTree(T->lchild);
        CreatTree(T->rchild);
    }
    return OK;
}

//按照后序遍历法遍历树
void LRDTree(BiTree T)
{
    if(T!=NULL)
    {

        LRDTree(T->lchild);
        LRDTree(T->rchild);
        printf("%c ",T->data);
    }
}

//按照先序遍历法遍历树
void DLRTree(BiTree T)
{
   if(T!=NULL)
   {printf("%c ",T->data);
    DLRTree(T->lchild);
    DLRTree(T->rchild);
   }
  
}

//按照中序遍历法遍历树
void LDRTree(BiTree T)
{
    if(T!=NULL)
    {
        LDRTree(T->lchild);
        printf("%c ",T->data);
        LDRTree(T->rchild);
    }
}

//清空这个树
void ClearTree(BiTree &T)
{
    if(T!=NULL)
    {
        ClearTree(T->lchild);
        ClearTree(T->rchild);
        free(T);
        T=NULL;
    }
}

//对树进行判空
void TreeEmpty(BiTree T)
{
    if(T==NULL)
    {
        printf("这个二叉树为空二叉树\n");
    }else{
        printf("这个二叉树不为空二叉树\n");
    }
}

//如果二叉树存在,返回根结点的值
void Root(BiTree T)
{
    if(T==NULL)
    {
        printf("这个树为空树,不存在根\n");
    }else{
        printf("这个树的根结点是:%c\n",T->data);
    }
}

//查找一个结点,是否存在
BiTree FindTree(BiTree T,char e)
{
    if(T->data==e)
        return T;
    BiTree p;
    p=NULL;
    if(T->lchild!=NULL)
        p=FindTree(T->lchild,e);
    if(p!=NULL)
        return p;
    if(T->rchild!=NULL)
        p=FindTree(T->rchild,e);
    if(p!=NULL)
        return p;
}

//二叉树存在,e是T中某个结点,结点e赋值为value
int Assign(BiTree T,char &e,char value)
{
    BiTree o=NULL;
    o=FindTree(T,e);
    if(o!=NULL)
    {
        o->data=value;
        printf("替换赋值操作已经完成\n");
    }else{
        printf("没有找到这个值\n");
    }
}

//若e是T的非根结点,则返回她的双亲,否则返回
BiTree Parent(BiTree T,char e)
{
    BiTree p;
    if(T!=NULL)
    {
        if(T->data==e)
        {
            p=NULL;
            return p;
        }else if(T->lchild!=NULL&&T->lchild->data==e){
            p=T;
            return p;
        }else if(T->rchild!=NULL&&T->rchild->data==e){
            p=T;
            return p;
        }else
            p=Parent(T->lchild,e);
            if(p!=NULL){
                return p;}
            else{
                p=Parent(T->rchild,e);
                return p;
            }
    }else{
        p=T;
        return p;
    }
}

//返回左右孩子,若e无左右孩子就返回空
BiTree LReftTree(BiTree T,char e)
{
    BiTree p;
    p=FindTree(T,e);
    if(p!=NULL)
    {
        return p;
    }else{
        return p;
    }
}


//功能区
void pro()
{
    printf("0.退出\n");
    printf("1.建立一个树\n");
    printf("2.使用后序遍历法遍历\n");
    printf("3.使用先序遍历法遍历\n");
    printf("4.使用中序遍历法遍历\n");
    printf("5.清空这个树\n");
    printf("6.对这个树进行判空\n");
    printf("7.求这个树的深度\n");
    printf("8.求这个树的根结点\n");
    printf("9.查找元素,看是否存在\n");
    printf("10.二叉树存在,e是T中某个结点,结点e赋值为value\n");
    printf("11.若e是T的非根结点,则返回她的双亲,否则返回\n");
    printf("12.返回左孩子,若e无左孩子就返回空\n");
    printf("13.返回右孩子,若e无右孩子就返回空\n");
    printf("14.返回e的左兄弟,若e是T的左孩子或左孩子不存在,则返回“空\n");
    printf("15.返回e的右兄弟,若e是T的右孩子或右孩子不存在,则返回“空\n");
    printf("16.根据LR为0或者1,插入c为T中p所指向结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树\n");
    printf("17.摧毁二叉树\n");
    printf("18.根据LR为0或1,删除T中p所指结点的左或右结点\n");
    printf("19.求叶子结点的个数\n");
    printf("20.求度数为2的结点个数\n");
    printf("21.求度数为1的结点个数\n");
    printf("22.层序遍历\n");
}

//求树的深度
int DeepthTree(BiTree T)
{
    if(!T)
        return 0;
    else{
        int leftdeepth,rightdeepth;
        leftdeepth = DeepthTree(T->lchild);
        rightdeepth = DeepthTree(T->rchild);
        return 1+(leftdeepth>rightdeepth?leftdeepth:rightdeepth);
    }
}

//返回e的左兄弟,若e是T的左孩子或左孩子不存在,则返回“空
BiTree LeftSibling(BiTree T,char e)
{
    BiTree p;
    p = Parent(T,e);
    if(p->lchild->data==e||p->lchild==NULL)
    {
        p=NULL;
        return p;
    }else if(p->lchild->data!=e&&p->lchild!=NULL)
    {
        return p;
    }
}

//返回e的右兄弟,若e是T的右孩子或右孩子不存在,则返回“空
BiTree RightSibling(BiTree T,char e)
{
    BiTree p;
    p=Parent(T,e);
    if(p->rchild->data==e||p->rchild==NULL)
    {
        p=NULL;
        return p;
    }else if(p->rchild->data!=e&&p->rchild!=NULL)
    {
        return p;
    }
}

//开辟c空间
void CreatC(BiTree &c)
{
    c=(BiTNode *)malloc(sizeof(BiTNode));
    c->lchild=NULL;
    c->rchild=NULL;
    printf("请输入C结点中的值:");
    scanf("%c",&c->data);
    getchar();
}
//根据LR为0或者1,插入c为T中p所指向结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树
void InsertChild(BiTree &T,BiTree c,int LR,char e)
{
    BiTree q;
    BiTree t;
    q=NULL;
    if(LR==0)
    {
        q=FindTree(T,e);
        t=q->lchild;
        q->lchild=c;
        c->rchild=t;
    }else if(LR==1)
    {
        q=FindTree(T,e);
        t=q->rchild;
        q->rchild=c;
        c->rchild=t;
    }

}

//摧毁二叉树
void DestoryTree(BiTree &T)
{
    if(T!=NULL)
    {
        DestoryTree(T->lchild);
        DestoryTree(T->rchild);
        free(T);
        T=NULL;
    }
}

//根据LR为0或1,删除T中p所指结点的左或右结点
void DeleteChild(BiTree T,char e,int LR)
{
    BiTree p;
    p=FindTree(T,e);
    if(LR==0)
    {
        if(p->lchild==NULL&&p->rchild==NULL)
        {
            free(p);
            p->lchild=NULL;
            p->rchild=NULL;
        }
    }
    
}

//求叶子结点个数
int LeaveSum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if(T->lchild==NULL&&T->rchild==NULL)
            n=n+1;
        int l=LeaveSum(T->lchild);
        int r=LeaveSum(T->rchild);
        return n+l+r;
    }
}

//度数为2的结点个数
int D2Sum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if(T->lchild!=NULL&&T->rchild!=NULL)
            n=n+1;
        int l=D2Sum(T->lchild);
        int r=D2Sum(T->rchild);
        return n+l+r;
    }
}

//度数为1的结点个数
int D1Sum(BiTree T)
{
    if(!T)
        return 0;
    else{
        int n=0;
        if((T->lchild==NULL&&T->rchild!=NULL)||(T->lchild!=NULL&&T->rchild==NULL))
            n=n+1;
        int l=D1Sum(T->lchild);
        int r=D1Sum(T->rchild);
        return n+l+r;
    }
}
//switch
void swi(BiTree T)
{
    int num;
    pro();
    printf("请输入功能数字:");
    scanf("%d",&num);
    getchar();
    while(num)
    {
        switch(num)
        {
            case 0:
                num=0;
                break;
            case 1:
                printf("请输入树内元素:");
                CreatTree(T);
                printf("元素输入操作已经完成\n");
            break;
            case 2:
                if(T==NULL)
                {
                    printf("在执行操作二之前需要执行操作一\n");
                }else{
                    LRDTree(T);
                }
            break;
            case 3:
                if(T==NULL)
                {
                    printf("在执行操作三之前需要执行操作一\n");
                }else{            
                    DLRTree(T);
                    }
            break;
            case 4:
                if(T==NULL)
                {
                    printf("在执行操作四之前需要执行操作一\n");
                }else{            
                    LDRTree(T);
                }
            break;
            case 5:
                if(T==NULL)
                {
                    printf("在执行操作五之前需要执行操作一\n");
                }else{  
                    ClearTree(T);
                }
            break;
            case 6:
                if(T==NULL)
                {
                    printf("在执行操作六之前需要执行操作一\n");
                }else{  
                    TreeEmpty(T);
                }
            break;
            case 7:
                if(T==NULL)
                {
                    printf("在执行操作七之前需要执行操作一\n");
                }else{  
                    int deepth;
                    deepth=DeepthTree(T);
                    printf("这个树的深度是:%d\n",deepth);
                }
            break;
            case 8:
                if(T==NULL)
                {
                    printf("在执行操作八之前需要执行操作一\n");
                }else{  
                    Root(T);
                    }
            break;
            case 9:
                if(T==NULL)
                {
                    printf("在执行操作九之前需要执行操作一\n");
                }else{
                    printf("请输入需要查找的元素:");
                    int e;
                    scanf("%c",&e);
                    BiTree t = FindTree(T,e);
                    if(t!=NULL)
                        printf("您所查找的%c存在\n",e);
                    else
                        printf("您所查找的%c不存在\n",e);
                }
            break;
            case 10:
                if(T==NULL)
                {
                    printf("在执行操作十之前需要执行操作一\n");
                }else{  
                    char s,value;
                    printf("请输入需要搜索(被替换)的结点:");
                    scanf("%c",&s);
                    getchar();
                    printf("请输入要换成的值:");
                    scanf("%c",&value);
                    Assign(T,s,value);
                    }
            break;
            case 11:
                if(T==NULL)
                {
                    printf("在执行操作十一之前需要执行操作一\n");
                }else{  
                    char a;
                    printf("请输入想要求什么元素的双亲\n");
                    scanf("%c",&a);
                    getchar();
                    BiTree q;
                    q=Parent(T,a);
                    if(q!=NULL)
                        printf("%c的双亲是%c\n",a,q->data);
                    else
                        printf("不存在双亲\n");
                        }
            break;
            case 12:
                if(T==NULL)
                {
                    printf("在执行操作十二之前需要执行操作一\n");
                }else{  
                    char b;
                    printf("请输入想要查找哪个元素的左孩子:");
                    scanf("%c",&b);
                    getchar();
                    BiTree x;
                    x=LReftTree(T,b);
                    if(x!=NULL)
                    {   if(x->lchild!=NULL)
                            printf("左孩子是%c\n",x->lchild->data);
                        else
                            printf("这个元素没有左孩子\n");
                    }else{
                        printf("这个元素不存在\n");
                    }
                    }
            break;            
            case 13:
                if(T==NULL)
                {
                    printf("在执行操作十三之前需要执行操作一\n");
                }else{  
                    char z;
                    printf("请输入想要查找哪个元素的右孩子:");
                    scanf("%c",&z);
                    getchar();
                    BiTree X;
                    X=LReftTree(T,z);
                    if(X!=NULL)
                    {   if(X->rchild!=NULL)
                            printf("右孩子是%c\n",X->rchild->data);
                        else
                            printf("这个元素没有右孩子\n");
                    }else{
                        printf("这个元素不存在\n");
                    }
                    }
            break;
            case 14:
                if(T==NULL)
                {
                    printf("在执行操作十四之前需要执行操作一\n");
                }else{  
                    char xx;
                    printf("请输入你想要查找什么元素的左兄弟\n");
                    scanf("%c",&xx);
                    getchar();
                    BiTree Xx;
                    Xx=LeftSibling(T,xx);
                    if(Xx!=NULL)
                    {
                        printf("%c的左兄弟是%c\n",xx,Xx->lchild->data);
                    }else{
                        printf("%c没有左兄弟",xx);
                    }
                }
            break;
            case 15:
                if(T==NULL)
                {
                    printf("在执行操作十五之前需要执行操作一\n");
                }else{  
                    char yy;
                    printf("请输入你想要查找什么元素的右兄弟\n");
                    scanf("%c",&yy);
                    getchar();
                    BiTree Xy;
                    Xy=RightSibling(T,yy);
                    if(Xy!=NULL)
                    {
                        printf("%c的右兄弟是%c\n",yy,Xy->rchild->data);
                    }else{
                        printf("%c没有右兄弟",yy);
                    }
                }
            break;
            case 16:
                if(T==NULL)
                {
                    printf("在执行操作十六之前需要执行操作一\n");
                }else{  
                    BiTree c;
                    char pp;
                    int LR;//L左R右
                    CreatC(c);
                    printf("请输入想要插入的元素的结点:");
                    scanf("%c",&pp);
                    printf("请输入LR:");
                    scanf("%d",&LR);
                    InsertChild(T,c,LR,pp);
                    printf("插入完成\n");
                }
            break;
            case 17:
                if(T==NULL)
                {
                    printf("在执行操作十七之前需要执行操作一\n");
                }else{  
                    DestoryTree(T);
                    printf("摧毁二叉树操作完成\n");
                }
            break;
            case 18:
                if(T==NULL)
                {
                    printf("在执行操作十八之前需要执行操作一\n");
                }else{  
                    printf("还未完成\n");
                }
            break;
            case 19:
                if(T==NULL)
                {
                    printf("在执行操作十九之前需要执行操作一\n");
                }else{  
                    int n;
                    n=LeaveSum(T);
                    printf("叶子结点个数是%d",n);
                    }
            break;
            case 20:
                if(T==NULL)
                {
                    printf("在执行操作二十之前需要执行操作一\n");
                }else{  
                    int l;
                    l=D2Sum(T);
                    printf("度数为2的结点为%d",l);
                    }
            break;
            case 21:
                if(T==NULL)
                {
                    printf("在执行操作二十一之前需要执行操作一\n");
                }else{  
                    int nn;
                    nn=D1Sum(T);
                    printf("度数为1的结点为%d",nn);
                }
            break;
            case 22:
                if(T==NULL)
                {
                    printf("在执行操作二十二之前需要执行操作一\n");
                }else{
                    CengXu(T);
                }
            break;
            default:
                printf("输入有误,请重新输入\n");
        }
        printf("\n\n\n");
        pro();
        printf("请输入功能数字:");
        scanf("%d",&num);
        getchar();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值