zoukankan      html  css  js  c++  java
  • 二叉树的遍历及例题

    二叉树的遍历及例题

    前序遍历就是根在前,中序是根在根在中,

    前序遍历

    根 --> 左 --> 右

    中序遍历

    左 --> 根 --> 右

    后序遍历

    左 --> 右 --> 根

    如图是一颗二叉树

    前序(根左右),中序(左根右),后序(左右根)

    它的前序遍历结果为: A B D F G H I E C 代表的含义为A( B ( D ( F ,G( H ,I ) ) ,E ) , C )

    所以第一个点一定是根节点

    它的中序遍历结果为: F D H G I B E A C

    它代表的含义,A(已知它不是叶子节点)在中间说明A的左边是左儿子,A的右边是他的右儿子

    它的后序遍历结果为:F H I G D E B C A

    解题:

    如果有前序和中序或者中序和后序可以得到二叉树,从而得到后序。

    如果有前序和后序无法的得到二叉树。

    1.已知前序、中序遍历求后序遍历

    例:

    ​ 前序遍历:A B G D E C F H

    ​ 中序遍历:G B E D A F C H

    构建二叉树的步骤:

    1.根据前序遍历特点,得到根节点A

    2.观察中序遍历结果: 根节点左边节点为G B E D,根节点的右边节点为 F C H。同时,两段也是左右子树的中序遍历的结果。

    ​ B G D E也是左子树前序遍历的结果。 C F H也是右子树前序遍历的结果。

    3.重复 1 2的步骤,直到找到叶子结点就可以得到最后的二叉树。

    例题:

    https://vjudge.net/contest/407936#problem/K

    题意:给出中序遍历和前序遍历,让你找到后序遍历的结果。

    #include <iostream>
    using namespace std;
    const int maxn = 105;  
    int pre[maxn],in[maxn],pos[maxn];
    
    int infind(int root,int l,int r){//在中序遍历中找到当前根节点的位置 
    	for(int i=l;i<r;i++){
    		if(in[i]==root){
    			return i;
    		}
    	}	
    }
    int cnt;
    
    void posorder(int prel,int prer,int inl,int inr){
    	if(prel==prer) return ;
    	int root=infind(pre[prel],inl,inr);//找当前的根的位置 
    	int len=root-inl;
    	posorder(prel+1,prel+1+len,inl,inl+len);//prel的位置是root的位置,删去
    	posorder(prel+1+len,prer,inl+1+len,inr);//inl+len+1的位置是root的位置,删去
        //进行完左边和右边的遍历之后,进行赋值。 左右根
    	pos[cnt++]=in[root];
    	return;
    }
    
    int main(){
    	int n;
    	while(~scanf("%d",&n)){
    		cnt=0;
    		for(int i=0;i<n;i++) cin>>in[i];
    		for(int i=0;i<n;i++) cin>>pre[i];
    		posorder(0,n,0,n);
    		for(int i=0;i<n;i++) cout<<pos[i]<<' ';
    		cout<<endl;
    	}
    	return 0;
    } 
    
    //关键代码:
    
    void posorder(int prel,int prer,int inl,int inr){
    	if(prel==prer) return ;
    	int root=infind(pre[prel],inl,inr);//找当前的根的位置 
    	int len=root-inl;
    	posorder(prel+1,prel+1+len,inl,inl+len);
    	posorder(prel+1+len,prer,inl+1+len,inr);
    	pos[cnt++]=in[root];//相当于输出操作
    	return;
    }
    
    //得到前序遍历的值
    pos[cnt++]=in[root];//相当于输出操作
    posorder(prel+1,prel+1+len,inl,inl+len);
    posorder(prel+1+len,prer,inl+1+len,inr);
    
    //得到中序遍历的值
    posorder(prel+1,prel+1+len,inl,inl+len);
    pos[cnt++]=in[root];//相当于输出操作
    posorder(prel+1+len,prer,inl+1+len,inr);
    
    //得到后序遍历的值
    posorder(prel+1,prel+1+len,inl,inl+len);
    pos[cnt++]=in[root];//相当于输出操作
    posorder(prel+1+len,prer,inl+1+len,inr);
    

    例题:

    玩转二叉树

    https://pintia.cn/problem-sets/994805046380707840/problems/994805065406070784

    题意:给你中序遍历和前序遍历的结果,让你找到二叉树的镜像,然后按层遍历输出

    #include <iostream>
    using namespace std;
    int pre[55],in[55],pos[55];
    int ans[55][55];//储存按层遍历的结果
    //第一个存的哪一层,第二个存的是具体的数,
    //ans[t][0]存储的是该层的数字个数。
    int find(int t,int l,int r){
    	for(int i=l;i<r;i++){
    		if(in[i]==t){
    			return i;
    		}
    	}
    }
    
    void ceng(int prel,int prer,int inl,int inr,int t){
    	if(prel==prer) return ;
    	ans[t][++ans[t][0]]=pre[prel];//存入答案。
    	int x=find(pre[prel],inl,inr);
    	int len=x-inl;
    	ceng(prel+len+1,prer,inl+len+1,inr,t+1);//先遍历右边,再遍历左边
    	ceng(prel+1,prel+len+1,inl,inl+len,t+1);
    	return;
    }
    
    int main(){
    	int n;
    	cin>>n;
    	for(int i=0;i<n;i++) cin>>in[i];
    	for(int i=0;i<n;i++) cin>>pre[i];
    	ceng(0,n,0,n,0);
    	int x=0;
    		int len=0;
    	while(ans[x][0]!=0){
    	
    		for(int i=1;i<=ans[x][0];i++){
    			if(len==0){
    				printf("%d",ans[x][i]);
    			}else{
    				printf(" %d",ans[x][i]);
    			}
    			len++;
    			
    		}
    		x++;
    	}
    	return 0;
    }
    

    2.已知后序、中序遍历求前序遍历

    后序遍历是:左右根,所以根在最后,跟前序遍历相似,把 prel 和 prer 的值改变一下即可。

    3.已知前序、后序遍历求中序遍历

    无法求得!!!

  • 相关阅读:
    2020.4.13 机器学习相关数学基础
    2020.3.30 机器学习概述
    12.18语法制导的语义翻译
    12.11算符优先分析
    12.4自下而上语法分析
    11.27实验二 递归下降语法分析
    11.20LL(1)文法的判断,递归下降分析程序
    11.13消除左递归
    4.K均值算法--应用
    3.K均值算法
  • 原文地址:https://www.cnblogs.com/AC673523745/p/13991094.html
Copyright © 2011-2022 走看看