【数据结构】实验八:树

news2024/10/7 20:33:41

实验八 树

一、实验目的与要求

1)理解树的定义;

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

二、 实验内容

题目一:采用树的双亲表示法根据输入实现以下树的存储,并实现输入给定结点的双亲结点的查找。

双亲表示法的存储结构描述如下

#define MaxSize 100  //树中最多结点数

typedef struct{  //树的结点定义

    char data;  //数据元素

    int parent;  //双亲位置域

}PTNode;

typedef struct{  //树的类型定义

    PTNode nodes[MaxSize];  //双亲表示

    int n;  //结点数

}PTree;

提示:一组连续空间来存储每个结点,同时在每个结点中增设一个伪指针,指示其双亲结点在数组中的位置。根结点的下标为0,其伪指针域为-1。

示列:

 

 

题目二:采用树的孩子表示法,实现以上树的存储,要求实现输入结点查找输出该结点的所有孩子结点,没有孩子结点输出-1。(选做)

存储结构描述

#define MaxSize 100

typedef struct ChildNode{ //链表中每个结点的定义

    //链表中每个结点存储的不是数据本身,而是数据在数组中存储的位置下标

    int child;

    struct ChildNode *next;

}ChildNode;

typedef struct{  //树中每个结点的定义

    char data;  //结点的数据类型

    ChildNode *firstchild;  //孩子链表头指针

}CHNode;

typedef struct{

    CHNode nodes[MaxSize];  //存储结点的数组

    int n;

}CTree;

示列:

三、实验结果

1)请将调试通过的运行结果截图粘贴在下面,并说明测试用例和运行过程。

2)请将源代码cpp文件和实验报告一起压缩上传。


第一题:

运行结果:

 

测试用例和运行过程:

如第一题A图和B图所示,测试用例为该树,各个结点对应的dataparent分别为{ (R,-1) , (A,0) , (B,0) , (C,0) , (D,1) , (E,1) , (F,3) , (G,6) , (H,6) , (K,6) }  

主函数首先创建一个树,通过构造树函数CreateTree依次录入结点的值及其双亲位于数组中的位置下标,再输入需要查询的结点值,通过查找结点函数SearchNode中的for循环遍历各个结点,当且仅当结点值匹配时,输出其父结点和存储位置,然后跳出循环。

最终结果如运行截图所示。

实验代码:

#include <iostream>
#include <cstdio>
using namespace std;

#define MaxSize 100  //树中最多结点数
typedef struct{  //树的结点定义
    char data;  //数据元素
    int parent;  //双亲位置域
}PTNode;

typedef struct{  //树的类型定义
    PTNode nodes[MaxSize];  //双亲表示
    int n;  //结点数
}PTree;

//构造树 
void CreateTree(PTree *T){
	int i=0;
	cout<<"请输入结点个数:"<<endl;
	cin>>T->n ;
	cout<<"请输入结点的值及其双亲位于数组中的位置下标:"<<endl;
	for( ;i<T->n ;i++){ 
		cin>>T->nodes[i].data>>T->nodes[i].parent ;
	}
	return;
}

//查找结点信息 
void SearchNode(PTree *T,char e){
	int i=0,flag=0;
	for( ;i<T->n ;i++){
		if(T->nodes[i].data ==e){
			flag=1;
			cout<<e<<"的父结点为:"<<T->nodes[T->nodes[i].parent].data<<endl;
			cout<<"存储位置为:"<<T->nodes[i].parent <<endl;
			break;
		}
	}
	if(flag==0){
		cout<<"NOT FOUND"<<endl;
	}
}

int main(){
	PTree T;
	CreateTree(&T);
	cout<<"请输入要查询的结点值:";
	char element;
	cin>>element;
	SearchNode(&T,element);
	return 0;
}

第二题:

运行结果:

 

测试用例和运行过程:

如第二题的图所示,测试用例为该树,只有RACF结点具有孩子结点,其余均为叶子结点。

主函数首先创建一个树,通过构造树函数CreateTree,首先录入结点的总数,再通过外层for循环依次输入每一个结点的值、当前结点的孩子结点数量,紧接着通过内层for循环依次输入当前结点的孩子结点在顺序表中存储的位置,最终完成树的创建。然后通过查找孩子结点函数SearchChild,输入要查找其孩子结点的结点,通过for循环查找元素一致的结点,确定之后判断孩子是否为空,若非空则通过while循环输出每一个非空的孩子结点。

最终结果如运行截图所示。

实验代码:

#include <iostream>
#include <cstdio>
#include <malloc.h>
using namespace std;

#define MaxSize 100
typedef struct ChildNode{ //链表中每个结点的定义
    //链表中每个结点存储的不是数据本身,而是数据在数组中存储的位置下标
    int child;
    struct ChildNode *next;
}ChildNode;
 
typedef struct{  //树中每个结点的定义
    char data;  //结点的数据类型
    ChildNode *firstchild;  //孩子链表头指针
}CHNode;
 
typedef struct{
    CHNode nodes[MaxSize];  //存储结点的数组
    int n;
}CTree;

//实现输入结点查找输出该结点的所有孩子结点,没有孩子结点输出-1

//创建树 
void CreateTree(CTree *T){
	cout<<"请输入结点总数:";
	cin>>T->n;
	int i=0;
	for( ;i<T->n;i++){
		cout<<"请输入第"<<i+1<<"个结点的值:";
		cin>>T->nodes[i].data;
		cout<<"请输入该结点的孩子结点数量:";
		int num;
		cin>>num;
		ChildNode *m=NULL;
		int j=0;
		for( ;j<num;j++){
			ChildNode *s=(ChildNode *)malloc(sizeof(ChildNode)); 
			cout<<"请输入第"<<j+1<<"个孩子结点在顺序表中的存储位置:";
			cin>>s->child;
			s->next = NULL;
			if(j==0){
				T->nodes[i].firstchild = s;
				m=s;
			}
			else{
				m->next = s;
				m=s;
			}
		}
	}
}

//查找孩子结点 
void SearchChild(CTree *T){
	char e;
	cout<<"请输入要查找其孩子结点的结点:";
	cin>>e;
	int flag=-1,i=0;
	for( ;i<T->n ;i++){
		if(T->nodes[i].data == e){
			flag=i;
			break;
		}
	} 
	if(flag==-1){
		cout<<"Not Found"<<endl;
		return;
	}
	ChildNode *p=T->nodes[flag].firstchild;
	if(p==NULL){
		cout<<"此结点为叶子结点"<<endl;
		return;
	}
	cout<<e<<"的所有孩子结点为:";
	while(p!=NULL){
		cout<<T->nodes[p->child].data<<" ";
		p=p->next;
	}
}

int main(){
	CTree T;
	int i=0;
	CreateTree(&T);
	SearchChild(&T);
	return 0;
}

其他:

#include<iostream>
using namespace std;

#define MaxSize 100  //树中最多结点数

typedef struct{  //树的结点定义
    char data;  //数据元素
    int parent;  //双亲位置域
}PTNode;

typedef struct{  //树的类型定义
    PTNode nodes[MaxSize];  //双亲表示
    int n;  //结点数
}PTree;

void Parent_PT(PTree &ptree,char m){
	int i;
	for(i=0;(i<ptree.n)&&(ptree.nodes[i].data!=m);i++);
	if(i>=ptree.n) 	cout<<"Node -"<<m<<" is not exist!"<<endl;
	else{
		int j=ptree.nodes[i].parent;
    	if(j==-1)
    	cout<<"Node -"<<m<<" has not parent!"<<endl;
    	else{
     		cout<<m<<"的父结点为:"<<ptree.nodes[j].data<<endl;
        	cout<<ptree.nodes[j].data<<"的储存位置为:"<<j<<endl;
        }
	}
}

int main(){
	PTree ptree;
	cout<<"请输入结点个数:";
	int num;cin>>num;
	ptree.n=num;
	cout<<"请输入结点的值以及双亲位于数组中的位置下标:"<<endl;
	char m;int q; 
	for(int i=0;i<num;i++){
		cin>>m;cin>>q;
		ptree.nodes[i].data=m;
        ptree.nodes[i].parent=q;
	}
	while(1){
    	cout<<"请输入要查询的结点值:";
    	cin>>m;
    	if(m=='#'){
    		cout<<"查询结束!";
			break; 
		} 
    	Parent_PT(ptree,m);	
	} 
	return 0;
} 

#include<iostream>
using namespace std;

#define MaxSize 100

typedef struct ChildNode{ //链表中每个结点的定义
    //链表中每个结点存储的不是数据本身,而是数据在数组中存储的位置下标
    int child;
    struct ChildNode *next;
}ChildNode;

typedef struct{  //树中每个结点的定义
    char data;  //结点的数据类型
    ChildNode *firstchild;  //孩子链表头指针
}CHNode;

typedef struct{
    CHNode nodes[MaxSize];  //存储结点的数组
    int n;
}CTree;

void Init_tree(CTree &ctree){
	cout<<"请输入结点总数:";
	int num;cin>>num;
	ctree.n=num;
	for(int i=0;i<num;i++){
		cout<<"请输入第"<<i+1<<"个结点的值:";
		char m;cin>>m;
		ctree.nodes[i].data=m;
		ctree.nodes[i].firstchild=NULL;
		cout<<"请输入结点"<<m<<"的孩子结点数:";
		int cnum;cin>>cnum;
		if(cnum==0) continue;
		cout<<"请输入第1个孩子结点在顺序表中的存储位置:";
		int l;cin>>l;
		ChildNode *p=new ChildNode;
		p->child=l;
		p->next=NULL;
		ctree.nodes[i].firstchild=p;
		for(int j=1;j<cnum;j++){
			cout<<"请输入第"<<j+1<<"孩子结点在顺序表中的存储位置:";
			cin>>l;
			ChildNode *q=new ChildNode;
			q->child=l;
			q->next=NULL;
			p->next=q;
			p=q;
		}
	}
}

void Children(CTree &ctree,char f){
	int j;
	for(j=0;(j<ctree.n)&&(ctree.nodes[j].data!=f);j++);
	if(j>=ctree.n) cout<<"Node -"<<f<<" is not exist!";
	else{
		ChildNode *p=ctree.nodes[j].firstchild;
		if(!p) cout<<"Node -"<<f<<" has not children!";
		else{
			cout<<f<<"的所有孩子结点为: ";
			cout<<ctree.nodes[p->child].data<<" ";
			while(p->next!=NULL){
				p=p->next;
		    	cout<<ctree.nodes[p->child].data<<" ";
			}
		}
	}
}

void Destroy(CTree &ctree){
	for(int i=0;i<ctree.n;i++){
		ChildNode *p=ctree.nodes[i].firstchild;
		ChildNode *q;
		if(!p) continue;
		while(p){
			q=p;
			p=p->next;
			q->next=NULL;
			delete q;
		}
		ctree.nodes[i].firstchild=NULL;
	}
} 

int main(){
	CTree ctree;
	Init_tree(ctree);//初始化 
	while(1){
		cout<<"--------------------------------------"<<endl;
    	cout<<"请输入要查找其孩子结点的结点:"; 
    	char f;cin>>f;
    	if(f=='#'){
    		cout<<"查询结束!";
			break; 
		} 
    	Children(ctree,f);	
    	cout<<endl;
	}
	Destroy(ctree);//释放new出的空间 
	return 0;
} 

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

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

相关文章

实验二十五、压控振荡电路的测试

一、题目 研究压控振荡电路输出波形频率随输入电压幅度的变化。 二、仿真电路 仿真电路如图1所示。集成运放采用 LM324AJ&#xff0c;其电源电压为 15 V。输入直流电压采用虚拟电压源&#xff0c;锯齿波才用函数发生器产生的锯齿波输出。 三、仿真内容 &#xff08;1&…

[自然语言处理] 自然语言处理库spaCy使用指北

spaCy是一个基于Python编写的开源自然语言处理库。基于自然处理领域的最新研究&#xff0c;spaCy提供了一系列高效且易用的工具&#xff0c;用于文本预处理、文本解析、命名实体识别、词性标注、句法分析和文本分类等任务。 spaCy的官方仓库地址为&#xff1a;spaCy-github。本…

mysql的整体架构

服务层-引擎层-硬盘层 一条语句执行的整体过程: 先建立连接&#xff08;mysql -h -p 密码&#xff09;–预处理-词法分析-语法分析-优化器选择用什么索引表如何连接等-执行器 到这里都是属于server层&#xff0c;大多数功能包括视图&#xff0c;存储过程&#xff0c;触发器都是…

透明屏能在商业广告中使用吗?

透明屏是一种新型的显示技术&#xff0c;它可以将图像或文字显示在透明的玻璃或塑料材料上&#xff0c;使得观看者可以同时看到背后的物体。 这种技术在商业广告、展览、零售和家庭娱乐等领域有着广泛的应用前景。 首先&#xff0c;透明屏可以用于商业广告。传统的广告牌通常…

100个网络安全测试面试题

1、Burpsuite常用的功能是什么&#xff1f; 2、reverse_tcp和bind_tcp的区别&#xff1f; 3、拿到一个待检测的站或给你一个网站&#xff0c;你觉得应该先做什么&#xff1f; 4、你在渗透测试过程中是如何敏感信息收集的&#xff1f; 5、你平时去哪些网站进行学习、挖漏洞提交到…

React 前端应用中快速实践 OpenTelemetry 云原生可观测性(SigNoz/K8S)

OpenTelemetry 可用于跟踪 React 应用程序的性能问题和错误。您可以跟踪从前端 web 应用程序到下游服务的用户请求。OpenTelemetry 是云原生计算基金会(CNCF)下的一个开源项目&#xff0c;旨在标准化遥测数据的生成和收集。已成为下一代可观测平台的事实标准。 React(也称为 Re…

基于物联网、视频监控与AI视觉技术的智慧电厂项目智能化改造方案

一、项目背景 现阶段&#xff0c;电力行业很多企业都在部署摄像头对电力巡检现场状况进行远程监控&#xff0c;但是存在人工查看费时、疲劳、出现问题无法第一时间发现等管理弊端&#xff0c;而且安全事件主要依靠人工经验判断分析、管控&#xff0c;效率十分低下。 为解决上述…

一文了解什么是Selenium自动化测试?

目录 一、Selenium是什么&#xff1f; 二、Selenium History 三、Selenium原理 四、Selenium工作过程总结&#xff1a; 五、remote server端的这些功能是如何实现的呢&#xff1f; 六、附&#xff1a; 一、Selenium是什么&#xff1f; 用官网的一句话来讲&#xff1a;Sel…

Vue2基础六、组件通信

零、文章目录 Vue2基础六、组件通信 1、组件通信 &#xff08;1&#xff09;组件通信是什么 组件通信, 就是指 组件与组件 之间的数据传递。 组件的数据是独立的&#xff0c;无法直接访问其他组件的数据。 想使用其他组件的数据&#xff0c;就需要组件通信 &#xff08;…

QTday2信号和槽

点击登录按钮,关闭Widget登录窗口,打开QQList窗口 widget.cpp #include "widget.h"void my_setupUI(Widget *w);Widget::Widget(QWidget *parent): QWidget(parent) {my_setupUI(this); }Widget::~Widget() { }void Widget::login_slots() {//fixemit jump_signal(…

Springboot+MyBatis使用

目录 依赖 配置信息 xml文件 mapper接口 打印日志 分页查询 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><dependency><groupId>my…

SpringBoot集成 Swagger

Spring Boot 集成 Swagger 在线接口文档 1、Swagger 简介 1.1 解决的问题 随着互联网技术的发展&#xff0c;现在的网站架构基本都由原来的后端渲染&#xff0c;变成了前后端分离的形态&#xff0c;而且前端技术和后端技术在各自的道路上越走越远。前端和后端的唯一联系变成…

LeetCode647.Palindromic-Substrings<回文子串>

题目&#xff1a; 思路&#xff1a; 错误代码&#xff1a;&#xff08;缺少部分判断&#xff09; 使用的是寻找回文子串的方法。以一个点为中心向两边扫描。但是有一点小问题。 因为回文子串是分奇偶的&#xff0c;所以需要两种判断方式。 看了下答案后发现我的代码距离答案一…

创建一个简单的 Servlet 项目

目录 1.首先创建一个 Maven 项目 2.配置 maven 仓库地址 3.添加引用 4.配置路由文件 web.xml 5.编写简单的代码 6.配置 Tomcat 7.写入名称,点击确定即可 8.访问 1.首先创建一个 Maven 项目 2.配置 maven 仓库地址 3.添加引用 https://mvnrepository.com/ 中央仓库地址…

入门篇——了解数据库

一、数据库是什么&#xff1f; 数据库是存放数据的仓库。它的存储空间很大&#xff0c;可以存放百万条、千万条、上亿条数据。但是数据库并不是随意地将数据进行存放&#xff0c;是有一定的规则的&#xff0c;否则查询的效率会很低。当今世界是一个充满着数据的互联网世界&…

给jupter设置新环境

文章目录 给jupternotebook设置新环境遇到的报错添加路径的方法 给jupternotebook设置新环境 # 先在anaconda界面新建环境 conda env list # 查看conda prompt下的有的环境变量 带星号的是当前活跃的 activate XXXX pip install ipykernel ipython ipython kernel install --u…

AI编程常用工具 Jupyter Notebook

点击上方蓝色字体&#xff0c;选择“设为星标” 回复”云原生“获取基础架构实践 深度学习编程常用工具 我们先来看 4 个常用的编程工具&#xff1a;Sublime Text、Vim、Jupyter。虽然我介绍的是 Jupyter&#xff0c;但并不是要求你必须使用它&#xff0c;你也可以根据自己的喜…

C++中deque的底层讲解

1.前言 1.了解过queue和stack底层的或许了解过&#xff0c;库里面的底层实现&#xff0c;选择的默认容器就是deque&#xff0c;那他有什么好处呢&#xff1f; 2.先前了解过deque的接口会发现&#xff0c;他感觉像是vector和list的合体&#xff0c;什么接口都有&#xff1a; 很…

14.Netty源码之模拟简单的HTTP服务器

highlight: arduino-light 简单的 HTTP 服务器 HTTP 服务器是我们平时最常用的工具之一。同传统 Web 容器 Tomcat、Jetty 一样&#xff0c;Netty 也可以方便地开发一个 HTTP 服务器。我从一个简单的 HTTP 服务器开始&#xff0c;通过程序示例为你展现 Netty 程序如何配置启动&a…

CMU 15-445 -- Logging Schemes - 17

CMU 15-445 -- Logging Schemes - 17 引言IndexFailure ClassificationTransaction FailuresSystem FailuresStorage Media Failures Buffer Pool PoliciesShadow Paging: No-Steal ForceWrite-Ahead Log (WAL): Steal No-ForceLogging SchemesCheckpoints小结 引言 本系列为…