【数据结构】实验九:二叉树

实验九 二叉树

一、实验目的与要求

1)理解二叉树的类型定义;

2掌握二叉树的存储方式及基于存储结构的基本操作实现;

二、 实验内容

1. 二叉树的结点定义如下:

struct TreeNode

{

int m_nvalue;

TreeNode* m_pLeft;

TreeNode* m_pRight;

};

输入二叉树中的两个结点,输出这两个结点在树中的最近公共祖先结点。

说明:最近公共祖先定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个结点也可以是它自己的祖先)。

2. 某同学非常喜欢玩二叉树。最喜欢的游戏是用结点中的大写字母构造查找二叉树。这是他构造的二叉树:

他为每棵树写下先序遍历和中序遍历两个字符串,例如:对于上面构造的树,先序遍历为DBACEGF中序遍历为ABCDEFG几年后,他想重新构造这棵树,请你来编写一个程序帮他实现基于上述遍历序列构造树。

题意解析:根据所给的两串序列,分别是前序和中序,求出二叉树的后序。

三、实验结果

1)简述算法步骤:

2)分析算法时间复杂度:

 


题目1:

0 实验代码及结果

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;#define Max 100
vector<int> E[Max]; 
int parent[Max];     
int depth[Max];     //构造递归的树  v->当前结点 p->当前的双亲结点 d->当前结点深度 
void BuildTree(int v,int p,int d){parent[v]=p;depth[v]=d;for(int i=0;i<E[v].size();i++){if(E[v][i]!=p){BuildTree(E[v][i],v,d+1);}}
}//lowest common ancestor的寻找函数 
int LCA(int u,int v){//深度不同时,用双亲结点替换 while(depth[u]!=depth[v]){if(depth[v]<depth[u]){u=parent[u];}else{v=parent[v];}}//同深度时,同时迭代寻找ancestor while(u!=v){u=parent[u];v=parent[v];}return v;//返回公共祖先 
}int main(){int n,root=1;//n->总结点数  root->根结点 //root需要定义!!!!!!!!!!!!! cout<<"请输入总结点数:"<<endl;cin>>n;if(n==1){cout<<"输入错误!不能只有一个结点!"<<endl;return 0;}//i<n-1 根结点无双亲,所以少输入一次 for(int i=0;i<n-1;i++){int u,v;cout<<"请输入双亲结点编号及其孩子结点编号:"<<endl;cin>>u>>v;E[u].push_back(v);E[v].push_back(u);  }BuildTree(root,-1,0);//根结点双亲为-1,深度为0 int u,v;cout<<"请输入两个待测结点的编号:" <<endl;cin>>u>>v;cout<<"其LCA为:"<<LCA(u,v)<<endl;return 0;
}

实验报告测试用例的二叉树如下图所示:

 代码测试结果如下图所示:

 

 

 

1 简述算法步骤

    定义存储当前结点数据、双亲结点、当前结点深度的数组,并规定最大范围为100。

    构造递归结构存储的数,存储当前结点的双亲结点和深度,然后通过for循环遍历,利用递归构造子树。在for循环中,如果遍历发现当前结点与双亲结点不同,即当前结点不是叶子结点,那么继续调用BuildTree函数构造子树,并将当前深度加一。

 

    寻找最近公共祖先时,先判断两个结点的深度是否相同。如果深度不同,则先回溯深度较深的结点,寻找其与另外一个结点深度相同时的祖先。回溯完以后,此时u、v深度相同,直接比较u、v结点是否相同。如果结点不同,则分别向上回溯一个祖先,再判断其祖先是否相同。最后两个结点回溯到相同值,返回其中一个结点即可。

    最后通过vector自带函数和for循环,将预设的树进行入栈并构造。

 

2 分析算法时间复杂度

    在利用递归创建树时,利用了for循环遍历双亲合集,来判断当前结点的双亲结点是否已经被存入。由此可见,时间复杂度为O(n^2)。

    在LCA函数中,通过第一个while循环收缩较远结点的深度进行回溯,通过第二个while循环同时收缩两个结点的深度进行回溯。由此可见,时间复杂度均为O(n)。

    在主函数输入预设树的基本信息时,利用了for循环将每一组【双亲结点+孩子结点】存入vector中。由此可见,时间复杂度为O(n)。

 

题目2:

0 实验代码及结果

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;typedef struct Node{char data;//数据域 struct Node *lchild,*rchild;//左孩子结点+右孩子结点 
}Node,*BiTree;char PreString[30],InString[30];//先序和中序遍历字符串 maxsize=30 //根据先序+中序,重新构造原来的树,即BiTree T = new Node(); 
BiTree Build(char *PreString,char *InString,int s1,int e1,int s2,int e2){//s:start e:end BiTree T = new Node();T -> data = PreString[s1];int rootIdx;//根结点所在序号for(int i = s2;i <= e2;i++){if(PreString[s1] == InString[i]){rootIdx = i;//寻找先序字符串中当前元素在中序字符串中的位置 break;//寻觅结束 }}int llen = rootIdx - s2;//左 为 根-初始 int rlen = e2 - rootIdx;//右 为 len(in)-根 if(llen != 0){//左 非空 T -> lchild = new Node();T -> lchild = Build(PreString,InString,s1 + 1,s1 + llen,s2,s2 + llen - 1);//继续在左子树里面重复上述操作;//prestring: start=s1+1; end=s1+llen//instring: start=s2; end=s2+llen-1 }else{T -> lchild = NULL;}if(rlen != 0){//右 非空 T -> rchild = new Node();T -> rchild = Build(PreString,InString,e1 - rlen + 1,e1,e2 - rlen + 1,e2);//继续在右子树里面重复上述操作;//pre: start=e1-rlen+1; end=e1//in: start=e2-rlen+1; end=e2}else{T -> rchild = NULL;}return T;
}//后序遍历 -> 递归输出 
void PostOrder(BiTree T){if(T != NULL){ //树非空 PostOrder(T -> lchild); //走左子树 PostOrder(T -> rchild); //走右子树 cout<<T -> data; //走根 or 叶子结点 }
}int main(){cout<<"请输入先序遍历字符串:";cin>>PreString;cout<<"请输入中序遍历字符串:";cin>>InString;BiTree T = NULL; //构建空树 int e1=strlen(PreString)-1,e2=strlen(InString)-1;//两个字符串下标位数 T = Build(PreString,InString,0,e1,0,e2); //通过先序遍历+中序遍历推断树结构 cout<<"此二叉树的后序遍历为:";PostOrder(T);//后序遍历输出该树 return 0;
}

题干给的先序遍历+中序遍历构成的二叉树如下图所示:

代码测试结果如下图所示:

 

 

1 简述算法步骤

构造一个二叉树,属性携带当前结点数据、当前结点左孩子指针和当前结点右孩子指针。

根据先序遍历【根->左子树->右子树】的特点可知,先序遍历字符串中的第一个结点必然为根,然后通过for循环在中序遍历字符串中寻找与当前结点数据相同的结点,并锁定其在中序遍历字符串中的位置为rootIdx。此时,在中序遍历字符串中,rootIdx左侧的字符串为左子树的内容,rootIdx右侧的字符串为右子树的内容。同时回溯到先序遍历字符串中,可锁定左子树的始末下标和右子树的始末下标。

根据树的定义,每一个子树可作为一棵新的树。于是我们将左子树和右子树分别看作新的两个树,确定好新的prestring和instring起始下标之后,重新进行上述操作来确定整个树的空间结构,直至左子树或右子树为空树。最后返回整个树。

在确定整个树的空间结构后,通过递归的后序遍历法【左子树->右子树->根】输出整个树的结点数据。

最后通过主函数依次调用上述算法函数。

2 分析算法时间复杂度

在寻找先序字符串中当前元素在中序字符串中的位置的时候,使用了for循环遍历instring里面的所有结点数据。由此可见,时间复杂度为O(n)。整个递归调用的时间复杂度为O(n logn)。

    前俩个递归调用的时候,均通过二分法处理两个遍历字符串,从而进行下一次函数调用。第三个递归调用的时候,也与上述两个递归类似,先通过锁定根结点,分为左子树和右子树继续遍历。由此可见,时间复杂度均为O(n/2)。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11036.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多源BFS-- 矩阵距离

关于多源BFS&#xff0c;基本上就是单源BFS的简单升级了一下&#xff0c;比如在queue中队头开始时只有一个&#xff0c;我们通过这一个队头去推导其他的东西。而多源最短路就是队头一开始有1-n个可能的数&#xff0c;一个一个去BFS。 题目思路&#xff1a; 这个题就直接把所有的…

分享69个Java源码,总有一款适合您

Java源码 分享69个Java源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c;大家下载后可以看到。 源码下载链接&#xff1a; https://pan.baidu.com/s/1ZgbJhMNwIyFyqFzHsDdL5w 提取码&a…

excel添加列匹配对比及标签生成(留存)

import pandas as pd import numpy as np import os from datetime import date,datetime todaydate.today()downpath/Users/kangyongqing/Downloads/ gensuipath/Users/kangyongqing/Documents/kangyq/202209/OKR预占/2023Q2促留存/月度留存分级/24样本学生跟随.xlsxdownname1…

WPF实战学习笔记17-TodoView 添加新增、编辑、查询功能

文章目录 TodoView 添加新增、编辑、查询功能修改TodoViewModel.cs修改XAML修改ToDoService TodoView 添加新增、编辑、查询功能 修改TodoViewModel.cs using Mytodo.Common.Models; using Mytodo.Service; using Prism.Commands; using Prism.Ioc; using Prism.Mvvm; using …

WebSocket心跳机制(笔记大全)

一、WebSocket心跳机制前端 前端实现WebSocket心跳机制的方式主要有两种&#xff1a; 使用setInterval定时发送心跳包。在前端监听到WebSocket的onclose()事件时&#xff0c;重新创建WebSocket连接。 第一种方式会对服务器造成很大的压力&#xff0c;因为即使WebSocket连接正…

HummerRisk V1.3.0 发布

HummerRisk V1.3.0发布&#xff1a; 大家好&#xff0c;HummerRisk 1.3.0和大家见面了&#xff0c;在这个版本中我们继续在多云接入管理、多云检测方式、云资源态势方面提供新的能力&#xff0c;并增加了新的镜像仓库支持类型&#xff0c;并优化了云的区域选择、优化规则组内容…

C#时间轴曲线图形编辑器开发1-基本功能

目录 一、前言 1、简介 2、开发过程 3、工程下载链接 二、基本功能实现 1、绘图面板创建 &#xff08;1&#xff09;界面布置 &#xff08;2&#xff09;显示面板代码 &#xff08;3&#xff09; 面板水平方向、竖直方向移动功能实现 &#xff08;4&#xff09;面板放…

【数据结构】实验五:栈

实验五 栈 一、实验目的与要求 1&#xff09;熟悉栈的类型定义和基本操作&#xff1b; 2&#xff09;灵活应用栈解决具体应用问题。 二、实验内容 1、判断回文数&#xff0c;回文是指正读反读均相同的字符序列&#xff0c;如“1221”和“12321”均是回文&#xff0c;但“…

与传统透明屏相比,BOE透明屏有哪些特点优势?

BOE透明屏是一种新型的显示技术&#xff0c;它能够实现透明度高达90%以上的显示效果。这种屏幕可以应用于各种领域&#xff0c;如商业展示、智能家居、汽车行业等&#xff0c;具有广阔的市场前景。 BOE透明屏采用了先进的光学技术&#xff0c;通过控制光的传播和折射&#xff…

自建纯内网iot平台服务,软硬件服务器全栈实践

基于以下几个考虑&#xff0c;自制硬件设备&#xff0c;mqtt内网服务器。 1.米家app不稳定&#xff0c;逻辑在云端或xiaomi中枢网关只支持少部分在本地计算。 2.监控homeassistant官方服务有大量数据交互。可能与hass安装小米账户有关。 3.硬件&#xff1a;原理图&#xff0c;l…

linux信号介绍

信号介绍 信号的概念 信号是信息的载体&#xff0c;Linux/UNIX 环境下&#xff0c;古老、经典的通信方式&#xff0c; 现下依然是主要的通信手段。 信号在我们的生活中随处可见&#xff0c;例如&#xff1a; 古代战争中摔杯为号&#xff1b; 现代战争中的信号弹&#x…

【KVC补充 Objective-C语言】

一、KVC补充 好,那么接下来,再给大家说一下这个KVC 1.首先我们说,这个KVC,就是指的什么 key value coding 吧 全称就是叫做(Key Value Coding),这是它的全称 那么,你在帮助文档里面搜的时候,你就搜key-value coding 是不是这个啊,key-value coding 然后点击,进…

Unity XML3——XML序列化

一、XML 序列化 ​ 序列化&#xff1a;把对象转化为可传输的字节序列过程称为序列化&#xff0c;就是把想要存储的内容转换为字节序列用于存储或传递 ​ 反序列化&#xff1a;把字节序列还原为对象的过程称为反序列化&#xff0c;就是把存储或收到的字节序列信息解析读取出来…

尚医通06:数据字典+EasyExcel+mongodb

内容介绍 1、数据字典列表前端 2、EasyExcel介绍、实例 3、数据字典导出接口、前端 4、数据字典导入接口、前端 5、数据字典添加redis缓存 6、MongoDB简介 7、MongoDB安装 8、MongoDB基本概念 数据字典列表前端 1、测试问题 &#xff08;1&#xff09;报错日志 &am…

SpringBoot复习:(4)打成的jar包是如何启动的?

jar包通过MANIFEST的Main-Class指定了主类JarLauncher, JarLauncher的main方法代码如下&#xff1a; 其中调用的launch的代码如下&#xff1a; 首先&#xff0c;创建了一个自定义的ClassLoader,代码如下&#xff1a; 其中调用的重载的createClassLoader代码如下&#xff1…

STM32MP157驱动开发——按键驱动(中断)

文章目录 编写使用中断的按键驱动程序编程思路设备树相关驱动代码相关 代码修改设备树文件gpio_key_drv.cMakefile编译测试 编写使用中断的按键驱动程序 对于使用中断的按键驱动&#xff0c;内核自带的驱动程序 drivers/input/keyboard/gpio_keys.c 就可以&#xff0c;需要做的…

对gpt的简单认识

1.gpt是什么&#xff1f; GPT&#xff08;Generative Pre-trained Transformer 生成式预训练Transformer模型&#xff09;是一种基于Transformer架构的预训练语言模型&#xff0c;由OpenAI开发。GPT模型以无监督学习的方式使用大规模语料库进行预训练&#xff0c;并具有生成文…

cpolar内网穿透工具

文章目录 cpolar内网穿透工具 cpolar内网穿透工具 科学技术的发展日新月异&#xff0c;电子设备在人们的生活中已成为不可或缺的工具&#xff0c;甚至在很多情况下&#xff0c;各类型的电子设备已经成为工作的核心&#xff0c;虽然移动设备越来越小巧&#xff0c;功能也越来越…

基于netlify生成custom SSL certificate

&#xff08;1&#xff09;腾讯云申请 &#xff08;2&#xff09;域名控制台解析 &#xff08;3&#xff09;Nginx下载&#xff08;crt: CA certificate Chain)

课程27:API接口请求日志【后端】

🚀前言 本文是《.Net Core从零学习搭建权限管理系统》教程专栏的课程(点击链接,跳转到专栏主页,欢迎订阅,持续更新…) 专栏介绍:以实战为线索,基于.Net 7 + REST + Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。 专栏适用于人群:We…