DS二叉排序树之删除

38a165c5d38e4b338a02a97eda970bb7.png

Description

给出一个数据序列,建立二叉排序树,并实现删除功能

对二叉排序树进行中序遍历,可以得到有序的数据序列

Input

第一行输入t,表示有t个数据序列

第二行输入n,表示首个序列包含n个数据

第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开

第四行输入m,表示要删除m个数据

从第五行起,输入m行,每行一个要删除的数据,都是自然数

以此类推输入下一个示例

Output

第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到

从第二行起,输出删除第m个数据后的有序序列,输出m行

以此类推输出下一个示例的结果

Sample

#0

Input

Copy

1
6
22 33 55 66 11 44
3
66
22
77

Output

Copy

11 22 33 44 55 66 
11 22 33 44 55 
11 33 44 55 
11 33 44 55 

 

难点:

 

 1.普通的删除:删除的是叶子

2df5167fe25446de92aab0bf408d2f74.png

2.删除的是中间的节点但是只有左右子树其中一个

467ecde2b99a46b48d2d1802043a0a5f.png

3.删除的节点是中间的节点且左右子树都有值

481729665f2242f4a9a15a4221397599.png

 

思路:

 

 1.删除的是叶子

18c640415c8f47738c35dd4f9035a37f.png
直接把那个叶子删了,不要了,就是这么大气!!!

 

2.删除的是中间的节点,但是只有左右子树其中一个

f2b02f271721473c8d9cf53b2c93af49.png

直接将要删掉的他的子树接上去就好了

3.要删的节点左右子树都有值

  我给此时的树再加一点,有点突然,别介意
  分为两种情况

 1.这个要删的节点22的左子树11只有左子树15没有右子树,

02d81826207d41879bcf5281f36e6fa8.jpeg

2.要删的节点22的左子树11不只有一个左子树还有右子树
abb076dda27848d0b171f792a00695e6.png

tips:
1.为什么要找左子树最大值?
    因为二叉排序树左子树小于根,根小于右子树,所以找左子树最大一直向右找就行了
2.为什么20的左子树是不是null没有关系?
    因为我们只需要拿20替换22的位置,花圈部分再比20小,也是11的右子树的位置里,肯定比11大,所以11的右子树直接指向花圈部分没有问题

 

删除节点的的部分:

         分为三个部分

1.删除的节点左子树为空,那就直接把这个节点的右子树接上去
2.删除的节点右子树为空,那就直接把这个节点的左子树接上去
3.删除的节点左右子树不为空:
    root为要被删除的节点
    一:root的左子树只有一个左子树,那就把这个节点替换要删的节点的值,然后root的左指针指向被替换节点的左子树,对应这张图

    二:左子树不只有一个节点,那就找这个子树的最大值,跟要删的节点替换,且这个节点的父节点的右指针指向最大值的左子树,对应这张图

 

代码部分:

 

1.构建二叉排序树,可以参考我另一篇文章DS二叉排序树之查找

     结构体:
72379d02c380400abf411003fdba332d.png

   建立根:

7b73c436a92f46d7bd916815cd78c52b.png

  剩下的元素逐个插入:

1301e5c01a1b4e9eba6a1a07ed4cb04e.png

 

2.删除元素的函数

    找到要删除的元素的节点的位置

6a677f7103c843e9af6ee080ab98c0c2.png

     删除函数remove

d7f93974415443108b54cc0a04eaf4a9.png

 

完整代码:

#include <iostream>
#include <queue>
using namespace std;
struct treenod
{int val;treenod* left, * right;//左右子树指针treenod(){left = NULL;right = NULL;}treenod(int x){val = x;left = NULL;right = NULL;}
};
queue<int>ss;//队列用来存要建树的值
void insert(treenod*& root, int num)///元素逐个插入
{if (root == NULL)//遇到空就插入{root = new treenod(num);}if (num < root->val)//插入的值比这个节点小就往左子树继续走{insert(root->left, num);}if (num > root->val)//插入的值比这个节点小就往右子树继续走{insert(root->right, num);}
}
treenod* buildtree()//建树
{if (ss.empty())return NULL;treenod* root;root = new treenod(ss.front());//先建立根ss.pop();while (!ss.empty()){insert(root, ss.front());//剩下的元素都一个一个插入ss.pop();}return root;
}
void zhonxu(treenod* root)
{if (root == NULL)return;zhonxu(root->left);cout << root->val << " ";zhonxu(root->right);
}
void remove(treenod*& root)//root是要删除的节点
{if (root->right == NULL)//要删的节点只有一个左子树{root = root->left;return;}if (root->left == NULL)//要删的节点只有一个右子树{root = root->right;return;}//要删的节点存在左右子树treenod* p = root->left;treenod* pre = root;//可以记为要删除的节点的父节点while (p->right != NULL){pre = p;            //pre可以理解为最大值的父节点p = p->right;       //向右子树走找最大值}if (pre == root)//说明要删的节点左子树只有一个左分支,没有右分支{root->val = p->val;//要删除的节点的值=p的值root->left = p->left;//且这个被删节点的左子树要指向,p的左子树delete p;return;}root->val = p->val;//说明要删的节点的左子树有右子树,有右分支,root=root的左子树里的最大值pre->right = p->left;//最大值的父节点的右子树指向最大值的左子树delete p;return;
}
void removeItem(treenod*& root, int num)//根节点和要删除的值
{if (root == NULL)//如果遇到空节点说明不存在这个值的节点,不用删除return;if (root->val == num)//说明存在这个值的节点,删除{remove(root);//调用删除函数return;}if (root->val > num)//如果要删除的值小于这个节点的值,向左子树走{removeItem(root->left, num);}if (root->val < num)//如果要删除的值大于这个节点的值,向右子树走{removeItem(root->right, num);}
}int main()
{int t;cin >> t;while (t--){int n;cin >> n;for (int i = 1; i <= n; i++){int num;cin >> num;ss.push(num);}treenod* root;root = buildtree();zhonxu(root);cout << endl;int m;cin >> m;for (int i = 1; i <= m; i++){int num;cin >> num;removeItem(root, num);zhonxu(root);cout << endl;}}return 0;
}

偷懒下,主函数不想打注释了,也不长,有读题的都知道在干嘛


这周估计就更这个吧,因为要备考四级了,而且我也不是大佬,后面的题还不太会,等我慢慢学吧!!!
不要催更,不要催更,不要催更!!!
祝我四级不要再421分好吧有缘人。

我祝你六级轻松拿下600分!!!

 

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

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

相关文章

蓝桥杯周赛 第 1 场 强者挑战赛 6. 小球碰撞【算法赛】(思维题/最长上升子序列LIS)

题目 https://www.lanqiao.cn/problems/9494/learning/?contest_id153 思路来源 Aging代码 题解 二分时间t&#xff0c;第i个小球对应一个起点pi、终点pit*vi的区间&#xff0c;问题转化为&#xff0c; 选最多的区间&#xff0c;使得不存在区间包含&#xff08;即li<l…

微信小程序过滤器之计算当前时间差

微信小程序过滤器之计算当前时间差 前言一、wxs简介二、使用步骤1.定义2.使用 前言 最近遇到了一个需求&#xff0c;将小程序里面的具体时间2023-12-11 09:41:06转为当前时间差10小时前&#xff0c;这块可以使用js逻辑函数对数据进行处理&#xff0c;但这里我们采用微信小程序…

Error: Failed to resolve vue/compiler-sfc——vite项目启动报错——npm run serve

运行项目时&#xff0c;报错如下&#xff1a; Error: Failed to resolve vue/compiler-sfc 根据报错信息的提示&#xff1a;vue的版本必须大于3.2.25&#xff0c;经过查看package.json文件&#xff0c;可以看到vue的版本为3.2.36&#xff0c;是满足条件的。 因此考虑缓存问题&…

【OPNEGIS】Geoserver原地升级jetty,解决Apache HTTP/2拒绝服务漏洞 (CVE-2023-44487)

Geoserver是我们常用的地图服务器&#xff0c;在开源系统中的应用比较广泛。在实际环境中&#xff0c;我们可能会选用官方的二进制安装包进行部署&#xff0c;这样只要服务器上有java环境就可以运行&#xff0c;方便在现场进行部署。 1.问题来源 这次由于甲方一月一次的漏洞扫…

智能优化算法应用:基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.阴阳对算法4.实验参数设定5.算法结果6.参考文…

Java - Mybatis的缓存机制、集成SpringBoot后缓存相关问题

mybaits提供一级缓存&#xff0c;和二级缓存 一级缓存&#xff08;默认开启&#xff09; 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象&#xff0c;在对象中有一个(内存区域)数据结构&#xff08;HashMap&#xff09;用于存储缓存数据。不同的sqlSe…

STM32F407-14.3.1-01 时基单元

时基单元 可编程高级控制定时器的主要模块是一个 16 位计数器及其相关的自动重载寄存器。计数器可递增计数、递减计数或交替进行递增和递减计数。计数器的时钟可通过预分频器进行分频。 计数器、自动重载寄存器和预分频器寄存器可通过软件进行读写。即使在计数器运行时也可执行…

Python:核心知识点整理大全14-笔记

目录 ​编辑 7.2.2 让用户选择何时退出 parrot.py 7.2.3 使用标志 7.2.4 使用 break 退出循环 cities.py 7.2.5 在循环中使用 continue counting.py 7.2.6 避免无限循环 counting.py 7.3 使用 while 循环来处理列表和字典 7.3.1 在列表之间移动元素 confirmed_user…

数字图像处理(实践篇)二十二 使用opencv进行人脸、眼睛、嘴的检测

目录 1 xml文件 2 涉及的函数 3 实践 使用opencv进行人脸、眼睛、嘴的检测。 1 xml文件 方法① 下载 地址&#xff1a;https://github.com/opencv/opencv/tree/master/data/haarcascades 点击haarcascade_frontalface_default.xml文件 对着Raw右键&#xff0c;选择“链接…

【JVM从入门到实战】(二)字节码文件的组成

一、Java虚拟机的组成 二、字节码文件的组成 字节码文件的组成 – 应用场景 字节码文件的组成部分-Magic魔数 什么是魔数&#xff1f; Java字节码文件中的魔数 文件是无法通过文件扩展名来确定文件类型的&#xff0c;文件扩展名可以随意修改&#xff0c;不影响文件的内容。…

UE引擎 LandscapeGrass 实现机制分析(UE5.2)

前言 随着电脑和手机硬件性能越来越高&#xff0c;游戏越来越追求大世界&#xff0c;而大世界非常核心的一环是植被&#xff0c;目前UE5引擎提供给植被生成的主流两种方式为 手刷植被和LandscapeGrass(WeightMap程序化植被)。当然UE5.3推出新一代PCGFramework 节点程序化生成框…

MyBatis:缓存

MyBatis 缓存一级缓存二级缓存注 缓存 缓存&#xff0c;是数据交换的缓冲区&#xff08;临时保存数据的地方&#xff09;。即将数据&#xff08;数据一般为频繁查询且不易改变&#xff09;保存在计算机内存中&#xff0c;下次读取数据时直接从内存中获取&#xff0c;以避免频繁…

OpenAI接口调用示例

最近为公司做了一个ChatGPT工具&#xff0c;这里展示一下OpenAI接口的调用 前提条件 访问OpenAI官网&#xff08;国内需要翻墙&#xff09;的账号&#xff0c;需要sk 地址&#xff1a;https://platform.openai.com 依赖 使用开源工具调用OpenAI接口&#xff0c;依赖如下&am…

Vue3封装一个轮播图组件

先看效果 编写组件代码 CarouselChart.vue <template><div classimg-box><el-button clickpreviousImages v-ifprops.showBtn>←</el-button><div classimg><div styledisplay: flex;gap: 20px idmove><imgclassimg-item v-for(item…

centos7部署docker

文章目录 &#xff08;1&#xff09;安装前准备&#xff08;2&#xff09;卸载旧版Docker&#xff08;3&#xff09;安装docker&#xff08;4&#xff09;配置镜像加速 &#xff08;1&#xff09;安装前准备 在开始安装之前&#xff0c;首先需要检查内核版本。使用 uname -r 命…

nodejs微信小程序+python+PHP个性化服装搭配系统APP-计算机毕业设计推荐 android

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

redis(设置密码)配置文件详细

1.设置账号密码端口 config set requirepass 123456 设置密码为123456 config get requirepass 查看账号密码 auth 123456 登入的时候输入这个确定账号密码 1. 首先连接到Redis服务器: redis-cli 2. 然后使用CONFIG SET命令设置requirepass参数并指定密码: CONFIG SET requi…

【PyTorch】现代卷积神经网络

文章目录 1. 理论介绍1.1. 深度卷积神经网络&#xff08;AlexNet&#xff09;1.1.1. 概述1.1.2. 模型设计 1.2. 使用块的网络&#xff08;VGG&#xff09;1.3. 网络中的网络&#xff08;NiN&#xff09;1.4. 含并行连结的网络&#xff08;GoogLeNet&#xff09; 2. 实例解析2.1…

家具制造ERP软件包含哪些功能?家具制造业ERP系统哪个好

不同的家具有不同的用料、品质、制造工时、营销渠道等&#xff0c;而有些家具制造企业采用传统的管理方式在处理物料BOM、生产实际成本核算、库存盘点、供应商选择、班组计件核对、生产领用以及物料追溯等方面存在不少提升空间。 与此同时也有很多的皮具制造企业借助ERP软件优…

Linux16 ftp文件服务区、vsftpd文件系统服务安装、lftp客户端安装、NFS远程共享存储

目录 一、FTP基础ftp主动模式ftp被动模式 二、vsftpd配置共享目录编辑配置文件使用windows 访问 三、客户端安装 &#xff08;lftp&#xff09;匿名用户的一些操作&#xff08;lftp {ip}&#xff09;ftp配置本地用户登录配置本地用户ftp配置文件 lftp操作 NFS远程共享存储安装n…