C语言数据结构学习笔记(10)-二叉树的创建及遍历

/*
二叉树的创建及遍历
输出结果:
请输入待创建的二叉树:ABD##E##CF###
前序遍历:A B D E C F 中序遍历:D B E A F C 后序遍历:D E B F C A 层序遍历:A B C D E F
请按任意键继续. . .
*/
# include <stdio.h>
# include <stdlib.h>
# define ElemType char
# define MAX_SIZE 20
# define bool int
# define true 1
# define false 0
typedef struct BiTNode{
    ElemType elem;//数据域
    struct BiTNode * lchild, * rchild;//左右节点指针域
}BiTNode, * BiTree;
typedef struct Queue{
    BiTree * data;//数据域存放树的节点指针
    int front;//队首指针
    int rear;//队尾指针
}Queue, *pQueue;
void InitQueue(pQueue ptrQ);//初始化队列
bool IsEmpty(pQueue ptrQ);//判断队列是否为空
bool IsFull(pQueue ptrQ);//判断队列是否已满
bool EnQueue(pQueue ptrQ, BiTree ptrB);//入队
bool DeQueue(pQueue ptrQ, BiTree *ptrB);//出队
void DestoryQueue(pQueue ptrQ);//销毁队列
BiTree CreateBiTree(BiTree T);//创建二叉树
void PreOrderBiTree(BiTree T);//前序遍历二叉树
void InOrderBiTree(BiTree T);//中序遍历二叉树
void PostOrderBiTree(BiTree T);//后序遍历二叉树
void LevelBiTree(BiTree T);//层序遍历二叉树

int main(void)
{    
    printf("请输入待创建的二叉树:");
    BiTree T = NULL;
    T =    CreateBiTree(T);
    printf("前序遍历:");
    PreOrderBiTree(T);
    printf("中序遍历:");
    InOrderBiTree(T);
    printf("后序遍历:");
    PostOrderBiTree(T);
    printf("层序遍历:");
    LevelBiTree(T);
    printf("\n");
    system("pause");
    return 0;
}
//创建二叉树
BiTree CreateBiTree(BiTree T)
{    
    ElemType ch;
    scanf("%c", &ch);
    if('#' == ch)
        T = NULL;
    else
    {
        T = (BiTree)malloc(sizeof(BiTNode));
        if(NULL == T)
            exit(-1);
        T->elem = ch;
        T->lchild = CreateBiTree(T->lchild);
        T->rchild = CreateBiTree(T->rchild);
    }
    return T;
}
//前序遍历二叉树
void PreOrderBiTree(BiTree T)
{    
    /*
    //递归方式
    if(NULL == T)
        return;
    else
    {
        printf("%c ", T->elem);
        PreOrderBiTree(T->lchild);
        PreOrderBiTree(T->rchild);
    }
    */
    //非递归-栈
    if(NULL == T)
        return;
    BiTree Stack[MAX_SIZE];
    int top = -1;
    BiTree pMove = T;
    while(top != -1 || pMove)
    {
        while(pMove)
        {    
            printf("%c ", pMove->elem);
            Stack[++top] = pMove;
            pMove = pMove->lchild;
        }
        if(top != -1)
        {
            pMove = Stack[top--];
            pMove = pMove->rchild;
        }
    }
}
//中序遍历二叉树
void InOrderBiTree(BiTree T)
{
    
    //递归方式
    /*
    if(NULL == T)
        return;
    else
    {
        InOrderBiTree(T->lchild);
        printf("%c ", T->elem);
        InOrderBiTree(T->rchild);
    }
    */
    //非递归-栈
    if(NULL == T)
        return;
    else
    {    
        BiTree pStack[MAX_SIZE];
        int Top = -1;
        BiTree pMove = T;
        while(Top != -1 || pMove)
        {
            while(pMove)
            {
                pStack[++Top] = pMove;
                pMove = pMove->lchild;
            }
            if(Top != -1)
            {
                pMove = pStack[Top--];
                printf("%c ", pMove->elem);
                pMove = pMove->rchild;
            }
        }
    }
}
//后序遍历二叉树
void PostOrderBiTree(BiTree T)
{    
    //递归方式
    /*
    if(NULL == T)
        return;
    else
    {
        PostOrderBiTree(T->lchild);
        PostOrderBiTree(T->rchild);
        printf("%c ", T->elem);
    }
    */
    //非递归-栈
    if(NULL == T)
        return;
    else
    {
        BiTree Stack[MAX_SIZE]; 
        int top = -1;
        BiTree pMove = T;
        BiTree pLast = NULL;
        while(pMove)
        {
            Stack[++top] = pMove;
            pMove = pMove->lchild;
        }
        while(top != -1)
        {
            pMove = Stack[top--];
            if(pMove->rchild == NULL || pMove->rchild == pLast)//当前节点右是否被访问
            {
                printf("%c ", pMove->elem);//若被访问则打印
                pLast = pMove;//改变标记位置
            }
            else//当前节点右未被访问
            {    
                Stack[++top] = pMove;
                pMove = pMove->rchild;
                while(pMove)
                {
                    Stack[++top] = pMove;
                    pMove = pMove->lchild;
                }
            }
        }
    }
}

//后序遍历二叉树非递归2
void PostOrderBiTree2(BiTree root)
{
    struct Elem {BiTree pMove; int flag;};
    struct Elem temp;
    struct Elem pStack[MAX_SIZE];
    int top = -1;
    temp.pMove = root;
    while(temp.pMove || top != -1)
    {
        if(temp.pMove)
        {    
            temp.flag = 1;
            pStack[++top] = temp;
            temp.pMove = temp.pMove->lchild;
        }
        else
        {
            temp = pStack[top--];
            if(1 == temp.flag)
            {
                temp.flag = 2;
                pStack[++top] = temp;
                temp.pMove = temp.pMove->rchild;
            }
            else
            {
                printf("%c ", temp.pMove->elem);
                temp.pMove = NULL;
            }
        }
    }
    printf("\n");
}
//层序遍历二叉树
void LevelBiTree(BiTree T)
{
    if(NULL == T)
        return;
    else
    {    
        Queue Q;
        InitQueue(&Q);
        BiTree data;
        EnQueue(&Q, T);//根指针入队
        while(!IsEmpty(&Q))//当队列不为空一直循环
        {
            if(DeQueue(&Q, &data))//树节点指针出队
            {
                printf("%c ", data->elem);
            }
            if(data->lchild != NULL)//左节点指针若不为空则入队
                EnQueue(&Q, data->lchild);
            if(data->rchild != NULL)//右节点指针若不为空则入队
                EnQueue(&Q, data->rchild);
        }
        DestoryQueue(&Q);//销毁队列
    }
}
//初始化队列
void InitQueue(pQueue ptrQ)
{    
    ptrQ->data = (BiTree*)malloc(MAX_SIZE * sizeof(BiTree));//构建动态数组存放树的节点的指针
    if(NULL == ptrQ->data)
        exit(-1);
    ptrQ->front = 0;
    ptrQ->rear = 0;
}
//判断队列是否为空
bool IsEmpty(pQueue ptrQ)
{
    if(ptrQ->front == ptrQ->rear)
        return true;
    else
        return false;
}
//判断队列是否已满
bool IsFull(pQueue ptrQ)
{
    if((ptrQ->rear + 1) % MAX_SIZE == ptrQ->front)
        return true;
    else
        return false;
}
//入队
bool EnQueue(pQueue ptrQ, BiTree ptrB)
{
    if(IsFull(ptrQ))
        return false;
    else
    {
        ptrQ->rear = (ptrQ->rear + 1) % MAX_SIZE;
        ptrQ->data[ptrQ->rear] = ptrB;
        return true;
    }
}
//出队
bool DeQueue(pQueue ptrQ, BiTree * ptrB)
{
    if(IsEmpty(ptrQ))
        return false;
    else
    {
        ptrQ->front = (ptrQ->front + 1) % MAX_SIZE;
        *ptrB = ptrQ->data[ptrQ->front];
        return true;
    }
}
//销毁队列
void DestoryQueue(pQueue ptrQ)
{
    if(NULL == ptrQ)
        return;
    else
    {
        free(ptrQ->data);
        ptrQ->data = NULL;
    }
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值