当前位置:网站首页>利用二叉树的前中序遍历序列再次创建二叉树
利用二叉树的前中序遍历序列再次创建二叉树
2022-06-10 07:02:00 【安和橋北】
前情提要
当时学习数据结构的时候,只是知道如何根据前中序列、后中序列或者层次遍历和中序遍历序列来人工画出一颗二叉树,但是并没有用代码去实现这个过程。
接下来介绍这个代码的思想,先放出全部的代码。
代码
#include <stdio.h>
#define maxsize 100
// 利用前序遍历生成二叉树 并且获得前中序遍历的序列之后,再利用这两个序列生成二叉树!!!
typedef struct node
{
char data;
struct node *lchild, *rchild;
} node;
typedef node *bitree;
typedef struct
{
bitree a[maxsize];
int top;
} seqstack;
typedef struct
{
char ch[maxsize];
int low, high;
} seqlist;
bitree buildtree() // 前序遍历创建二叉树
{
char c;
node *p;
c = getchar();
if (c == '0')
return (0);
p = new (node);
p->data = c;
p->lchild = buildtree();
p->rchild = buildtree();
return (p);
}
bitree buildtreebyseq(seqlist s1, seqlist s2) // 根据前中序遍历序列创建二叉树
{
int rt, j, l1, l2, h1, h2;
l1 = s1.low;
l2 = s2.low;
h1 = s1.high;
h2 = s2.high;
char c;
node *p;
if (s1.low > s1.high || s2.low > s2.high)
return (0);
c = s1.ch[s1.low];
p = new (node);
p->data = c;
for (j = s2.low; j <= s2.high; j++)
if (c == s2.ch[j])
{
rt = j;
break;
}
s1.low = l1 + 1;
s1.high = l1 + rt - l2;
s2.low = l2;
s2.high = rt - 1; // s2 用左半段
p->lchild = buildtreebyseq(s1, s2);
s1.low = l1 + rt - l2 + 1;
s1.high = h1;
s2.low = rt + 1;
s2.high = h2; // s2用右半段
p->rchild = buildtreebyseq(s1, s2);
return (p);
}
void preorder(bitree t, seqlist &spreoder) // 前序遍历非递归
{
spreoder.low = 0;
int i = 0;
seqstack s;
s.top = -1; //置栈空
while ((t) || (s.top != -1))
{
while (t)
{
printf("%c", t->data);
spreoder.ch[i] = t->data;
i++;
s.top++;
s.a[s.top] = t;
t = t->lchild;
}
if (s.top > -1)
{
t = s.a[s.top];
s.top--;
t = t->rchild;
}
}
spreoder.high = i - 1;
}
void DLR(node *root) // 前序遍历递归
{
if (root != NULL) //非空二叉树
{
printf("%c", root->data); //访问D
DLR(root->lchild); //递归遍历左子树
DLR(root->rchild); //递归遍历右子树
}
}
void midorder(bitree t, seqlist &smidoder) // 中序遍历非递归
{
smidoder.low = 0;
int i = 0;
seqstack s;
s.top = -1; //置栈空
while ((t) || (s.top != -1))
{
while (t)
{
s.top++;
s.a[s.top] = t;
t = t->lchild;
}
t = s.a[s.top];
smidoder.ch[i] = t->data;
i++;
printf("%c", t->data);
s.top--;
t = t->rchild;
}
smidoder.high = i - 1;
}
void LDR(node *root) // 中序遍历递归
{
if (root != NULL)
{
LDR(root->lchild);
printf("%c", root->data);
LDR(root->rchild);
}
}
void postorder(bitree t) //非递归后序实现
{
bitree lastvist;
seqstack s;
lastvist = 0;
s.top = -1; //置栈空
while (t || s.top != -1)
{
while (t)
{
s.top++;
s.a[s.top] = t;
t = t->lchild;
}
t = s.a[s.top];
if (t->rchild == lastvist || t->rchild == NULL)
{
printf("%c", t->data);
s.top--;
lastvist = t;
t = 0;
}
else
t = t->rchild;
}
}
void LRD(node *root) // 后序遍历递归
{
if (root != NULL)
{
LRD(root->lchild);
LRD(root->rchild);
printf("%c", root->data);
}
}
int main()
{
seqlist s1, s2;
bitree t1, t2;
t1 = buildtree(); // 测试用例:abc00d00e0fg000
printf("\n第一次生成的二叉树非递归前序遍历结果,并生成前序序列s1\n");
preorder(t1, s1);
printf("\n第一次生成的二叉树非递归中序遍历结果,并生成中序序列s2\n");
midorder(t1, s2);
t2 = buildtreebyseq(s1, s2);
printf("\n第二次生成的二叉树前序遍历\n");
DLR(t2);
printf("\n第二次生成的二叉树中序遍历\n");
LDR(t2);
}
思路分析
利用前中序遍历序列来创建二叉树,重点肯定是放在两个序列上。
前序序列是用来找根节点的,根节点都在前序序列的前部分。
中序序列是用来根据前面找到的根节点来划分左右子树的。
所以我们可以通过下标low和high来对两个序列的左右部分进行划分,从而用递归的方法构建出整个二叉树。
过程
第一个for循环,是确定根节点在中序序列的位置,然后用rt记录下来。
然后开始调整s1和s2的大小。s1的low比较好理解,第一个根节点访问过了,所以跳过,直接+1即可。但是s1的high比较难。l1 + rt - l2这个值代表着分界线,把左子树的所有根节点 和 右子树的所有根节点分开来
然后s2.low = l2 s2.high = rt - 1代表只用s2的左边段,因为s2的左半段是左孩子的全部。然后进入p的左孩子的递归创建。
同理下面s1.low只是+1,往后移了一位,画了图就知道为啥只加1。同理s2,同理递归创建
边栏推荐
- Data migration of OLAP tool Doris or starrocks
- I/o basic knowledge sorting
- R语言数据处理:tidyr包学习
- The title of my composition is - "my district head father"
- 简述静态网页和动态网页的区别 Webl.0 和 Web2.0 的区别 简述 GET 和 POST 方法的区别
- POC_ Jenkins
- Go+vue+pgsql- family management system project conclusion
- 想要粽子可以,但是得经过我的认证授权才可以
- 智能合并视频,随机合并视频封面,并预设新标题
- All in one 1258 Dynamic programming of digital pyramid problem solving
猜你喜欢

I/o basic knowledge sorting

GO+VUE+PGSQL-家族管理系统项目结项

How to quickly clip multiple short videos and remove Video Trailer

Matlab: polynomial representation and its basic operations

leetcode.38 ---外观数列
[email protected] Bankruptcy"/>[today in history] March 2: Yahoo was officially established; PC design pioneer was born; [email protected] Bankruptcy
![[width first search] the shortest path in leetcode1091 binary matrix](/img/75/b7764114b2b0d137136ca5cc3222d7.png)
[width first search] the shortest path in leetcode1091 binary matrix

ShardingSphere实践(6)——弹性伸缩

智能合并视频,随机合并视频封面,并预设新标题

pyinstaller
随机推荐
R语言怎么利用ggplot2绘制QQ图和箱线图
Deploy MySQL based on statefulset in kubernetes (Part 2)
mongo,mongodb优化思路
Opengauss database ODBC environment connection configuration (Windows)
Beyond compare
『Three.js』起飞!
One brush 163 force deduction hot topic-76 minimum covering substring (H)
P1073 [NOIP2009 提高组] 最优贸易 题解 分层图最短路
Matlab: polynomial representation and its basic operations
Successfully solved: importerror: cannot import name 'import' from 'sklearn preprocessing
Refresh 54 Chinese NLP task benchmarks at one stroke. Easydl under ernie3.0 may be the best NLP development platform on the market
Fastjson利用笔记
LabVIEW控制Arduino实现红外测距(进阶篇—6)
27. encapsulate an animation function
Detailed explanation of C language linked list
spark 避免对一个列重复解析json
Keyboard events and form events
Scala fastjson gets the maximum value of a key in the jsonarray
Wechat team sharing: how the wechat background does not crash under massive concurrent requests
[dynamic programming] Game Theory: a collection of stone games