二叉树的先中后序遍历以及c语言实现二叉树

二叉树的先中后序遍历以及c语言实现二叉树

二叉树主要有三种遍历方式

  1. 先序遍历(根节点>左节点>右节点)
  2. 中序遍历(左节点>根节点>右节点)
  3. 后序遍历(左节点>右节点>根节点)
    ps:这个先中后其实是根据根节点的读取顺序定义的,根节点先遍历则为先序遍历,根节点后遍历则为后序遍历。
    举个例子:
    在这里插入图片描述
    先序遍历:ABDGHKECFIJ
    中序遍历:GDKHBEACIFJ
    后序遍历:GKHDEBIJFCA

先序遍历

        先序遍历,即先输出根节点,在输入左右子节点。
        在这棵二叉树中,根节点为A ,则先输出A,接着输出A的左节点B,按理说输出左节点之后要输出右节点,但是我们注意到A的左节点B,同时也是一个“根节点”,有D,E两个子节点,既然B作为“根节点”已经输出,接下来应该输入B的左节点D,同理D也是一个“根节点”,所以输出D的左节点G,此时对于(DGHK)这棵子树来说,根节点输出完毕,左节点输出完毕,输出右节点H,但是H也是一个“根节点”,同上,输出H的左节点K,H无右节点,所以(DGHK)这棵子树就输出完毕,也就是说B的左节点输出完毕,按照相同的方法输出右节点E,此时A的左节点输出完毕,右节点同理。

中序遍历

       中序遍历,即先输出左节点,然后输出根节点,最后是右节点
       在这棵二叉树中,根节点为A,按照定义我们应该先输出A的左节点B,但是我们注意到B也是一个“根节点”,我们在输出B之前要输出B的左节点D,同理,在输出D之前要输出D的左节点G,G是一个叶子节点,无牵无挂,我们直接输出,现在D的左节点G已经输出,我们就可以输出D,接着输出D的右节点,发现D的右节点H也是一个“根节点”,我们只要先输出H的左节点K,然后输出H,H没有右节点不用输出,此时B的左节点已经输出完毕,我们可以输出B了,然后输出B的右节点E,E为叶子节点,无牵无挂,直接输出,此时A的左节点已经全部输出,输出A,输出A之后看右节点,右节点同理。

后序遍历

          后序遍历,即先输出左节点,然后输出右节点,最后是根节点
       (这里换一种描述方式),可以把根节点理解为BOSS,左右节点为左右护法,如果想要打败BOSS就必须先打败左右护法,同时左右护法有可能也有左右小护法,同理打败小护法才能打败护法,这个时候我们看这棵二叉树,想打败A ,就要先打败BC,但是想打败B,就要先打败DE,,,,所以我们直接从最左下角开始看,最左边是G,G没有小护法,可以直接打败(输出G),G打败后D还有右护法H,想要打败H就必须打败H的护法K,K没有小护法,可以直接打败(输出K),打败K之后H就没有了小护法,击败H(输出H),GH都打败只有D就没有了护法,击败(输出D),同理B的左护法D已经被击败,下一个受害者就是B的右护法E,E没有左右护法,击败(输出E),这时B的左右护法都被击败了,我们就可以击败B,这样A的左护法就被干掉了,下一个目标是右护法C,后面同理。

规律分析

先序遍历:ABDGHKECFIJ(根节点A在输出队列的最前面)
中序遍历:GDKHBEACIFJ(根节点A在输出队列的中间,左右子树在左右两侧)
后序遍历:GKHDEBIJFCA(根节点A在输出队列的最后面)

代码实现(递归)

void PreOrder(Tree T)//二叉树的先序遍历
{
    if(T==NULL)
        return ;
    printf("%c ",T->data);
    PreOrder(T->lchild);
    PreOrder(T->rchild);
}
void InOrder(Tree T)//二叉树的中序遍历
{
   if(T==NULL)
       return ;
   InOrder(T->lchild);
    printf("%c ",T->data);
   InOrder(T->rchild);
}
void PostOrder(Tree T)//后序遍历
{
    if(T==NULL)
        return;
    PostOrder(T->lchild);
    PostOrder(T->rchild);
    printf("%c ",T->data);
}

二叉树完整代码

这里附上c语言创建二叉树的完整代码
ps:ABDG##HK###E##C#FI##J##(图中二叉树的输入)

#include<stdio.h>
#include<stdlib.h>
typedef struct TNode
{
    char data;
    struct TNode *lchild,*rchild;
}TNode,*Tree;
void PreOrder(Tree T)//二叉树的先序遍历
{
    if(T==NULL)
        return ;
    printf("%c ",T->data);
    PreOrder(T->lchild);
    PreOrder(T->rchild);
}
void InOrder(Tree T)//二叉树的中序遍历
{
   if(T==NULL)
       return ;
   InOrder(T->lchild);
    printf("%c ",T->data);
   InOrder(T->rchild);
}
void PostOrder(Tree T)//后序遍历
{
    if(T==NULL)
        return;
    PostOrder(T->lchild);
    PostOrder(T->rchild);
    printf("%c ",T->data);
}
void CreateBiTree(Tree *T)
{
    char ch;
    scanf("%c",&ch);
    if(ch=='#')
        *T=NULL;
    else
    {
        *T=(Tree)malloc(sizeof(TNode));
        if(!*T)
            exit(-1);
        (*T)->data=ch;
        CreateBiTree(&(*T)->lchild);
        CreateBiTree(&(*T)->rchild);
    }
}
int main()
{
    Tree T;
    CreateBiTree(&T);
    PreOrder(T);
    printf("\n");
    InOrder(T);
    printf("\n");
    PostOrder(T);
    return 0;
}


  • 12
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值