二叉树的遍历
1.已知中序遍历和后序遍历,得到先序遍历。
P1030 [NOIP2001 普及组] 求先序排列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路
例如:中序ACGDBHZKX,后序CDGAHXKZB,首先可找到主根B;
那么我们找到中序遍历中的B,由这种遍历的性质,可将中序遍历分为ACGD和HZKX两棵子树,
那么对应可找到后序遍历CDGA和HXKZ(从头找即可)
从而问题就变成求1.中序遍历ACGD,后序遍历CDGA的树 2.中序遍历HZKX,后序遍历HXKZ的树;
接着递归,按照原先方法,找到1.子根A,再分为两棵子树2.子根Z,再分为两棵子树。
就按这样一直做下去(先输出根,再递归);
模板概括为step1:找到根并输出
step2:将中序,后序各分为左右两棵子树;
step3:递归,重复step1,2;
图中即为先序遍历、中序遍历、后序遍历。
代码实现
#include<stdio.h>
#include<string.h>
char zx[10],hx[10];
int len;
void fun(int zl,int zr,int hl,int hr)
{
printf("%c",hx[hr-1]);//打印根结点
int u;//标记根结点的位置
for(int i=zl; i<zr; i++)
{
if(zx[i]==hx[hr-1])//找出根结点在中序遍历的位置,然后进行标记
u=i;
}
if(u-zl>0)//有左子树
fun(zl,u,hl,hl+u-zl);
if(zr-u-1>0)//有右子树
fun(u+1,zr,hr-zr+u,hr-1);
}
int main()
{
void fun(int zl,int zr,int hl,int hr);
scanf("%s",zx);
scanf("%s",hx);
len=strlen(zx);//反正长度一样
fun(0,len,0,len);
return 0;
}
2.已知先序遍历、中序遍历,得到后续遍历。
P1827 [USACO3.4]美国血统 American Heritage - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路
这个其实和上面一个差不多,不同就是要在最后输出根结点,还有左右子树的范围。
代码实现
#include<stdio.h>
#include<string.h>
char zx[30],qx[30];
int len;
void fun(int ql,int qr,int zl,int zr)
{
int u;
for(int i=zl;i<zr;i++)
{
if(zx[i]==qx[ql])//标记根结点
{
u=i;
}
}
if(u-zl>0)//有左子树
fun(ql+1,ql+u+1-zl,zl,u);
if(zr-u-1>0)//有右子树
fun(qr-zr+u+1,qr,u+1,zr);
printf("%c",qx[ql]);//打印根结点
}
int main()
{
void fun(int ql,int qr,int zl,int zr);
scanf("%s",zx);
scanf("%s",qx);
len=strlen(zx);
fun(0,len,0,len);
return 0;
}
3.输出二叉树的先序遍历。
P1305 新二叉树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路
原来的思路是只用一个main函数,而不自定义函数,但这样的话就要写很多的for循环,特别绕,然后就改变了一下思路,自定义一个函数,用递归来不断找到结点,题目说了每一行每一个字母为节点,后两个字母分别为其左右儿子,如果这个结点用*表示,就是空的,没有左右子树,不需要在往下遍历这个结点。
代码实现
#include<stdio.h>
/*typedef struct Bnode
{
char data;//存储结点元素的值
struct Bnode *lchild;//指向左孩子
struct Bnode *rchile;//指向右孩子
}BiNode,*BiTree;
void PreOrderTraverse(BiTree T)
{
if(T!=NULL)//二叉树非空
{
printf("%c",T->data);//根结点
PreOrderTraverse(T->lchild);//先序遍历左子树
PreOrderTraverse(T->rchild);//先序遍历右子树
}
}*/
int n;
char s[30][5];
void fun(char u)
{
if(u!='*')
{
printf("%c",u);
for(int i=0;i<=n;i++)
{
if(s[i][0]==u)
{
fun(s[i][1]);
fun(s[i][2]);
}
}
return;
}
else
return;
}
int main()
{
void fun(char v);
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%s",s[i]);
fun(s[0][0]);
return 0;
}