备战蓝桥杯Day26 - 二叉搜索树查询和删除操作

一、查询

递归查询

寻找的值比根节点大,遍历右子树;

寻找的值比根节点小,遍历左子树。

    def qurey(self, node, val):if not node:  # 没有节点,返回空return Noneif node.data < val:return self.qurey(node.rchild, val)elif node.data > val:return self.qurey(node.lchild, val)else:return node

非递归查询 

通过比较,指针不断向下移动,直到找到节点。

 def query_no_rec(self, val):p = self.rootwhile p:if p.data < val:p = p.rchildelif p.data > val:p = p.lchildelse:return preturn None

二、删除 

删除操作思路

删除操作比较难,需要考虑三种情况

1、删除叶子节点:直接删除

2、如果删除的节点只有一个孩子:将此节点的孩子与父亲链接,然后删除此节点。(如果删除的根节点只有一个孩子,删除根节点后,要重新更新一下根节点)

3、如果要删除的节点有两个孩子,将其右子树的最小节点(该节点最多有一个右孩子)替换当前节点,并删除。

详细解释

第一种情况:叶子节点

如果只有一个根节点,那么把根节点置为空就算删除。

如果是叶子节点,将该节点的父节点指向空,即为删除这个节点。ps:需要判断是左孩子还是右孩子

    def __remove_node_1(self, node):# 情况1:node是叶子节点if not node.parent:self.root = Noneif node == node.parent.lchild:node.parent.lchild = Noneelse:node.parent.rchild = None

第二种情况:2.1 只有一个左孩子

2.1.1

如果是删除根节点,那么将根节点直接指向左孩子即可。

2.1.2

如果是树中的某一个左孩子,且只有一个左孩子,那么将该节点的父节点指向该节点的左孩子,并将指向该节点左孩子的指针指向该节点的父节点。

这个过程有点绕,多理解理解就好了,下面配图帮助理解。图中蓝线是指针变化后应该指向的位置。

2.1.3

如果是树中的某一个右孩子,且只有一个左孩子,那么将该节点的父节点指向该节点的左孩子,并将指向该节点左孩子的指针指向该节点的父节点。

实现代码

    def __remove_node_21(self, node):# 情况2.1:node只有一个左孩子if not node.parent:self.root = node.lchildnode.parent.lchild = Noneelif node == node.parent.lchild:node.parent.lchild = node.lchildnode.lchild.parent = node.parentelse:node.parent.rchild = node.lchildnode.lchild.parent = node.parent

第二种情况:2.2 只有一个右孩子 

2.2.1

如果是删除根节点,那么将根节点直接指向右孩子即可。

2.2.2

如果是树中的某一个左孩子,且只有一个右孩子,那么将该节点的父节点指向该节点的右孩子,并将指向该节点右孩子的指针指向该节点的父节点。

2.2.3

如果是树中的某一个右孩子,且只有一个右孩子,那么将该节点的父节点指向该节点的右孩子,并将指向该节点右孩子的指针指向该节点的父节点。

实现代码

    def __remove_node_22(self, node):# 情况2.2:node只有一个右孩子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.parent

 第三种情况:左右两个孩子都有

3.1 在右子树中寻找最小的数。因为你删除的那个节点需要有数字替代,那么就是右子树中最小的那个数。

3.2 for循环遍历右子树的左孩子,找到最小的值。

3.3 把找到的最小的数替换到要删除的节点位置。

3.4 判断我们找到的最小数是只有右孩子的情况还是叶子节点的情况。这个节点不可能会有左孩子的情况,因为我们寻找最小数的已经找到最后一个左孩子了。

实现代码

                min_node = node.rchildwhile min_node.lchild:min_node = min_node.lchildnode.data = min_node.data# 删除min_node节点if min_node.rchild:self.__remove_node_22(node)else:self.__remove_node_1(node)

删除操作整个实现

没有右孩子就是只有一个左孩子

没有左孩子就是只有一个右孩子

    def delete(self, val):if self.root:   # 不是空树查询节点node = self.query_no_rec(val)if not node:return 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.3 只有一个右孩子self.__remove_node_22(node)else:  # 3.两个孩子都有min_node = node.rchildwhile min_node.lchild:min_node = min_node.lchildnode.data = min_node.data# 删除min_node节点if min_node.rchild:self.__remove_node_22(node)else:self.__remove_node_1(node)

ok这就是查询和删除操作!代码一定要自己手敲!多动手!勤思考!一定会有进步的! 

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

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

相关文章

24计算机考研调剂 | 【官方】山东师范大学(22自命题)

山东师范大学2024年拟接收调剂 考研调剂信息 调剂专业目录如下&#xff1a; 计算机技术&#xff08;085404&#xff09;、软件工程&#xff08;085405&#xff09; 补充内容 我校2024年硕士研究生调剂工作将于4月8日教育部“中国研究生招生信息网”&#xff08;https://yz.ch…

Servlet两种配置

通过xml配置 <servlet><servlet-name>MyServlet</servlet-name><servlet-class>MyServlet</servlet-class> </servlet> <servlet-mapping><servlet-name>MyServlet</servlet-name><url-pattern>/MyServlet</ur…

力扣17. 电话号码的字母组合

Problem: 17. 电话号码的字母组合 文章目录 思路及解法复杂度Code 题目描述 思路及解法 1.将电话号码和对应的数组存入数组中创建映射关系&#xff1b; 2.编写&#xff0c;并调用回溯函数&#xff0c;当决策阶段等于digits的长度时&#xff0c;将当前的决策路径添加到结果集合中…

技术桃花源

&#xff08;1&#xff09; 京东在1998年时是一家中关村普通的小铺面&#xff0c;老板是刚刚从人民大学社会学系毕业的高材生刘强东。但是这样的铺面在中关村有2万多家。十年后&#xff0c;京东已经拥有11家铺面&#xff0c;年营收已经达到5000多万。 2007年&#xff0c;老刘跑…

[python3] 设置多进程名称并且在ps命令中可见

Centos7 系统 setproctitle 是一个 Python 模块&#xff0c;用于设置进程标题&#xff08;process title&#xff09;。进程标题是在系统中用来标识进程的名字&#xff0c;通常会显示在系统级的进程管理工具&#xff08;如 ps 命令&#xff09;中。通过设置进程标题&#xff0c…

ChatGPT登陆提示:“Please unblock challenges.cloudflare.com to proceed…”

ChatGPT登陆时提示&#xff1a;“Please unblock challenges.cloudflare.com to proceed”&#xff0c; 说明&#xff1a;请解除对challenges.cloudflare.com的屏蔽以继续 原因及解决方法&#xff1a; 1、出现这个问题&#xff0c;一般都是网络和本地环境问题&#xff0c;可以…

Linux权限维持后门及应急响应

本次应急响应实验用kali和centos7来充当攻击机和靶机 kali&#xff1a;192.168.10.130 centos7&#xff1a;192.168.10.155 前提&#xff1a; 用kali连接到centos7上面ssh root192.168.10.155 一、SSH软链接 任意密码登录即可发现程度&#xff1a;|||||| ln -sf /usr/sbi…

超实用!免费软件站大盘点,总有一款适合你

相信用Mac电脑的同学都知道一个网站MacWK&#xff0c;可以白嫖几乎所有常用软件&#xff0c;不用付费&#xff0c;但不好的消息是在2022年10月宣布关站&#xff0c;小编从此走上了开源免费的道路&#xff0c;尽管不太好用&#xff0c;奈何口袋木有钱&#xff0c;经过小编的不断…

C#开发中方法使用的问题注意

C#开发中&#xff0c;我们在进行方法内嵌时&#xff0c;需要注意方法回传带值时&#xff0c;我们需要对方法回传的值进行一个赋值传递 如下所示 console.WriteLine("请输入你的爱好&#xff1a;"); string aihao Console.ReadLine(); name ChangeData(name);同时在…

KT6368A蓝牙主从一体芯片_功能简要说明

一、功能简介 新增KT1328A芯片方案的蓝牙主从一体版本&#xff0c;实现的是主从一体相互切换&#xff0c;也就是说可以设置为主机【类似于手机的角色】&#xff0c;也可以设置为从机角色&#xff0c;通过AT指令 此版本的型号命名为&#xff1a;KT1328A-SOP8 。后续需要下单…

2024-Spring IOC 和 AOP源码分析(上篇)

**前言&#xff1a;**笔者最近面了几次大厂。。。开局Spring源码暴击 之前看过忘了写篇总结。。。 1、介绍一下Spring 核心组件&#xff1a; 常用模块&#xff1a; 常用注解&#xff1a; 2、说一下SpringIOC原理 概念&#xff1a;Spring 通过一个配置文件描述 Bean 及 B…

Linux系统中安装Docker

用Linux既可以用虚拟机操作&#xff0c;也可以自己弄一个云服务器进行操作&#xff0c;两者没啥区别。 操作之前需要将用户等级升级到root级别&#xff0c;防止有些操作因为权限限制而不能操作。 安装docker非常简单&#xff0c;只需要一直按照下列命令顺序进行操作即可。 安装…