首页 > 其他分享 >给出中序和前序如何求出后序

给出中序和前序如何求出后序

时间:2024-01-03 20:11:46浏览次数:23  
标签:pre string 后序 前序 substr 序列 中序

看题:

输入:
ABEDFCHG
CBADEFGH     输出:AEFDBHGC

这里利用到一个最重要的知识点——二叉树遍历

前序遍历:根左右

中序遍历:左根右

后序遍历:左右根

前序遍历是先遍历根节点,再遍历根节点的左右子树。

那么,前序序列的第一个节点,一定是根节点。

找到根节点,再确定根节点在中序序列中的位置,就可以分出左右两棵子树。

这道题我们不需要建树,只要通过递归不断切割字符串就好了。

字符串切割时应注意的问题

那便是切割位置。STL的string类型自带切割方法substr,但搞不清参数就会导致WA甚至RE。

首先我们搞清楚substr方法的使用方法。

string s;

s.substr(order,k);

参数传入一个order,一个k。

函数将会从下标为order的位置开始,连续截取k个字符。返回截取后的字符串。

order显然不能超出0~s.size()-1的范围。

但是,如果order+k超过了s.size()-1,函数会自动只截取到s的末尾。

如果不传入k,那么默认截取到末尾。

这个函数是返回一个字符串,而不是对s进行改动。

那么我们现在就开始寻找参数规律。

见下面的图(样例)

看到前序序列的第一个字符是 C ,那么根节点就是 C ,找到中序中对应的位置,数下标,发现 C 在 5 处 (注意字符串下标从0开始)。

然后在先序序列中把C删掉。

这是因为我们后面不会用到了。(下面的数字是下标)

中序序列中C在5处,那么左右子树分别就是ABEDF(0~4)和HG(6~7)。

设在中序序列中根节点的位置是k,

很容易发现:

中序序列中左子树就是从0开始切割到k-1,也就是切割了k个字符;

中序序列中右子树就是从k+1开始,一直切割到最后。

然后找前序序列切割的规律。

中序序列中左子树是ABEDF,右子树是HG,对应在前序序列中就是BADEF(0~4)和GH(5~6)。

那么前序序列中左子树是从0开始切割到k-1,也就是切割了k个字符;前序序列中右子树就是从k开始,一直切割到最后。另外仍需补充的几点,是关于查找和删除。

s.find(c);

在字符串s中查找第一个字符c的位置,返回下标,如果没有返回string::npos

s.erase(it);

在字符串中删除指针it所指向的字符

s.begin();

返回s的首字符的指针(迭代器)

那么我们现在就可以开始写代码了!(注意代码中的pre是前序,inor是中序)

 
          #include<string>   #include<cstring>   #include<iostream>   #include<cstdio>   using namespace std;   string pre,inor;   void work(string pre,string inor)   {   if(pre.empty())return;   //如果序列空了,就没必要继续了   char root=pre[0];   //取到前序序列的首字母,即根节点   int k=inor.find(root);   //找到中序序列中根节点的位置   pre.erase(pre.begin());   //删去前序序列中的根节点   string leftpre=pre.substr(0,k);   //从0开始切割k个   string rightpre=pre.substr(k);           //从k开始切割到最后   string leftinor=inor.substr(0,k);   //从0开始切割k个   string rightinor=inor.substr(k+1);   //从k+1开始切割到最后   work(leftpre,leftinor);   work(rightpre,rightinor);   printf("%c",root);   //因为要输出后序序列,所以是左右根   //先遍历左子树,再右子树,再根节点   }   int main()   {   cin>>inor>>pre;   work(pre,inor);   putchar('\n');   return 0;   }
 

2022年8月1日补充简洁代码

 
  #include<iostream>   #include<string>   #include<cstdio>   #include<string>       using namespace std;       void fun(string in , string pre)   {   if(!pre.empty())   {   char root = pre[0];   int k = in.find(root);   pre.erase(pre.begin());   fun(in.substr(0,k),pre.substr(0,k));   fun(in.substr(k+1),pre.substr(k));   cout << root;   }   }       int main()   {   string in,af;   cin >> in >> af;   fun(in,af);   return 0;   }
 

标签:pre,string,后序,前序,substr,序列,中序
From: https://www.cnblogs.com/lidabo/p/17943960

相关文章

  • 代码随想录算法训练营第十八天 | 513.找树左下角的值,112. 路径总和,113.路径总和ii,106.
    一、513.找树左下角的值题目链接:LeetCode513.找树左下角的值学习前:思路:层序遍历。采用递归和迭代两种方式递归:定义最大深度和目标值两个成员变量,方法参数是结点和当前结点的深度;返回类型为void;终止条件为结点为空;单次循环内容为判断该节点是否符合目标要求,且分别传入左子......
  • 二叉树的四种遍历-前序、中序、后序、层序
    目录一、易懂的形象理解1、先序遍历2、中序遍历3、后序遍历4、层序遍历二、真正理解三种遍历一、易懂的形象理解其实从名字就可以很好的理解这三种遍历,我在第二点时候说,但是估计能翻到我的文的同学们之前肯定看过好多类似的了,那咱们换个思路~先用我想的一种简单易懂的形象思维......
  • [LeetCode Hot 100] LeetCode94. 二叉树的中序遍历
    题目描述思路熟练掌握迭代和递归的代码。递归:额外写一个函数voidinOrder(TreeNodenode,Listres)迭代:令cur=root,一直往左子树找,找到最后一个左子节点,当cur为空,就开始处理栈顶元素(将栈顶元素加入结果集),随后将cur设置为右子节点,继续执行以上操作。方法一:递归/***......
  • [LeetCode Hot 100] LeetCode144. 二叉树的前序遍历
    题目描述思路熟练掌握迭代和递归的代码。递归代码:额外写一个函数voidpreOrder(TreeNodenode,Listres)迭代代码:会用到数据结构——栈。先入栈当前节点的右子节点,再入栈左子节点。方法一:递归/***Definitionforabinarytreenode.*publicclassTreeNode{*......
  • [LeetCode Hot 100] LeetCode145. 二叉树的后序遍历
    题目描述思路递归:额外写一个函数voidpostOrder(TreeNodenode,Listres)迭代:前序遍历:根---左---右将前序遍历改造成:根---右---左然后反转根右左为:左---右---根,即为后序遍历优化一下:while(!stack.isEmpty()){ TreeNodenode=stack.pop(); res.addFirst(node.......
  • 给出中序和按层遍历,求该树的先序遍历,后序遍历,叶子结点。
    一切的核心是怎么利用中序和按层遍历构建二叉树?1.优化空间很大,可以提前预处理记录每个数对应的位置,还可以vis数组记录这个点是不是已经作为根了。2.我们考虑到每次找到当前中序要处理区间,里面的数记为集合mid,我们从前到后看层序遍历中的哪个数最先出现在mid中。那么这个数就是当......
  • 二叉树给出先序和中序遍历序列,求和树 要求输出中序遍历序列;
    1.就算不知道用vector的初始化,也可以手动赋值创建子数组。2.不断找到当前序列对应的根节点,计算他的子节点的总和,在这样递归处理过程中,注意要中序输出,所以对于是先遍历完左子树,然后输出答案,然后遍历右子树#include<bits/stdc++.h>usingnamespacestd;#definelllonglong//......
  • 二叉树已经知道先序中序推后序
    https://www.acwing.com/problem/content/3601/不断找新的先序的根节点,根据位置切割中序,根据中序左右子树大小反切割先序,找到左子树对应的先序中序,然后递归处理#include<stdio.h>#include<vector>#include<map>#include<algorithm>#include<algorithm>#include<iostream>......
  • 320二叉树的不同形态(已知层次遍历和中序遍历创建二叉树;输出叶子结点(从左到右);后序遍历)
    题目:二叉树的不同形态问题描述给定二叉树T(树深度H<=10,深度从1开始,结点个数N<1024,结点编号1~N)的层次遍历序列和中序遍历序列,输出T从左向右叶子结点以及二叉树先序和后序遍历序列。输入格式输入共三行:第一行是整数n,表示二叉树中的结点数目;第二行有n个整数,表示该二叉树的层次遍......
  • 315二叉树扩展先序遍历转中序遍历
    题目:二叉树扩展先序遍历转中序遍历问题描述编一个程序,读入用户输入的一串扩展先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。例如如下的扩展先序遍历字符串:ABC##DE#G##F###其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出......