【数据结构5】二叉搜索树(插入、查询、删除)

1 二叉搜索树
1.1 二叉搜索树-插入
1.2 二叉搜索树-查询
1.3 二叉搜索树-删除

1 二叉搜索树

二叉搜索树是一颗二叉树且满足性质:设是二叉树的一个节点。
如果y是x左子树的一个节点,那么y.key< x.key;如果y是x右子树的一个节点,那么y.key > x.key。二叉搜索树的操作:查询、插入、删除

在这里插入图片描述

1.1 二叉搜索树-插入

class BiTreeNode:def __init__(self, data):"""初始化二叉树节点:param data: 节点的值"""self.data = data  # 节点的值self.lchild = None  # 左子节点self.rchild = None  # 右子节点self.parent = None  # 父节点class BST:def __init__(self, li: list):"""初始化二叉搜索树,并插入给定的值:param li: 包含插入值的列表"""self.root = None  # 初始化根节点为空if li:for val in li:self.insert_no_rec(val)  # 使用非递归插入方法将列表中的值插入树中def insert(self, node, val):"""递归插入节点到二叉搜索树中:param node: 当前节点:param val: 要插入的值:return: 插入后的节点"""if not node:# 如果当前节点为空,则创建一个新节点作为叶节点return BiTreeNode(val)elif val < node.data:# 如果要插入的值小于当前节点的值,则递归插入到左子树node.lchild = self.insert(node.lchild, val)node.lchild.parent = node  # 更新左子节点的父节点elif val > node.data:# 如果要插入的值大于当前节点的值,则递归插入到右子树node.rchild = self.insert(node.rchild, val)node.rchild.parent = node  # 更新右子节点的父节点# 如果要插入的值等于当前节点的值,则不做任何操作(BST中不允许重复值)return nodedef insert_no_rec(self, val):"""非递归插入节点到二叉搜索树中:param val: 要插入的值:return: None"""p = self.rootif not p:# 如果树为空,将新节点设置为根节点self.root = BiTreeNode(val)returnwhile True:if val < p.data:# 如果要插入的值小于当前节点的值,则移动到左子树if p.lchild:p = p.lchildelse:# 如果左子树为空,则在此位置插入新节点p.lchild = BiTreeNode(val)p.lchild.parent = p  # 更新新节点的父节点returnelif val > p.data:# 如果要插入的值大于当前节点的值,则移动到右子树if p.rchild:p = p.rchildelse:# 如果右子树为空,则在此位置插入新节点p.rchild = BiTreeNode(val)p.rchild.parent = p  # 更新新节点的父节点returnelse:# 如果要插入的值等于当前节点的值,则不做任何操作(BST中不允许重复值)returndef pre_order(self, root):"""二叉树的前序遍历:param root::return:"""if root:print(root.data, end=',')self.pre_order(root.lchild)self.pre_order(root.rchild)def mid_order(self, root):"""二叉树的中序遍历:param root::return:"""if root:self.mid_order(root.lchild)print(root.data, end=',')self.mid_order(root.rchild)def post_order(self, root):"""二叉树的后序遍历:param root::return:"""if root:self.post_order(root.lchild)self.post_order(root.rchild)print(root.data, end=',')tree = BST([4, 5, 6, 7, 1, 3, 2, 8])
tree.post_order(tree.root)  # 2,3,1,8,7,6,5,4,
print('')
tree.mid_order(tree.root)  # 1,2,3,4,5,6,7,8,
print('')
tree.post_order(tree.root)  # 2,3,1,8,7,6,5,4,

1.2 二叉搜索树-查询

class BST:def query(self, node, val):"""递归查询二叉搜索树中的节点:param node: 当前节点:param val: 要查询的值:return: 节点对象(如果找到)或 None(如果未找到)"""if not node:# 如果当前节点为空,则值未找到,返回 Nonereturn Noneif node.data < val:# 如果当前节点的值小于要查询的值,则递归查询右子树return self.query(node.rchild, val)elif node.data > val:# 如果当前节点的值大于要查询的值,则递归查询左子树return self.query(node.lchild, val)else:# 如果当前节点的值等于要查询的值,返回当前节点return nodedef query_no_rec(self, val):"""非递归查询二叉搜索树中的节点:param val: 要查询的值:return: 节点对象(如果找到)或 None(如果未找到)"""p = self.rootwhile p:if p.data < val:# 如果当前节点的值小于要查询的值,则移动到右子树p = p.rchildelif p.data > val:# 如果当前节点的值大于要查询的值,则移动到左子树p = p.lchildelse:# 如果当前节点的值等于要查询的值,返回当前节点return p# 如果遍历结束仍未找到值,返回 Nonereturn None

1.3 二叉搜索树-删除

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class BST:# 其他方法...def __remove_node_1(self, node):"""情况1:node是叶子节点:param node: 要删除的节点:return: None"""if not node.parent:# 如果节点没有父节点,说明它是根节点,直接将根节点置为 Noneself.root = Noneelif node == node.parent.lchild:# 如果节点是它父节点的左孩子,则将父节点的左孩子指针置为 Nonenode.parent.lchild = Noneelse:# 如果节点是它父节点的右孩子,则将父节点的右孩子指针置为 Nonenode.parent.rchild = Nonenode.parent = None  # 清除删除节点的父节点引用def __remove_node_21(self, node):"""情况2.1:node只有一个左孩子:param node: 要删除的节点:return: None"""if not node.parent:# 如果节点没有父节点,说明它是根节点,将根节点指向它的左孩子self.root = node.lchildnode.lchild.parent = Noneelif node == node.parent.lchild:# 如果节点是它父节点的左孩子,则将父节点的左孩子指向该节点的左孩子node.parent.lchild = node.lchildnode.lchild.parent = node.parentelse:# 如果节点是它父节点的右孩子,则将父节点的右孩子指向该节点的左孩子node.parent.rchild = node.lchildnode.lchild.parent = node.parentdef __remove_node_22(self, node):"""情况2.2:node只有一个右孩子:param node: 要删除的节点:return: None"""if not node.parent:# 如果节点没有父节点,说明它是根节点,将根节点指向它的右孩子self.root = node.rchildelif node == node.parent.lchild:# 如果节点是它父节点的左孩子,则将父节点的左孩子指向该节点的右孩子node.parent.lchild = node.rchildnode.rchild.parent = node.parentelse:# 如果节点是它父节点的右孩子,则将父节点的右孩子指向该节点的右孩子node.parent.rchild = node.rchildnode.rchild.parent = node.parentdef delete(self, val):"""删除二叉搜索树中的节点:param val: 要删除的节点的值:return: 如果删除成功返回 True,否则返回 False"""if self.root:  # 如果树非空node = self.query_no_rec(val)  # 查找要删除的节点if not node:return False  # 如果节点不存在,返回 Falseif not node.lchild and not node.rchild:# 情况1:叶子节点self.__remove_node_1(node)elif not node.rchild:# 情况2.1:只有左孩子self.__remove_node_21(node)elif not node.lchild:# 情况2.2:只有右孩子self.__remove_node_22(node)else:# 情况3:左右孩子都有# 查找右子树中最小的节点min_node = node.rchildwhile min_node.lchild:min_node = min_node.lchildnode.data = min_node.data  # 用最小节点的值替换当前节点的值# 删除最小节点if min_node.rchild:self.__remove_node_22(min_node)else:self.__remove_node_1(min_node)return True  # 删除成功return False  # 树为空,删除失败

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

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

相关文章

绘剪批量软件——绘剪批量软件

批量软件是一种可以批量处理大量数据或操作的软件。它通常通过自动化的方式&#xff0c;快速高效地完成任务&#xff0c;减少人工操作的时间和工作量。批量软件可以用于数据处理、文件转换、批量重命名、批量下载等各种场景。 绘剪批量软件——绘剪TK批量软件 AIWYZ77 批量软…

docker容器数据卷、数据卷基本案例

在docker里面创建也会在主机中生成文件 并且docker停止 时在主机中创建文件仍然可以生成在docker中

机器学习入门指南:如何构建智能预测模型

【机器学习】&#xff1a;入门从零开始的指南 随着人工智能的快速发展&#xff0c;机器学习&#xff08;Machine Learning&#xff09;已经成为技术领域的热点话题。无论是推荐系统、语音识别、自动驾驶汽车&#xff0c;还是自然语言处理&#xff0c;机器学习的应用随处可见。…

动态规划-打家劫舍Ⅱ

该题是打家劫舍Ⅰ的升级版并与其相关&#xff0c;如果对其感兴趣的话可以先看看打家劫舍Ⅰ 题目描述 一个专业的小偷&#xff0c;计划偷窃一个环形街道上沿街的房屋&#xff0c;每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈 &#xff0c;这意味着第一个房屋和最后…

如何在IIS中为typecho博客启用HTTPS访问

在上篇文章中&#xff0c;介绍了如何安装typecho博客系统&#xff0c;默认是没有启用https访问的&#xff0c;这篇文章介绍如何 在IIS中开启 https访问。 开启https访问需要两个步骤&#xff1a; 1、申请 一个ssl证书&#xff0c;我这里以阿里云上面的申请流程为例。其它云服务…

Variomes:支持基因组变异筛选的高召回率搜索引擎

《Bioinformatics》2022 Variomes&#xff1a; https://candy.hesge.ch/Variomes Source code&#xff1a; https://github.com/variomes/sibtm-variomes SynVar&#xff1a; https://goldorak.hesge.ch/synvar 文章摘要&#xff08;Abstract&#xff09; 动机&#xff08;Mot…

前端宝典十:webpack性能优化最佳实践

Webpack 内置了很多功能。 通常你可用如下经验去判断如何配置 Webpack&#xff1a; 想让源文件加入到构建流程中去被 Webpack 控制&#xff0c;配置 entry&#xff1b;想自定义输出文件的位置和名称&#xff0c;配置 output&#xff1b;想自定义寻找依赖模块时的策略&#xff…

C++笔记---内存管理

1. 内存分布 在对操作系统有更加深入的了解之前&#xff0c;在写代码的层面我们需要对下面的几个内存区域有所了解&#xff1a; 1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等&#xff0c;栈是向下增长的。 2. 堆--用于程序运行时动态内存分配&#xff0c;堆是可以上增长…

猫头虎分享:Python库 Httpx 的简介、安装、用法详解入门教程

猫头虎分享&#xff1a;Python库 Httpx 的简介、安装、用法详解入门教程&#x1f405; 大家好&#xff01;今天猫头虎来为大家分享一个在 Python 开发中非常实用的库——Httpx。 最近有很多粉丝问猫哥&#xff0c;Httpx 是什么&#xff1f;如何安装和使用&#xff1f;今天猫头…

深入解析SSRF和Redis未授权访问

深入解析SSRF和Redis未授权访问&#xff1a;漏洞分析与防御 在网络安全领域&#xff0c;服务器端请求伪造&#xff08;SSRF&#xff09; 和 Redis未授权访问 是两类常见且危险的安全漏洞。 1.2 SSRF攻击的利用 1.2.1 测试并确认SSRF漏洞 一个典型的例子是&#xff0c;当应用…

Java入门:06.Java中的方法--进阶04

4方法递归 简而言之就是方法的自身调用。 也可以是方法组自身的调用 递归类似循环&#xff0c;可以实现功能的反复执行。在某些(算法)环境下&#xff0c;比使用循环更轻松。 递归的本质就是方法的不同调用&#xff0c;就会不同的产生栈帧压栈&#xff0c;栈空间有限&#xff…

如何优雅的实现CRUD,包含微信小程序,API,HTML的表单(一)

前言 在开发实际项目中&#xff0c;其实CRUD的代码量并不小&#xff0c;最近要做一个小程序项目&#xff0c;由于涉及表单的东西比较多&#xff0c;就萌生了一个想法&#xff0c;小程序的写法不是和VUE类似&#xff0c;就是数据绑定&#xff0c;模块么&#xff01;那就来一个动…

redis核心数据结构源码分析

dictEntry和redisObject 在 Redis 的实现中&#xff0c;当一个键值对被创建并存储时&#xff0c;键通常是一个字符串&#xff0c;而值则是一个 redisObject。因此&#xff0c;在 dictEntry 结构中&#xff0c;key 成员指向的是一个字符串&#xff0c;而 v.val 成员则指向一个 …

IO进程day01(函数接口fopen、fclose、fgetc、fputc、fgets、fputs)

目录 函数接口 1》打开文件fopen 2》关闭文件fclose 3》文件读写操作 1> 每次读写一个字符&#xff1a;fgetc(),fputc() 针对文件读写 针对终端读写 练习&#xff1a;实现 cat 命令功能 格式&#xff1a;cat 文件名 2> 每次一个字符串的读写 fgets() 和 fputs() …

云原生系列 - Nginx(高级篇)

前言 学习视频&#xff1a;尚硅谷Nginx教程&#xff08;亿级流量nginx架构设计&#xff09;本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删学习文档&#xff1a; 云原生系列 - Nginx(基础篇)云原生系列 - Nginx(高级篇) 一、扩容 通过扩容提升整体吞吐量…

【非常简单】 猿人学web第一届 第12题 入门级js

这一题非常简单&#xff0c;只需要找到数据接口&#xff0c;请求参数 m生成的逻辑即可 查看数据接口 https://match.yuanrenxue.cn/api/match/12 查看请求对应的堆栈中的 requests 栈 list 为对应的请求参数 list 是由 btoa 函数传入 ‘yuanrenxue’ 对应的页码生成的 bto…

PD取电快充协议方案

PD快充协议是通过调整电压和电流来提供不同的充电功率。它采用了一种基于USB-C端口的通信协议&#xff0c;实现了充电器于设备之间的信息交换。在充电过程中设备会向充电器发出请求&#xff0c;要求提供不同的电压和电流&#xff0c;充电器接收到请求后&#xff0c;会根据设备的…

第6章 B+树索引

目录 6.1 没有索引的查找 6.1.1 在一个页中的查找 6.1.2 在很多页中查找 6.2 索引 6.2.1 一个简单的索引方案 6.2.2 InnoDB中的索引方案 6.2.2.1 聚簇索引 6.2.2.2 二级索引 6.2.2.3 联合索引 6.2.3 InnoDB的B树索引的注意事项 6.2.3.1 根页面万年不动窝 6.2.3.2 内节…

【vue】编辑器段落对应材料同步滚动交互

场景需求 编辑器段落对应显示材料编辑器滚动时&#xff0c;材料同步滚动编辑器段落无数据时&#xff0c;材料不显示 实现方法 编辑器与材料组件左右布局获取编辑器高度&#xff0c;材料高度与编辑器高度一致禁用材料组件的滚动事件获取编辑器段落距离顶部的位置&#xff0c;…

【机器学习-监督学习】支持向量机

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;…