先序中序数组推后序数组

二叉树遍历

所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。

 

从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:

⑴访问结点本身(N),

⑵遍历该结点的左子树(L),

⑶遍历该结点的右子树(R)。

以上三种操作有六种执行次序:

NLR、LNR、LRN、NRL、RNL、RLN。

注意:

前三种次序与后三种次序对称,故只讨论先左后右的前三种次序。

遍历命名

根据访问结点操作发生位置命名:

① NLR:前序遍历(Preorder Traversal 亦称(先序遍历))

——访问根结点的操作发生在遍历其左右子树之前。

② LNR:中序遍历(Inorder Traversal)

——访问根结点的操作发生在遍历其左右子树之中(间)。

③ LRN:后序遍历(Postorder Traversal)

——访问根结点的操作发生在遍历其左右子树之后。

注意:

由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

 

给出某棵树的先序遍历结果和中序遍历结果(无重复值),求后序遍历结果。

比如

先序序列为:1,2,4,5,3,6,7,8,9

中序序列为:4,2,5,1,6,3,7,9,8

方法1:我们可以重建整棵树:

https://blog.csdn.net/hebtu666/article/details/84322113

建议好好看这个网址,对理解这个方法有帮助。

 

如图

然后后序遍历得出后序序列。

 

方法2:我们可以不用重建,直接得出:

过程:

1)根据当前先序数组,设置后序数组最右边的值

2)划分出左子树的先序、中序数组和右子树的先序、中序数组

3)对右子树重复同样的过程

4)对左子树重复同样的过程

 

原因:我们的后序遍历是左右中的,也就是先左子树,再右子树,再根

举个例子:

比如这是待填充序列:

我们确定了根,并且根据根和中序序列划分出了左右子树,黄色部分为左子树:

先处理右子树(其实左右中反过来就是中右左,顺着填就好了):

我们又确定了右子树的右子树为黑色区域,然后接着填右子树的右子树的根(N)即可。

 

 

举例说明:

a[]先序序列为:1,2,4,5,3,6,7,8,9

b[]中序序列为:4,2,5,1,6,3,7,9,8

c[]后序序列为:0,0,0,0,0,0,0,0,0(0代表未确定)

我们根据先序序列,知道根一定是1,所以后序序列:0,0,0,0,0,0,0,0,1

从b[]中找到1,并划分数组:

          左子树的先序:2,4,5,

          中序:4,2,5

          右子树的先序:3,6,7,8,9,

          中序:6,3,7,9,8

 

我们继续对右子树重复相同的过程:

(图示为当前操作的树,我们是不知道这棵树的样子的,我是为了方便叙述,图片表达一下当前处理的位置)

当前树的根一定为先序序列的第一个元素,3,所以我们知道后序序列:0,0,0,0,0,0,0,3,1

我们继续对左右子树进行划分,中序序列为6,3,7,9,8,我们在序列中找到2,并划分为左右子树:

左子树:

先序序列:6

中序序列:6

右子树:

先序序列:7,8,9

中序序列:7,9,8

我们继续对右子树重复相同的过程,也就是如图所示的这棵树:

现在我们的后序序列为0,0,0,0,0,0,0,3,1

这时我们继续取当前的根(先序第一个元素)放在下一个后序位置:0,0,0,0,0,0,7,3,1

划分左右子树:

左子树:空,也就是它

右子树:先序8,9,中序9,8,也就是这个树

我们继续处理右子树:先序序列为8,9,所以根为8,我们继续填后序数组0,0,0,0,0,8,7,3,1

然后划分左右子树:

左子树:先序:9,中序:9

右子树:空

对于左子树,一样,我们取头填后序数组0,0,0,0,9,8,7,3,1,然后发现左右子树都为空.

我们就把这个小框框处理完了

然后这棵树的右子树就处理完了,处理左子树,发现为空。这棵树也处理完了。

这一堆就完了。我们处理以3为根的二叉树的左子树。继续填后序数组:

0,0,0,6,9,8,7,3,1

整棵树的右子树处理完了,左子树同样重复这个过程。

最后4,5,2,6,9,8,7,3,1

 

好累啊。。。。。。挺简单个事写了这么多。

回忆一下过程:

1)根据当前先序数组,设置后序数组最右边的值

2)划分出左子树的先序、中序数组和右子树的先序、中序数组

3)对右子树重复同样的过程

4)对左子树重复同样的过程

就这么简单

 

先填右子树是为了数组连续填充,容易理解,先处理左子树也可以。

最后放上代码吧

a=[1,2,4,5,3,6,7,8,9]
b=[4,2,5,1,6,3,7,9,8]
l=[0,0,0,0,0,0,0,0,0]

def f(pre,tin,x,y):
    #x,y为树在后序数组中对应的范围
    if pre==[]:return
    l[y]=pre[0]#根
    pos=tin.index(pre[0])#左子树元素个数
    f(pre[pos+1:],tin[pos+1:],x+pos,y-1)#处理右子树
    f(pre[1:pos+1],tin[:pos],x,x+pos-1)#处理左子树
    
f(a,b,0,len(l)-1)
print(l)

 

  • 131
    点赞
  • 203
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
### 回答1: 近序数组是指一个具有 n 个元素的数组,可以分为两个部分,且它的各个部分都是一个非严格有序数组。例如,数组 1、2、3、4、4、3、2、1 和数组 4、2、1、2、3、4 都是近序数组,但数组 1、5、7、3、9、3 不是近序数组。有序数组是近序数组的特例,例如数组 1、3、3、4。 ### 回答2: 简单来说,近序数组就是由两个非严格有序数组组成的数组。严格有序指的是每个元素都满足从左到右/从小到大(或从大到小)的排列顺序,而非严格有序指的是元素之间可以相同。也就是说,在近序数组中,两个相同的元素之间可以存在其他元素。 那么如何判断一个数组是否为近序数组呢?我们可以通过对数组进行分割,看其分为的两部分是否都是非严格有序。比如,对于数组1、2、3、4、4、3、2、1,我们可以将其分为1、2、3、4和4、3、2、1两部分,两部分都是非严格有序,因此这是一个近序数组。 再比如,对于数组4、2、1、2、3、4,我们可以将其分为4、2、1和2、3、4两部分,同样都是非严格有序,所以这也是一个近序数组。 但是,对于数组1、5、7、3、9、3,我们无法将其分为两个非严格有序的部分,因此它不是近序数组。 近序数组的存在并不常见,但是有时会在具有特定性质的数据集中出现。它的性质与有序数组类似,但比有序数组更容易构造。对于一些算法问题,近序数组也可以作为输入数据,提供不同于有序数组的挑战性。 ### 回答3: 什么是近序数组? 近序数组是指一个具有n个元素的数组,可以将其分为两个部分,它的各个部分都是一个非严格有序数组数组。所谓非严格有序,就是数组中有重复元素,且重复元素可以放在任意位置,而不会影响数组的排序结果。 近序数组的特点 1. 可以被分为两个部分:一个是递增部分,一个是递减部分。 2. 数组中的元素可以存在重复。 3. 数组中的元素不一定要完全按照升序或降序排列,只是要求部分数组是非严格有序数组。 如何判断一个数组是否是近序数组? 判断一个数组是否是近序数组,需要根据其是否满足上述近序数组的特点来进行判断。 具体来说,我们可以遍历整个数组,将其分为两个部分,分别判断这两个部分是否为非严格有序数组即可。 在遍历过程中,需要注意处理重复元素的情况。一般来说,我们可以将重复元素视为相同的元素,将其放置在相同的位置上。 如果分成的两个部分均为非严格有序数组,则该数组为近序数组;否则,该数组不是近序数组。 近序数组的应用 近序数组的应用比较广泛。在算法题中,常常会出现要求处理近序数组的问题。比如,在处理搜索和排序问题时,近序数组可以为我们提供更多的信息,有助于提高算法的效率。 另外,在实际的应用场景中,也有一些问题可以转化为近序数组的处理问题。比如,在处理时间序列数据时,往往需要对数据进行排序和查找等操作,此时可以将时间序列转化为近序数组,再进行处理。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔老大RabbitMQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值