18724 二叉树的遍历运算—— SCAU 数据结构——根据先序和中序,确定后序

这篇博客探讨如何根据先序和中序遍历序列构建二叉树,并导出后序遍历序列。通过分治思想,使用递归方法拆分和合并二叉树节点,最终实现从给定序列构造唯一二叉树并输出后序遍历顺序。示例展示了具体的操作过程和C语言实现。
摘要由CSDN通过智能技术生成

C,核心代码有详细注释,自写,请读者视情参考

思想:

根据中序排序的特点我们可以知道,如果我们选中其中某一节点,它的左边一定是这个节点的左子树,右边一定是这个节点的右子树。
根据先序排序的特点我们可以知道,如果我们选中其中某一节点,它右边的节点一定是先排列完左子树,再排列右子树。

那么我们能否根据这两个规律,确定唯一的二叉树?

如果确定能够构造唯一的二叉树,那么根据后序遍历的算法很容易得出后序序列。

所需知识:

C,二叉树,先序遍历,中序遍历,后序遍历

途径:

采用分治思想,先分后合。将左子树和右子树逐层分开,直到左边没有节点,右边没有节点,此时该节点为叶子节点,再进行合并,接上上一层的节点。分治法一般采用递归实现拆分和合并,所以这里用一个递归函数来实现。

举例:

(建议直接看代码,不清楚再看这里)

对于示例先序pre[] = abcde,中序in[] = bcade,从先序第一个节点a开始,在中序中找到a,则a的左子树为preL[] = bc(这里可以看出左子树是两个节点),右子树为preR[] = de(两个)。

那么,我们可以知道先序中a的后面两个节点是左子树inL[] = bc,再后面两个是右子树inR[] = de。把左子树接上a,右子树接上a(因为是递归,所以会从底层一个一个接上的)。

对左子树再进行拆分,先序preL[] = bc,中序inL[] = bc,从先序第一个节点b开始,在中序中找到b,则b的左子树为 (这里可以看出该节点没有左子树),右子树为c(一个)。

那么,我们可以知道先序中b的后面零个节点是左子树,再后面一个是右子树。再对右子树进行拆分,发现右子树只有一个,已经是叶子了,那么接上上一层。

右子树同样道理,拆分到底层叶子不可再拆分,再从底层一层一层接上去。

.

当然,若是对后序比较熟悉的话,就会发现,这接上去的顺序其实就是后序的顺序,针对这道题目可以直接输出。

所以这道题有更简单的写法,简单写法代码贴在最后以供参考,但这道题目的是理解三种序列的特点,熟练的读者可以尝试自行修改。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)
#define ElemType char
#define OK 1
#define  ERROR 0
#define MaxNodeCount 50
typedef int Status;

typedef struct BiTreeNode
{
   
	ElemType data;
	struct BiTreeNode *lchild;
	struct BiTreeNode *rchild;
}BiTreeNode, *Bitree;

Bitree Stack[MaxNodeCount];//栈
int base = 0, top = 0;

char pre[100];//先序
char in[100];//后序

//根据给出前序和中序序列,创建二叉树。
//preL:前序左界,preR前序右界,inL中序左界,inR中序右界
//返回:当前构造子树根节点
Bitree PreInCreat(int preL, int preR, int inL, int inR) {
   
  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值