3.15总结

P1305 新二叉树

首先介绍一下何为先序遍历:
在二叉树中,对于每一对父亲与左右儿子,都按照{父亲,左儿子,右儿子}的顺序来遍历
例如有这样一棵树:image
先序遍历的顺序:

遍历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;
}
posted @ 2025-03-16 18:02  KK_SpongeBob  阅读(16)  评论(0)    收藏  举报