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分!!!

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

修改汽车的控制系统实现自动驾驶,基于一个开源的汽车驾驶辅助系统实现全自动驾驶

修改汽车的控制系统实现自动驾驶,基于一个开源的汽车驾驶辅助系统实现全自动驾驶。 自动驾驶汽车依靠人工智能、视觉计算、雷达、监控装置和全球定位系统协同合作,让电脑可以在没有任何人类主动的操作下,自动安全地操作机动车辆。 演示视频: Openpilot :一个开源的汽车驾…

音乐制作工具 Ableton Live 12中文最新 for Mac

Ableton Live 12 Mac具有直观的界面和强大的功能&#xff0c;使得音乐制作变得更加简单和高效。它支持实时录制、编辑和混音&#xff0c;用户可以在创作过程中随时进行修改和调整。此外&#xff0c;该软件还提供了各种音频效果、虚拟乐器和采样器&#xff0c;使用户可以创建出更…

el-table的复选框占满全格

el-table的复选框格子很小每次点击都点不到&#xff0c;又不想设置行点击&#xff0c;因为每次复制内容都会选中&#xff0c;实现效果是点击el-table的复选框单元格就可以选中 <template><div style"width: 60vw; margin: 10px;"><el-table :data&quo…

1 CPU实现的基本框图

汇编语言 && 指令格式 CPU设计的框架&#xff1a;三级流水线 ROM存放指令和数据&#xff0c;大端模式&小端模式&#xff0c;地址对齐 取指 译码&#xff1a; 执行&#xff1a; 汇编语言 & 指令格式 流水线实现工作机制 模块功能划分&接口信号 参考…

新工科:数据科学与大数据技术实验中心解决方案,赋能高校新工科数智人才培养

随着数字经济蓬勃发展&#xff0c;数字化产业和产业数字化成为就业增长新动能。据人瑞人才与德勤调研显示&#xff0c;未来3年&#xff0c;数字产业化企业最需要运营人员和开发人员&#xff08;包括大数据开发工程师、数据建模开发工程师等&#xff09;&#xff0c;其次是数据分…

12 位多通道国产芯片ACM32F403/F433 系列,支持 MPU 存储保护功能,应用于工业控制,智能家居等产品中

ACM32F403/F433 芯片的内核基于 ARMv8-M 架构&#xff0c;支持 Cortex-M33 和 Cortex-M4F 指令集。芯片内核 支持一整套DSP指令用于数字信号处理&#xff0c;支持单精度FPU处理浮点数据&#xff0c;同时还支持Memory Protection Unit &#xff08;MPU&#xff09;用于提升应用的…

lv13 交叉开发环境搭建

1 ubuntu网络环境配置 目的&#xff1a;让Ubuntu可以上外网&#xff0c;让开发板可以与ubuntu互通 2 tftp 服务器环境搭建 tftp&#xff08;Trivial File Transfer Protocol&#xff09;即简单文件传输协议 是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件 传输…

LabVIEW发开发电状态监测系统

LabVIEW发开发电状态监测系统 对发电设备的持续监测对于确保可靠的电力供应至消费者极为重要。它不仅能够及时提醒操作员注意发电设备的潜在损坏&#xff0c;还能减少由于设备故障造成的停机时间。为了达到这一目标&#xff0c;开发了一款基于LabVIEW的软件&#xff0c;专门用…

基于YOLOv8深度学习的血细胞检测与计数系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战、智慧医疗

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

【UE5】监控摄像头效果(下)

目录 效果 步骤 一、多摄像机视角切换 二、摄像头自动旋转巡视 三、摄像头跟踪拍摄 效果 步骤 一、多摄像机视角切换 1. 打开玩家控制器“MyPlayerController”&#xff0c;添加一个变量&#xff0c;命名为“BP_SecurityCameraArray”&#xff0c;类型为“BP_SecurityCa…

Word插件-好用的插件-批量插入图片-大珩助手

现有100张图片&#xff0c;需要批量插入word中&#xff0c;并在word中以每页6张图片的形式呈现&#xff0c;请问怎样做&#xff1f; 使用word大珩助手&#xff0c;多媒体-插入图片&#xff0c;根据图片的长宽&#xff0c;选择连续图片、一行2个图或一行3个图&#xff0c;可一次…

线程互斥与同步

用户级线程 内核的LWP Linux线程 OS概念中经常说的 用户级线程 和 内核级线程 也就是线程实现真的是在OS内部实现&#xff0c;还是应用层或用户层实现 很明显Linux是属于用户级线程 用户级执行流&#xff08;用户级线程&#xff09; &#xff1a;内核lwp 1 : 1 也有1&…

#define宏定义

#define 语法规定 #define定义标识符 语法: #define name stuff #define例子 #include<stdio.h> #define A 100 #define STR "abc" #define FOR for(;;)int main() {printf("%d\n", A);printf("%s\n", STR);FOR;return 0; } 运行结果…

Flutter实现自定义二级列表

在Flutter开发中&#xff0c;其实系统已经给我们提供了一个可靠的二级列表展开的API&#xff08;ExpansionPanelList&#xff09;&#xff0c;我们先看系统的二级列表展开效果&#xff0c;一次只能展开一个&#xff0c;用ExpansionPanelList.radio实现 由此可见&#xff0c;已经…

5V低压步进电机驱动芯片GC6150,应用于摄像机,机器人 医疗器械等产品中。具有低噪声、低振动的特点

GC6150是双通道5V低压步进电机驱动器&#xff0c;具有低噪声、低振动的特点&#xff0c;特别适用于相机变焦对焦系统、万向架、摇头机等精度、低噪声STM控制系统&#xff0c;该芯片为每个通道集成了一个256微步的驱动器。通过SPI & T2C接口&#xff0c;客户可以方使地调整驱…

智慧机房与3D机房动环监控系统的应用

智慧机房是什么&#xff1f; 智慧机房是集采集信息、实时监控、数据分析、统一管理、故障告警等功能于一体的全方位、立体化的智能环境监控系统&#xff0c;构建物联网、大数据和云计算背景下现代企业的“数据心脏”。它能为机房管理者呈现细致入微的关键性数据&#xff0c;优…

20231211解压缩tar.xz压缩包

20231211解压缩tar.xz压缩包 缘起&#xff1a;解压缩友善之臂的NanoPC-T4(RK3399)开发板的Android11的SDK。 rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ cd nanopc-t4/ rootrootrootroot-X99-Turbo:~/nanopc-t4$ ll total…

树根研习社|数据为王,洞察“工业数据采集”背后的价值与实践

一、工业数据采集是什么&#xff1f; 数据采集是将各种信息传感设备通过网络结合起来&#xff0c;实现任何时间、任何地点&#xff0c;人、机、物的互联互通。数据采集的主要的作用是&#xff1a; “翻译官”&#xff1a;不同程序语言的设备数据通过协议解析“翻译”为上层系…

2023年国赛高教杯数学建模A题定日镜场的优化设计解题全过程文档及程序

2023年国赛高教杯数学建模 A题 定日镜场的优化设计 原题再现 构建以新能源为主体的新型电力系统&#xff0c;是我国实现“碳达峰”“碳中和”目标的一项重要措施。塔式太阳能光热发电是一种低碳环保的新型清洁能源技术[1]。   定日镜是塔式太阳能光热发电站&#xff08;以下…

树莓派,opencv,Picamera2利用舵机云台追踪特定颜色对象

一、需要准备的硬件 Raspiberry 4b两个SG90 180度舵机&#xff08;注意舵机的角度&#xff0c;最好是180度且带限位的&#xff0c;切勿选360度舵机&#xff09;二自由度舵机云台&#xff08;如下图&#xff09;Raspiberry CSI 摄像头 组装后的效果&#xff1a; 二、项目目标…