由序列确定二叉树:前序序列和中序序列构造二叉树 后序序列和中序序列构造二叉树 层次遍历序列和中序遍历序列构造二叉树 代码实现(c语言)

article/2025/6/23 14:24:14

下面三种序列可以唯一的构造唯一的一棵二叉树:

前序序列和中序序列构造二叉树  

后序序列和中序序列构造二叉树

层次遍历序列和中序遍历序列构造二叉树  

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MaxSize 10
typedef struct BTNode{char data;struct BTNode *lchild,*rchild;
}BTNode,*BiTree;//根据前序序列,中序序列建造一棵二叉树
//参数含义:pre[]前序序列  in[]中序序列
//			L1  R1用于指定pre[]的搜索区域
//			L2  R2用于指定in[]的搜索区域 
BiTree createBiTree(char pre[],char in[],int L1,int R1,int L2,int R2){if(L1>R1){return NULL;//递归出口 }BTNode *s =(BTNode*)malloc(sizeof(BTNode));s->lchild =NULL;s->rchild =NULL;s->data=pre[L1];int i;//根据中序序列的特性,元素左边的元素属于该节点的左孩子序列,右边则是右孩子序列 for(i=L2;i<=R2;i++){if(pre[L1]==in[i]) break;//在中序序列找到该元素 }s->lchild=createBiTree(pre,in,L1+1,L1+i-L2,L2,i-1);//递归 s->rchild=createBiTree(pre,in,L1+i-L2+1,R1,i+1,R2); return s;
}
//根据后序中序建立二叉树 
BiTree createBiTree2(char post[],char in[],int L1,int R1,int L2,int R2){if(L1>R1){return NULL;//递归出口 }BTNode *s =(BTNode*)malloc(sizeof(BTNode));s->lchild =NULL;s->rchild =NULL;                   s->data=post[R1];//后序序列最后一个节点为根节点 int i;//根据中序序列的特性,元素左边的元素属于该节点的左孩子序列,右边则是右孩子序列 for(i=L2;i<=R2;i++){if(post[R1]==in[i]) break;//在中序序列找到该元素 }//递归 面试官:为什么要减去L2? 答:递归传下去的是整个数组,需要根据参数找到递归出口,-L2是缩小查找范围 s->lchild=createBiTree2(post,in,L1,L1+i-L2-1,L2,i-1);s->rchild=createBiTree2(post,in,L1+i-L2,R1-1,i+1,R2); return s;
}
//该函数用于在中序序列中找到key,返回其位置 
//参数含义:in[]:中序序列  key:所要查找元素 L,R:查找范围 
int serach(char in[],char key,int L,int R){for(int i=L;i<=R;i++){if(in[i]==key) return i;}return -1;
}//因为在中序序列元素的左面的元素在层次遍历序列中并不连续,所以需要用子序列函数将并不连续的序列连续起来
//为什么要连续起来?因为需要连续起来才能和中序序列构造出二叉树
//思路:在中序序列里查找到一个范围,从这个范围里遍历元素,在层次遍历序列里找该元素 
//参数含义:sublevel[]:存放子序列数组  level[]:层次遍历序列  in[]:中序序列 n:level层次序列长度 L,R:查找范围 
void getSubLevel(char sublevel[],char level[],char in[],int n,int L,int R){int k=0;for(int i=0;i<n;i++){if(serach(in,level[i],L,R)!=-1)sublevel[k++]=level[i]; }
}
//由中序序列和层次遍历序列构造二叉树 
BiTree createBiTree3(char level[],char in[],int n,int L,int R){if(L>R) return NULL;BTNode *s =(BTNode*)malloc(sizeof(BTNode));s->lchild =NULL;s->rchild =NULL;                   s->data=level[0];int i=serach(in,level[0],L,R);//找到i便可以确定左右子树答大小 int LN=i-L; char LLevel[LN];int RN=R-i; char RLevel[RN];getSubLevel(LLevel,level,in,n,L,i-1);//得到子序列 getSubLevel(RLevel,level,in,n,i+1,R);s->lchild=createBiTree3(LLevel,in,LN,L,i-1);//用子序列递归 s->rchild=createBiTree3(RLevel,in,RN,i+1,R); return s;
}
void visit(BiTree T) {printf("%c  ",T->data);
}
//前序遍历 
void PreOrder(BiTree T){if(T!=NULL){visit(T);//根 PreOrder(T->lchild);//左 PreOrder(T->rchild);//右 }
} 
//中序遍历 
void InOrder(BiTree T){if(T!=NULL){InOrder(T->lchild);visit(T);InOrder(T->rchild);}
}
//后序遍历 
void PostOrder(BiTree T){if(T!=NULL){PostOrder(T->lchild);PostOrder(T->rchild);visit(T);}
} 
//层次遍历 
void level(BiTree T){if(T!=NULL){int front=0;int rear=0;BiTree queue[MaxSize];BiTree p;p=T;rear=(rear+1)%MaxSize;queue[rear]=p;while(rear!=front){front=(front+1)%MaxSize;p=queue[front];visit(p); if(p->lchild!=NULL){rear=(rear+1)%MaxSize;queue[rear]=p->lchild; } if(p->rchild!=NULL){rear=(rear+1)%MaxSize;queue[rear]=p->rchild;}}}
}
int main(){char c[]="ABDECFGH";//前序序列 char d[]="DBEACGFH";//中序序列 char p[]="DEBGHFCA";//后序序列 char l[]="ABCDEFGH";//层次遍历序列 BTNode *r=createBiTree(c,d,0,7,0,7);BTNode *r2=createBiTree2(p,d,0,7,0,7);BTNode *r3=createBiTree3(l,d,8,0,7); printf("前序序列为:"); PreOrder(r);printf("\n");printf("后序序列为:");PostOrder(r2);printf("\n");printf("中序序列为:"); InOrder(r3);printf("\n");printf("层次遍历为:");level(r3); printf("\n");} 

代码运行截图:


http://chatgpt.dhexx.cn/article/LsUtjM39.shtml

相关文章

python实现根据前序序列和中序序列求二叉树的后序序列

根据前序序列求根结点&#xff0c;根据中序序列求左右子树。 如上图&#xff1a;根据前序序列&#xff0c;谁在前面谁就是根结点&#xff1b;根据根结点&#xff0c;确定左右子树。 class BiTreeNode:def __init__(self, data):self.data dataself.lchild Noneself.rchild …

已知二叉树的前序序列跟中序序列求后序序列(C语言)

原理是&#xff0c;比如 先序序列决定二叉树的根结点&#xff08;比如上图的“1”&#xff09;&#xff0c;后序序列决定二叉树的左右子结点&#xff08;比如上图的“4”&#xff0c;“7”&#xff0c;“2”为左子树的那部分&#xff0c;而“8”&#xff0c;“5”&#xff0c;“…

验证二叉树的前序序列化

缩点法验证二叉树的前序序列化 题目解决思路代码说明 题目 &#xff08;1&#xff09;序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时&#xff0c;我们可以记录下这个节点的值。如果它是一个空节点&#xff0c;我们可以使用一个标记值记录&#xff0c;例如 …

验证二叉树的前序序列化Python解法

序列化二叉树的一种方法是使用 前序遍历 。当我们遇到一个非空节点时&#xff0c;我们可以记录下这个节点的值。如果它是一个空节点&#xff0c;我们可以使用一个标记值记录&#xff0c;例如 #。 例如&#xff0c;上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,…

7-1 前序序列创建二叉树

7-1 前序序列创建二叉树 编一个程序&#xff0c;读入用户输入的一串先序遍历字符串&#xff0c;根据此字符串建立一个二叉树&#xff08;以二叉链表存储&#xff09;。 例如如下的先序遍历字符串&#xff1a; ABC##DE#G##F### 其中“#”表示的是空格&#xff0c;代表一棵空树。…

超容易理解的数据结构前序,中序和后序序列

今天听了我们数据结构老师讲三序序列&#xff0c;发现有很多同学不能根据二叉树推&#xff0c;特发此文讲解。 对于三序序列&#xff0c;我们可以选择构造一个表格并创造一个指针&#xff0c;将指针指于二叉树根结点&#xff0c;对应表格则如下所示&#xff0c;若某节点无左孩…

IIC通信协议详解[转载]

IIC的基本介绍 IIC的简介 IIC&#xff08;Inter&#xff0d;Integrated Circuit&#xff09;总线是一种由PHILIPS公司在80年代开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备。它是半双工通信方式。 IIC总线最主要的优点是其简单性和有效性。由于接口直接在组件…

IIC通信协议学习

1.IIC简介 IIC&#xff1a;Inter-Integrated Circuit&#xff08;内部集成电路&#xff09; 需要两个管脚&#xff1a;SDA、SCL SPI协议&#xff1a;一个主设备对多个从设备&#xff0c;每增加一个从设备&#xff0c;需要增加一个端口CS* 特点&#xff1a;速度较快&#xff…

IIC总线设计①——IIC通信协议

目录 一、IIC&#xff08;Inter-Integrated Circuit&#xff09;总线介绍 二、IIC协议 &#xff08;一&#xff09;IIC通信过程 &#xff08;二&#xff09;起始信号和停止信号 程序 &#xff08;三&#xff09;应答信号和非应答信号 程序 &#xff08;四&#xff09;数…

STM32基于IIC通信协议的OLED模块使用(详解)

目录 前言 一、项目内容 实验简介 二、IIC模块 1、IIC协议简介 2、物理层 3、协议层 4、硬件IIC代码配置 5、软件模拟IIC配置 1、起始信号与停止信号 2、从机应答信号 3、数据的有效性 4、数据传输 三、OLED模块 1、软件配置 2、OLED原理 1、OLED初始化函数 …

IIC 通信协议 (一)

目录 引言 IIC协议 1、历史 2、特点 3、信号线 4、主从关系 5、通信过程 6、协议规范 地址 1、器件地址 2、存储器地址 读写时序 1、写时序 1.1、单字节写时序 1.2、连续写时序 2、读时序 2.1、单字节读时序 2.2、连续读时序 参考声明 引言 这个专栏闲置好…

基础通信协议之 IIC (I2C) 详细讲解

IIC是当今嵌入式应用中最常见的串行通信协议之一。对比OneWire严苛的时序要求&#xff0c;SPI等更多的线缆要求&#xff0c;IIC处于一个折中的位置&#xff1a;不那么多的2根线缆的硬件要求&#xff0c;不那么复杂严苛的时序要求&#xff0c;便可进行多主多从的双向通信&#x…

IIC 通信协议 (二)

目录 引言 子模块设计 思路 单字节 IIC 发送模块 思路 Verilog 源码 多字节发送控制模块 思路 Verilog 源码 仿真 思路 test bench 仿真结果 参考声明 引言 本篇博文承接前文&#xff0c;继续做 IIC 通信协议 FPGA实现相关的内容。用Verilog 编写一个 IIC 通信控…

IIC通信协议(硬件实现IIC通信详解I)

IIC通信协议 什么是IIC协议协议层起始信号和停止信号数据的有效性 什么是IIC协议 I2C&#xff08;Inter-Integrated Circuit&#xff09;通讯协议是由 Phiilps 公司开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备。是微电子通信控制领域广泛采用的一种总线标准…

详解通信协议之IIC通信协议

详解通信协议之IIC通信协议 本文结合AT24C02对IIC通信协议原理进行了描述。 IIC通信协议(以AT24C02为例) IIC通讯协议(Inter&#xff0d;Integrated Circuit)是由 Philips 公司开发双向同步半双工串行总线&#xff0c;只需要两根线(SDA、SCL)即可在连接于总线上的器件之间传…

IIC(I2C)通信协议详解

简介 I2C 是飞利浦公司设计的&#xff0c;一种很常见的总线协议&#xff0c; I2C 使用两条线在主控制器和从机之间进行数据通信。一条是 SCL(串行时钟线)&#xff0c;另外一条是SDA(串行数据线)&#xff0c;这两条数据线需要接上拉电阻&#xff0c;总线空闲的时候 SCL 和 SDA …

IIC 通信协议

一、IIC 通信协议介绍 IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备。 如今主要在服务器管理中使用&#xff0c;其中包括单个组件状态的通信。例如管理员可对各个组件进行查询&#xff0c;以管理系统…

三大通信协议(二):IIC通信协议

目录 1. 概念2. 硬件连接3. 数据传输协议3.1 开始信号3.2 地址位3.3 读写位&#xff08;R/W&#xff09;3.4 应答位&#xff08;ACK / NACK&#xff09;3.5 数据位&#xff08;8Bit&#xff09;3.6 停止信号 4. 软件编写4.1 初始化4.2 开始信号4.3 IIC发送一个字节数据4.4 IIC读…

IIC通信协议总结

&#xff08;1&#xff09;概述 I2C(Inter-Integrated Circuit BUS) 集成电路总线&#xff0c;该总线由NXP&#xff08;原PHILIPS&#xff09;公司设计&#xff0c;多用于主控制器和从器件间的主从通信&#xff0c;在小数据量场合使用&#xff0c;传输距离短&#xff0c;任意时…

IIC通信协议,搞懂这篇就够了

注&#xff1a;公众号后台发送 “IIC” 即可获取基于STM32上实现软件模拟IIC的完整代码。 I2C(IIC)属于两线式串行总线&#xff0c;由飞利浦公司开发用于微控制器(MCU)和外围设备(从设备)进行通信的一种总线&#xff0c;属于一主多从(一个主设备(Master)&#xff0c;多个从设备…