树讲解(4)——先序遍历

何为先序遍历??

先序遍历(DLR)(根左右

先序遍历也叫做先根遍历、前序遍历,可记做根左右。

先序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。

二叉树为空则结束返回,否则:

(1)访问根结点。

2)前序遍历左子树

(3)前序遍历右子树 。

需要注意的是:遍历左右子树时仍然采用前序遍历方法。

如图所示二叉树

  

 

 

前序遍历,也叫先根遍历,遍历的顺序是,根,左子树,右子树

遍历结果:ABDECF

中序遍历,也叫中根遍历,顺序是 左子树,根,右子树(左根右

遍历结果:DBEAFC

后序遍历,也叫后根遍历,遍历顺序,左子树,右子树,根(左右根

遍历结果:DEBFCA

 

好,明白概念了,我们来做个题吧!

洛谷——P1030 求先序排列

题目描述

给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度<=8)。

输入输出格式

输入格式:

 

2行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。

 

输出格式:

 

1行,表示一棵二叉树的先序。

 

输入输出样例

输入样例#1:
BADC
BDCA
输出样例#1:
ABCD


思路:
对于一棵树,我们可以知道他的后续遍历的最后一项一定是这棵树的根。
这样我们在拿到一棵树的中序遍历和这棵树的后序遍历以后,我们先找到这棵树的根节点;
然后再对这棵树的中续遍历扫一遍,确定下来这个根节点在中序遍历的位置,这样,在这棵树的根节点两边的就分别是这个根节点的左右子树
然后我们就把这整棵树转化成两颗子树的问题了!
这样对于这个题,我们就采取分治的方法进行求解!
注意:
本题使用gets时全部wa掉,改成scanf就全都对了!
同时注意
if(d[R]<r) dfs(d[R]+1,r,R-r+d[R],R-1);里面为r!
在这里我们就来看看scanf和gets的区别吧!
首先:scanf可以接受多个字符串,而gets只可以接受一个字符串
其次:scanf不能读入带空格的字符串,gets可以读入带空格的字符串
最后:scanf()不能接受长度为0的字符串,会自动忽略开头的所有空格,并且以空格、换行符、回车结束输入
。而gets()能接受长度为0的字符串,不会自动忽略开头的所有空格或回车,并以回车结束。
代码:
#include<vector>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100000
#define maxn 123456
using namespace std;
char a[N],b[N];
int c[N],d[N]; 
void dfs(int l,int r,int L,int R)
{
    printf("%c",b[R]);
    if(d[R]>l) dfs(l,d[R]-1,L,d[R]-l+L-1);//说明他有左子树,那么对她的左子树进行查找 
                        //对一棵树来说,它的左子树的最左端一定是L,最右端就是
                        //它的根所在的地方(在中序排序中)+减去中序排序的左端点——这是求出了他的左子树的长度 
                        //那他的在后续排序中的最右端是在后续排序的左端+他的左子树的长度 
    if(d[R]<r) dfs(d[R]+1,r,R-r+d[R],R-1);//说明它具有右子树,那么对他的右子树进行查找。
                        // 对一棵树来说,他的右子树在后续遍历中左端点的的位置为:R-r+d[R]
                        //r-d[R]是求出了这棵树的右子树的长度,那他的左端点为当前的右端点减去右子树的长度 
 } 
int main()
{
    /*gets(a);//这棵树的中序排序 
    gets(b);//这棵树的后序排序 */
    scanf("%s",a);
    scanf("%s",b);
    int l=strlen(a);//对于一棵树来说:他的中序排序和它的后续排序的长度是相同的,所以在这里我们只要求他中序排序的长度就好了! 
    for(int i=0;i<l;i++)
      c[a[i]]=i;//储存中序排序的每个点在中序排序中的位置 
    for(int i=0;i<l;i++ )
      d[i]=c[b[i]];//储存后序遍历的每个点在中序遍历中的位置; 
    dfs(0,l-1,0,l-1);//同时在中序遍历和后序便利中进行查找(第一个1~n是中序遍历要进行查找的位置,第二个是后续遍历要查找的位置) 
    return 0; 
}
 
   

 



转载于:https://www.cnblogs.com/z360/p/6820759.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值