关于二叉树的一些操作

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0

#define MAXSIZE 24/*存储空间初始量分配*/
#define LONG sizeof(BiNode)

#define TREE "ABDH#K###E##CFI###G#J##"//需要创建的树

typedef int Status;//Status为函数变量类型返回值如OK等
typedef char TElemType;
typedef char String[25];//0号单元存放字符串长度

typedef struct BiNode//定义二叉树
{
    TElemType data;
    struct BiNode *lchild,*rchild;
}BiNode,*BiTree;

typedef struct queue
{
    BiTree data[MAXSIZE];//定义一个BiTree型指针数组存放二叉树节点
    int front,rear;
}LinkQueue;

Status CreateTree(BiTree *T);
void Destory(BiTree T);
void PreOrderTraverse(BiTree T);//先序遍历
void InOrderTraverse(BiTree T);//中序遍历
void PostOrderTraverse(BiTree T);//后序遍历
void GroundOrderTraverse(BiTree T);//层级遍历
int BiTreeDepth(BiTree T);//求深度
int TreeLeaf(BiTree T);//求叶子节点数

Status StrAssign(String T,char *chars);

Status CreateQueue(LinkQueue*S);
Status EnQueue(LinkQueue*S,BiTree T);
Status Deueue(LinkQueue*S,BiTree temp);

String str;
int zb = 1;

int main()
{
    int i = 0;
    char key;
    BiTree T;
    StrAssign(str,TREE);
    while('i' != key)
    {
        printf("选择要使用的功能:\n");
        printf("a:创建二叉树b:销毁二叉树c:求二叉树深度d:求叶子节点数e:先序遍历f:中序遍历g:后序遍历h:层次遍历i:退出\n");
        scanf("%c",&key);
        getchar();
        switch(key)
        {
            case 'a':CreateTree(&T);break;
            case'b':Destory(T);break;
            case 'c':i =BiTreeDepth(T);printf("%d\n",i);break;
            case 'd':i =TreeLeaf(T);printf("%d\n",i);break;
            case'e':PreOrderTraverse(T);break;
            case'f':InOrderTraverse(T);break;
            case 'g':PostOrderTraverse(T);break;
            case'h':GroundOrderTraverse(T);break;
            case'i':printf("beybey\n");break;
            default :printf("输入错误请从新输入\n");
        }
    }
    return 0;
}

Status StrAssign(String T,char *chars)
{
    int i;
    if(strlen(chars) > MAXSIZE)
        return ERROR;
    T[0] = strlen(chars);//T[0]存放数组长度
    for(i = 1;i <= T[0]; i++)
        T[i] = *(chars + i - 1);//将chars中字符赋给从T[1]开始的数组
    return OK;
}

Status CreateTree(BiTree*T)
{
    TElemType ch;
    ch = str[zb++];
    if(ch == '#')//判出条件
        return 0;
    *T = (BiTree)malloc(LONG);
    if(!*T)
        return ERROR;
    (*T)->data = ch;
    CreateTree(&((*T)->lchild));
    CreateTree(&((*T)->rchild));//递归调用左右子树
    return OK;
}

void Destory(BiTree T)
{
    if(T)
    {
        if(T->lchild)
            Destory(T->lchild);
        if(T->rchild)
            Destory(T->rchild);
        free(T);//递归调用左右子树释放空间
        T = NULL;
    }
}

int BiTreeDepth(BiTree T)
{
    int i,j;
    if(!T)
        return 0;//如果根为空返回深度为1
    if(T->lchild)
        i =BiTreeDepth(T->lchild);
    else
        i = 0;
    if(T->rchild)
        j =BiTreeDepth(T->rchild);
    else
        j = 0;
    return i>j?i+1:j+1;//递归分别计算根节点向下左右子树深度并返回大的那个值+1
}

void PreOrderTraverse(BiTree T)//先序遍历
{
    if(NULL == T)
        return;
    printf("%c",T->data);
    PreOrderTraverse(T->lchild);
    PreOrderTraverse(T->rchild);
}

void InOrderTraverse(BiTree T)//中序遍历
{
    if(NULL == T)
        return;
    InOrderTraverse(T->lchild);
    printf("%c",T->data);
    InOrderTraverse(T->rchild);
}

void PostOrderTraverse(BiTree T)//后序遍历
{
    if(NULL == T)
        return;
    PostOrderTraverse(T->lchild);
    PostOrderTraverse(T->rchild);
    printf("%c",T->data);
}

Status CreatQueue(LinkQueue *S)
{
    S->front = S->rear = 0;
    return OK;
}

Status EnQueue(LinkQueue *S,BiTree T)
{
    if((S->rear + 1)%MAXSIZE ==S->front)
    {
        return ERROR;
        printf("队列满\n");
    }
    S->data[S->rear] = T;
    S->rear = (S->rear +1)%MAXSIZE;//rear向后移一位,当rear到数组尾回到0
    return OK;
}

Status DeQueue(LinkQueue*S,BiTree*temp)
{
    if(S->rear == S->front)
    {
        printf("队列空\n");
        return ERROR;
    }
    *temp = S->data[S->front];//注意指针指向
    S->front = (S->front +1)%MAXSIZE;//循环队列出队列,当front到数组尾回到0
    return OK;
}

void GroundOrderTraverse(BiTree T)
{
    int count = 1;
    LinkQueue S;
    BiTree temp = T;
    if(!temp)
        return;
    CreatQueue(&S);
    EnQueue(&S,temp);
    do
    {
        if(DeQueue(&S,&temp))
        {
            printf("%c",temp->data);//取出节点
            count--;
        }
        if(temp->lchild)
        {
            EnQueue(&S,temp->lchild);
            count++;
        }  
        if(temp->rchild)
        {
            EnQueue(&S,temp->rchild);//将左右儿子节点放入队列尾
            count++;
        }
    }while(count);//循环把同层树节点入队列尾,再在队列头输出每一层
}

int TreeLeaf(BiTree T)
{
    static int i = 0;
    if(NULL == T)
        return 0;
    if(T->lchild)
        TreeLeaf(T->lchild);
    if(T->rchild)
        TreeLeaf(T->rchild);//递归调用判断是否为叶子节点
    if(!T->lchild &&!T->rchild)
        i++;//是叶子节点i自增
    return i;
}

猜你喜欢

转载自blog.csdn.net/chenwenjie666/article/details/79202820
今日推荐