3.15总结
P1305 新二叉树
首先介绍一下何为先序遍历:
在二叉树中,对于每一对父亲与左右儿子,都按照{父亲,左儿子,右儿子}的顺序来遍历
例如有这样一棵树:
先序遍历的顺序:
遍历1,输出“1”
遍历1的左儿子3,输出“3”遍历3的左儿子5,输出“5”
5没有左右儿子,返回3
遍历3的右儿子2,输出“2”
2没有左右儿子,返回3
3的左右儿子都遍历了,返回1遍历1的右儿子4,输出“4”
4没有左右儿子,返回1
1的左右儿子都遍历了,结束
所以这棵树的先序遍历是:1,3,5,2,4
那么代码也很简单了(伪代码):
点击查看代码
void dfs(int x){
if(x==leafnode){//叶子结点
return;/不跑了
}
cout<<x<<' ';//输出
dfs(leftson[x]);//左儿子
dfs(rightson[x]);//右儿子
}
而此题只需要先将字母转为ASCI码,输出时在转为字母即可
我的代码中没有记录左右儿子,将vector的存贮顺序定为先左后右:
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e6+5,mod=1e9+7,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
int n;
int root;
vector<int>vt[maxn];
void dfs(int x){
cout<<char(x);
for(int v:vt[x]){
dfs(v);
}
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
char r,u,v;
cin>>r>>u>>v;
if(i==1){
root=signed(r);
}
if(u!='*'){
vt[signed(r)].push_back(u);
}
if(v!='*'){
vt[signed(r)].push_back(v);
}
}
dfs(root);
return 0;
}
P1030 [NOIP 2001 普及组] 求先序排列
中序遍历与后序遍历是一样的,只是中序遍历的顺序是{左儿子,父亲,右儿子},后序遍历是{左儿子,右儿子,父亲}
写出上面的图的前中后序遍历:
先序:1,3,5,2,4
中序:5,3,2,1,4
后序:5,2,3,4,1
可以发现一个规律,先序的第一个与后序的最后一个都是根,而中序的根左边右边分别是左右子树的中序遍历
那么这一题就用后序遍历不断求根,在中序中找到根,分出左右子树,在递归即可
样例分析:
BADC
BDCA
后序遍历求根:A,输出
中序遍历中找到A在2的位置,得A左子树为B,右子树为DC
后序遍历的左子树是一样的从1到2-1的位置,即B,而右子树则是2+1~长度-1的位置,即DC
遍历左子树B,后序遍历求根:B,输出
中序遍历空了,返回
遍历右子树DC,得到根:C,输出
中序遍历中找到C在2的位置,得C左子树为D
后序遍历的左子树是一样的从1到2-1的位置,即D
遍历左子树D,得到根:D,输出
中序遍历空了,返回
C无右子树,返回
结束
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e6+5,mod=1e9+7,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
string a,b;
void dfs(string zhong,string hou){
if(zhong.size()==0){
return;
}
char root=hou[hou.size()-1];//求根
int pos=zhong.find(root);
cout<<root;
dfs(zhong.substr(0,pos),hou.substr(0,pos));//左子树
dfs(zhong.substr(pos+1),hou.substr(pos,hou.size()-pos-1));//右子树
}
signed main(){
cin>>a>>b;
dfs(a,b);
return 0;
}
本人(KK_SpongeBob)蒟蒻,写不出好文章,但转载请注明原文链接:https://www.cnblogs.com/OIer-QAQ/p/18775353

浙公网安备 33010602011771号