二叉树的三种遍历方法
先序遍历
中序遍历
后序遍历
从上面的流程图不难看出,三种遍历方法均为递归定义,区别仅在于访问根节点的时间。
已知先序遍历和中序遍历,求后序遍历
对于一个二叉树的先序遍历,它的第一个值一定是该树的根节点。在中序遍历中找到该节点,那么在这个中序遍历中,该节点左边即是节点左子树对应的中序遍历,根据左子树的大小又可以确定左子树的先序遍历;该右边即是节点右子树对应的中序遍历,根据右子树的大小又可以确定右子树的先序遍历,递归求解即可。
P1827 [USACO3.4] 美国血统 American Heritage
#include<bits/stdc++.h>
using namespace std;
string pre,ino;
int n;
void pos(int lpre,int rpre,int lino,int rino){
//printf("%d %d %d %d\n",lpre,rpre,lino,rino);
if(lpre==rpre){
cout<<pre[lpre];
return;
}
if(lpre>rpre||lino>rino) return;
char root=pre[lpre];
int i;
for(i=lino;i<=rino;i++){
if(ino[i]==root) break;
}
pos(lpre+1,lpre+i-lino,lino,i-1);
pos(rpre-rino+i+1,rpre,i+1,rino);
cout<<root;
}
int main(){
cin>>ino>>pre;
n=pre.length();
pos(0,n-1,0,n-1);
return 0;
}
已知中序遍历和后序遍历,求先序遍历
对于一个二叉树的后序遍历,它的最后一个值一定是该树的根节点。类似上述方法递归求解即可。
#include<bits/stdc++.h>
using namespace std;
string ino,pos;
int n;
void pre(int lino,int rino,int lpos,int rpos){
if(lpos>rpos||lino>rino) return;
cout<<pos[rpos];
if(lino==rino) return;
int i;
for(i=lino;i<=rino;i++){
if(ino[i]==pos[rpos]) break;
}
pre(lino,i-1,lpos,lpos+i-lino-1);
pre(i+1,rino,rpos-rino+i,rpos-1);
}
int main(){
cin>>ino>>pos;
int n=ino.length();
pre(0,n-1,0,n-1);
return 0;
}
已知先序遍历和后序遍历,求可能的中序遍历的数量
已知二叉树的先序遍历和后序遍历,可能存在多种对应的二叉树,即存在多种可能的中序遍历。
首先,当二叉树中的某一节点只有左子树或只有右子树,对于该根节点,可能存在两种不同的二叉树,使其先序遍历和后序遍历相同,因此只需要找到这样的节点有x个,答案即为2^x。
一个二叉树的先序遍历可以这样描述: root->left->right;
一个二叉树的后序遍历可以这样描述:left->root->right;
如果一个二叉树只有左子树,则其先序遍历为:root->left,后序遍历为:left->root;
并且由于两种遍历方式的特性,root之后/之前的节点一定是其左子树的根节点,因此,如果root之后/之前的节点相同,则可以判定该根节点满足条件,x++,然后得出左子树的先序遍历和后序遍历继续搜索左子树。对于右子树也是一样的。
如果一个二叉树既有左子树,也有右子树,分别得出两个子树的先序遍历和后序遍历后,向下搜索两个子树即可。
#include<bits/stdc++.h>
using namespace std;
string pre,pos;
int x=0;
void ino(int lpre,int rpre,int lpos,int rpos){
if(lpre>=rpre||lpos>=rpos) return;
int l=rpre-lpre+1;
//string pre_n=pre.substr(lpre,l),pos_n=pos.substr(lpos,l);
if(pre[lpre+1]==pos[lpos+1]){
x++;
ino(lpre+1,rpre,lpos+1,rpos);
return;
}
int i;
for(i=lpre;i<=rpre;i++){
if(pos[lpos+1]==pre[i]) break;
}
ino(i,rpre,lpos+1,lpos+1+rpre-i);
ino(lpre+1,i-1,rpos-(i-2-lpre),rpos);
}
int main(){
cin>>pre>>pos;
reverse(pos.begin(),pos.end());
int l=pre.length();
ino(0,l-1,0,l-1);
cout<<(long long)pow(2,x);
return 0;
}