西南交通大学【数据结构实验8】

实验内容及要求: 

编写控制台应用程序,提供以下菜单项:

  1. 插入元素

从键盘输入若干两两互不相同的非0整数,直到输入0时停止。将输入的所有非0整数按输入次序插入二叉排序树(初始时是空树)。

插入某个非0整数时,若该整数已在二叉排序树中,则插入该整数失败(应显示提示信息)。

全部整数插入结束后,显示成功插入的整数个数。

  1. 删除元素

输入一个整数,若它在二叉排序树中,则删除它(提示删除成功与失败)。

  1. 输出

输出二叉排序树的先序和中序递归遍历结点访问次序。

  1. 结束程序

实验目的:掌握二叉排序树插入、删除元素的基本算法。

数据结构设计简要描述:

将int型作为此次实验的关键字,通过自定义二叉排序树节点结构存储二叉排序树

// 将int作为元素类型typedef int elem;// 自定义二叉排序树节点类型typedef struct node{elem data;// 左子树 右子树struct node* lchild, * rchild;}BSTNode, * BSTree;

算法设计简要描述:

创建二叉排序树采用逐个读取value值创建二叉排序树节点,然后逐个插入进二叉树。在插入时先判断此节点的值是否已存在,若存在则插入失败并释放该节点空间。若不存在则通过逐个与树中各节点比较值大小不断向下,得到插入位置,进行节点的插入。

删除节点时先对预删除的节点的值进行查找,若查找失败则删除失败。若查找成功则分为三种情况删除:左右子树均存在、只存在左子树或右子树、叶子结点。后两种情况较为简单不需复杂的变换:叶子结点直接删除,只有一方子树的将子树接到删除节点位置即可。若是左右子树均存在,需找到删除节点左子树中的最大值节点,将此节点接到删除节点的位置,将删除节点的右子树接到此节点的右子树上。

遍历操作采用中序递归遍历和先序递归遍历。

输入/输出设计简要描述:

输入:直接在控制台输入全部整数,两两之间用空格间隔,以0作为结尾代表输入结束。

输出:根据输入操作的不同将不同的结果展示在控制台

编程语言说明:

    使用Visual Studio Code编程。 主要代码采用C语言实现 ;动态存储分配采用C++的new和delete操作符实现;输入与输出采用C++的文件流对象和cout流;程序注释采用C/C++规范。  

主要函数说明:

// 在二叉排序树中查找BSTNode* SearchBST(BSTree bt, elem key);// 在二叉排序树中插入void Insert(BSTree& bt, BSTNode* p, int& count);// 创建二叉排序树void CreBst(BSTree& bt);// 删除二叉排序树中的节点void erase(BSTree& bt, elem key);// 中序递归遍历void Inorder(BSTree T);// 先序递归遍历void Preorder(BSTree T);// 删除功能void Delete(BSTree& bt);// 释放二叉排序树空间void clear(BSTree& bt);

程序测试简要报告:

测试样例(1)

程序输入

二叉排序树示意图

功能测试

结论

程序输出结果与期望输出结果相符。

测试样例(2)

程序输入

二叉排序树示意图

功能测试

结论

程序输出结果与期望输出结果相符。

源程序代码:

#include <iostream>using namespace std;// 将int作为元素类型typedef int elem;// 自定义二叉排序树节点类型typedef struct node{elem data;// 左子树 右子树struct node* lchild, * rchild;}BSTNode, * BSTree;// 在二叉排序树中查找BSTNode* SearchBST(BSTree bt, elem key) {// 若bt不为空且bt不是要查找的值while (bt && bt->data != key){// 如果key比bt小则转到左子树if (key < bt->data) {bt = bt->lchild;}else {// 否则转到右子树bt = bt->rchild;}}// 返回bt 若返回的是NULL则表示未找到return bt;}// 在二叉排序树中插入void Insert(BSTree& bt, BSTNode* p, int& count) {// bt为二叉排序树 p为要插入的节点 count记录已插入的个数// flag为查找p的值是否已在排序二叉树中 若为NULL表示不在可以插入BSTNode* flag = SearchBST(bt, p->data);if (!flag) {// parent为双亲节点BSTNode* parent = NULL;// pt为插入的位置节点BSTNode* pt = bt;// 通过p的值不断和二叉排序树中的值不断比较找出ptwhile (pt){parent = pt;if (p->data < pt->data) {pt = pt->lchild;}else {pt = pt->rchild;}}// 如果parent为空表示二叉排序树是空树if (parent) {// 比parent小则是左子树if (p->data < parent->data) {parent->lchild = p;}else {// 否则是右子树parent->rchild = p;}}else {bt = p;}// 个数加一count++;}else {// 如果flag不为空说明p值已在二叉排序树中存在 插入失败cout << p->data << "插入失败" << endl;delete p;}}// 创建二叉排序树void CreBst(BSTree& bt) {int value;int count = 0;cout << "请输入整数: ";cin >> value;// 如果value不为0 则插入while (value != 0){// 创建以value为值的节点BSTNode* temp = new BSTNode;temp->data = value;temp->lchild = NULL;temp->rchild = NULL;// 插入Insert(bt, temp, count);// 继续读取valuecin >> value;}cout << "成功插入 " << count << " 个数" << endl;}// 删除二叉排序树中的节点void erase(BSTree& bt, elem key) {// f为p的双亲节点BSTNode* f = NULL;// p为位置节点BSTNode* p = bt;// 通过不断比较查找到pwhile (p && key != p->data){f = p;if (key < p->data) {p = p->lchild;}else {p = p->rchild;}}// 如果p为空 说明不存在key值节点 删除失败if (!p) {cout << "查找失败 删除失败" << endl;return;}// pl为删除节点的左子树BSTNode* pl = p->lchild;// pr为删除节点的右子树BSTNode* pr = p->rchild;BSTNode* ps;// 替代p节点位置的节点BSTNode* s;// 如果左右子树都存在 查找左子树中最大值if (pl && pr) {ps = NULL;s = pl;while (s->rchild){ps = s;s = s->rchild;}if (!ps) {pl = s->lchild;}else {ps->rchild = s->lchild;}s->lchild = pl;s->rchild = pr;}else if (pl) {// 只存在左子树s = pl;}else {// 只存在右子树s = pr;}// 如果f为空 说明删除根节点if (!f) {bt = s;}else if (f->lchild == p) {f->lchild = s;}else {f->rchild = s;}delete p;cout << "删除成功" << endl;}// 中序递归遍历void Inorder(BSTree T) {/*此算法采用递归方式实现中序遍历*/if (T) {Inorder(T->lchild);cout << T->data << " ";Inorder(T->rchild);}}// 先序递归遍历void Preorder(BSTree T) {/*此算法采用递归方式实现先序遍历*/if (T) {cout << T->data << " ";Preorder(T->lchild);Preorder(T->rchild);}}// 删除功能void Delete(BSTree& bt) {int value;cout << "请输入一个整数: ";cin >> value;erase(bt, value);}// 释放二叉排序树空间void clear(BSTree& bt) {if (bt) {clear(bt->lchild);clear(bt->rchild);delete bt;}}int main(void) {// 选项变量int choose;BSTree bt = NULL;// 标志变量 控制循环int flag = 1;while (flag){cout << "------------------------------------------------------" << endl;cout << "-      1.插入元素                                    -" << endl;cout << "-      2.删除元素                                    -" << endl;cout << "-      3.输出                                        -" << endl;cout << "-      4.结束程序                                    -" << endl;cout << "------------------------------------------------------" << endl;cout << "请输入选项: ";cin >> choose;// 防止选项输入导致出错if (cin.fail()) {cin.clear();cin.ignore(10, '\n');}switch (choose){case 1:CreBst(bt);system("pause");system("cls");break;case 2:if (!bt) {cout << "二叉排序树是空树" << endl;}else {Delete(bt);}system("pause");system("cls");break;case 3:cout << "先序顺序: ";Preorder(bt);cout << "\n中序顺序: ";Inorder(bt);cout << endl;system("pause");system("cls");break;case 4:flag = 0;clear(bt);break;default:cout << "请输入有效选项!!!" << endl;system("pause");system("cls");break;}}return 0;}

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

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

相关文章

MySQL笔记-第11章_数据处理之增删改

视频链接&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 文章目录 第11章_数据处理之增删改1. 插入数据1.1 实际问题1.2 方式1&#xff1a;VALUES的方式添加1.3 方式2&#xff1a;将查询结果插入到表中 2. 更…

Latex/Overleafc插入eps格式图片不显示、png转eps等解决问题

最近在搞论文&#xff0c;有些程序生成的图片大部分为png格式&#xff0c;但很多期刊要求eps矢量图格式&#xff0c;特此整理下遇到的各种坑&#xff0c;虽然不算什么技术问题&#xff0c;但是确实也浪费了不少时间。。。 1. png转eps在线神器&#xff1a; 【cloudconvert】 …

Python从入门到精通九:Python异常、模块与包

了解异常 什么是异常 当检测到一个错误时&#xff0c;Python解释器就无法继续执行了&#xff0c;反而出现了一些错误的提示&#xff0c;这就是所谓的“异常”, 也就是我们常说的BUG bug单词的诞生 早期计算机采用大量继电器工作&#xff0c;马克二型计算机就是这样的。 19…

Redis生产实战-热key、大key解决方案、数据库与缓存最终一致性解决方案

生产环境中热 key 处理 热 key 问题就是某一瞬间可能某条内容特别火爆&#xff0c;大量的请求去访问这个数据&#xff0c;那么这样的 key 就是热 key&#xff0c;往往这样的 key 也是存储在了一个 redis 节点中&#xff0c;对该节点压力很大 那么对于热 key 的处理就是通过热…

【JVM从入门到实战】(四)类的生命周期

什么是类的生命周期 类的生命周期描述了一个类加载、连接、初始化、使用、卸载的整个过程 一个类完整的生命周期如下&#xff1a; 加载阶段 加载阶段第一步是类加载器根据类的全限定名通过不同的渠道以二进制流的方式获取字节码信息。 程序员可以使用Java代码拓展的不同的渠道…

CentOS7安装MySQL8.0

一、使用Yum安装 1. 使用wget下载MySQL的rpm包 wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm2. 安装下载好的rpm包 yum localinstall mysql80-community-release-el7-3.noarch.rpm 3. 安装mysql&#xff08;该步可能出现问题&#xff09; yum…

vue项目中 CDN 是vue本身的依赖可以按需加载还是项目中所有的第三方库都可以按需加载?

这是我看到CDN简介时产生的问题 相信很多小伙伴会有 和我一样的疑问 在这里 我也统一回答一下 CDN&#xff08;内容分发网络&#xff09;是一种通过将数据分发到全球各个节点&#xff0c;以提供快速、可靠的内容传输的技术。在Vue项目中&#xff0c;CDN可以用于按需加载Vue本…

GEE:使用网格搜索法(Grid Search)求机器学习的最优参数或者参数组合

作者:CSDN @ _养乐多_ 本文记录了在 Google Earth Engine(GEE)平台中,计算机器学习分类算法最优参数的代码,其中包括单一参数的最优和不同参数组合的最优。使用的最优参数计算方法是网格搜索法(Grid Search),GEE 平台上并没有现成的网格搜索法 API,因此,本文在 GEE …

Android studio 无法查看源码

Android studio 查看源码时提示 Decompiled .class file,bytecode version:52.0(java 8) 1、检查 buildToolsVersion 2、检查相关资源文件

Flink 有状态流式处理

传统批次处理方法 【1】持续收取数据&#xff08;kafka等&#xff09;&#xff0c;以window时间作为划分&#xff0c;划分一个一个的批次档案&#xff08;按照时间或者大小等&#xff09;&#xff1b; 【2】周期性执行批次运算&#xff08;Spark/Stom等&#xff09;&#xff1b…

基于ssm旅游网站的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本旅游网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&#x…

5G下行链路中的MIMO

5G MIMO 影响5G MIMO配置的主要因素是天线的数量和层数UE和gNB有一些预定义的表来定义天线端口和层的数量&#xff0c;选择了特定的表&#xff0c;UE如何确定表中的哪一行用于gNB的每次传输DCI 1-1中该规定了Antenna port 和 层数DMRS 端口数表示正在使用的天线数量&#xff0…