【408考研数据结构】二叉树的前序、中序、后序、层序遍历

本期的内容是“二叉树的前序、中序、后序遍历”

理论就不多嗦了,测试用的树是:
图片来源:王道考研数据结构PPT,侵权请联系删除
图片来源:王道考研数据结构PPT,侵权请联系删除

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

/*链式存储二叉树的先序、中序、后序、层序遍历*/
typedef struct BiTNode{
    char data;
    struct BiTNode* lchild;
    struct BiTNode* rchild;
}BiTNode,*BiTree;

void visit(BiTNode *t){
    printf("%c",t->data);
}

//这里编写一个链式队列,提供给层序遍历使用
typedef struct LNode{
    BiTNode data;
    struct LNode *next;
}LNode;

typedef struct{
    LNode *front,*rear;//队列头指针尾指针
}LinkQueue;

void InitQueue(LinkQueue *Q)
{
    Q->front=Q->rear=(LNode*)malloc(sizeof(LNode));//初始状态队列的头节点和尾结点都指向头节点
    Q->front->next=NULL;
}

bool IsEmpty(LinkQueue Q)//判断队列是否为空
{
    if(Q.front==Q.rear)
        return true;
    else
        return false;
}

void Enqueue(LinkQueue *Q,BiTNode N)//入队操作
{
    //给队列创建一个新的结点,存储要入队的数据
    LNode *s=(LNode*)malloc(sizeof(LNode));
    s->data=N;
    s->next=NULL;

    //将这个结点接入队列中
    Q->rear->next=s;//将这个结点放到队尾指针之后
    Q->rear=s;//队尾指针指向新元素
}

bool Dequeue(LinkQueue *Q, BiTNode *T)//出队操作
{
    if(IsEmpty(*Q))
        return true;

    LNode *p;
    

    p=Q->front->next;
    (*T)=p->data;//用T返回我们要删除的结点,便于后续访问这个结点的值
    Q->front->next=p->next;
    if(Q->rear==p)//这个情况是队列中只有一个元素,要把头指针和尾指针都指向头节点(不存数据)
    {
            Q->rear=Q->front;
    }
    free(p);
    return false;
}



//正片开始
//二叉树的先序遍历
void PreOrder(BiTree T)
{
    if(T!=NULL)//如果不是空树就进行遍历
    {
        visit(T);//访问根节点
        PreOrder(T->lchild);//以先序遍历的方式递归遍历左子树
        PreOrder(T->rchild);//以先序遍历的方式递归遍历右子树
    }
}

//二叉树的中序遍历
void InOrder(BiTree T){
    if(T!=NULL)
    {
        InOrder(T->lchild);//先用中序的方式访问左子树
        visit(T);//在访问本结点
        InOrder(T->rchild);//在用中序的方式访问右子树
    }
}

//二叉树后序遍历
void PostOrder(BiTree T){
    if(T!=NULL){
        PostOrder(T->lchild);//先以后序的方式遍历左子树
        PostOrder(T->rchild);//在以后序的方式遍历右子树
        visit(T);//最后访问根节点
    }
}

/*  二叉树层序遍历
    1.初始化一个辅助队列
    2.根节点入队
    3.若队列非空,则头节点出队,并将改头节点的左右子节点插入队尾
    4.重复步骤3直到队列为空
*/
void LevelOrder(BiTree T)
{
    LinkQueue Q;
    BiTNode n;//我们目前访问到的结点,也就是出队结点
    InitQueue(&Q);
    Enqueue(&Q,*T);
    while(!IsEmpty(Q))
    {
        Dequeue(&Q,&n);
        visit(&n);
        if(n.lchild!=NULL)
            Enqueue(&Q , *(n.lchild));
        if(n.rchild!=NULL)
            Enqueue(&Q, *(n.rchild));
    }
}


void test01()
{
    BiTree A;//创建一棵用于测试的树
    A=(BiTNode*)malloc(sizeof(BiTNode));//给头节点分配空间
    A->data='A';

    //创建几个节点,准备形成一棵树
    BiTNode *B;
    B=(BiTNode*)malloc(sizeof(BiTNode));
    B->data='B';

    BiTNode *C;
    C=(BiTNode*)malloc(sizeof(BiTNode));
    C->data='C';

    BiTNode *D;
    D=(BiTNode*)malloc(sizeof(BiTNode));
    D->data='D';

    BiTNode *E;
    E=(BiTNode*)malloc(sizeof(BiTNode));
    E->data='E';

    BiTNode *F;
    F=(BiTNode*)malloc(sizeof(BiTNode));
    F->data='F';

    BiTNode *G;
    G=(BiTNode*)malloc(sizeof(BiTNode));
    G->data='G';

    //把这些结点连成二叉树
    A->lchild=B;
    A->rchild=C;

    B->lchild=D;
    B->rchild=E;

    C->lchild=F;
    C->rchild=NULL;

    D->lchild=NULL;
    D->rchild=G;

    E->lchild=NULL;
    E->rchild=NULL;

    F->lchild=NULL;
    F->rchild=NULL;

    G->lchild=NULL;
    G->rchild=NULL;


    PreOrder(A);
    printf("\n\n");
    InOrder(A);
    printf("\n\n");
    PostOrder(A);
    printf("\n\n");
    LevelOrder(A);
}



int main()
{
    test01();
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值