二叉树遍历

1.广度优先遍历

2.深度优先遍历

1.前序遍历

根结点--左子树--右子树

void pre(int p){
	printf("%d\n",p);
    if(tree[p].l)pre(tree[p].l);
    if(tree[p].r)pre(tree[p].r);
}

2.中序遍历

左子树--根结点--右子树

void in(int p){
	if(tree[p].l)in(tree[p].l);
    printf("%d\n",p);
    if(tree[p].r)in(tree[p].r);
}

3.后序遍历

左子树--右子树--根结点

void post(int p){
	if(tree[p].l)post(tree[p].l);
    if(tree[p].r)post(tree[p].r);
    printf("%d\n",p);
}

3.已知先中求后

P1827 [USACO3.4] 美国血统 American Heritage

#include<bits/stdc++.h>
using namespace std;
string a,b;
void dfs(int l,int r,int ql,int qr){
	for(int i=ql;i<=qr;i++){
		if(a[i]==b[l]){
			dfs(l+1,l+i-ql,ql,i-1);  //i-ql表示左子树长度
			dfs(l+i-ql+1,r,i+1,qr);
			cout<<b[l];
		}
	}
}
int main(){
	cin>>a>>b;
	dfs(0,a.length()-1,0,a.length()-1);
	return 0;
}

4.已知中后求先

P1030 [NOIP 2001 普及组] 求先序排列

反过来即可

#include<bits/stdc++.h>
using namespace std;
string a,b;
void dfs(int l,int r,int ql,int qr){
	for(int i=qr;i>=ql;i--){
		if(a[i]==b[r]){
			cout<<b[r];
			dfs(l,r-(qr-i)-1,ql,i-1);  
			dfs(r+i-qr,r-1,i+1,qr);
			 
		}
	}
}
int main(){
	cin>>a>>b;
	dfs(0,a.length()-1,0,a.length()-1);
	return 0;
}

5.已知先后求中的可能个数

P1229 遍历问题

有n个只有一个子树的结点就有2^n种可能

输入例子:

前:abc

后:cba

若两个字母在前序与后序中位置相邻且相反,那便是一个单子树结点

因为前序是根左右

后序是左右根

若存在两个子树

那么相邻一定不一样

#include<bits/stdc++.h>
using namespace std;
string a,b; 
long long ans;
int main(){
	cin>>a>>b;
	int n=a.length();
	for(int i=0;i<=n-2;i++){
		for(int j=0;j<=n-1;j++){
			if(a[i]==b[j]&&a[i+1]==b[j-1])ans++;
		}
	}
	cout<<pow(2,ans);
	return 0;
}
posted @ 2025-09-16 12:35  R-99Player  阅读(7)  评论(0)    收藏  举报