二叉树的先中后序遍历以及c语言实现二叉树
二叉树主要有三种遍历方式
- 先序遍历(根节点>左节点>右节点)
- 中序遍历(左节点>根节点>右节点)
- 后序遍历(左节点>右节点>根节点)
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;
}