数据结构与算法-二叉排序树创建、查找、删除(Swift实现)

C语言实现二叉排序树生成算法 输入:待排序数据序列 功能要求:输出平衡的二叉排序树的形态或输出二叉树的三种遍历序列 立即下载

基本概念

二叉排序树(Binary Sort Tree),又称为二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树。

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树。

二叉排序树查找

  • Swift代码实现

//二叉树结点
class BinaryTreeNode {
    var data: Int                   //结点存储数据
    var leftChild: BinaryTreeNode?  //左孩子指针
    var rightChild: BinaryTreeNode? //右孩子指针
    
    //初始化方法
    init(data: Int) {
        self.data = data
    }
}

//二叉排序树查找结果
class SearchResult {
    //存储查找的结点,如果查找成功就是当前查找成功的结点
    var searchNode: BinaryTreeNode?
    
    //存储当前查找结点的直接父母结点
    var parentNode: BinaryTreeNode?
    
    //查找成功为true,查找失败为false
    var isFound: Bool = false
}

/**
 * 二叉排序树查找
 * @param currentRoot 当前二叉排序树的根结点或子树的根结点
 * @param parentNote  currentRoot的父母结点,如果currentRoot是整个二叉排序树的根结点,则该参数为nil
 * @param key         查找的关键字
 *
 * @return            返回查找的结果对象 
 */
 fileprivate func searchBST(currentRoot: BinaryTreeNode?,
                               parentNode: BinaryTreeNode?,
                               key: Int) -> SearchResult {
        let searchResult = SearchResult()
        
        //查找失败,返回该结点的父母结点(便于插入)
        if currentRoot == nil {
            searchResult.parentNode = parentNode
            searchResult.isFound = false
            return searchResult
        }
        
        //查找成功,返回查找成功的结点,将isFound设置为true
        if key == currentRoot!.data {
            searchResult.searchNode = currentRoot
            searchResult.parentNode = parentNode
            searchResult.isFound = true
            return searchResult
        }
        
        if key < currentRoot!.data { //在左子树继续查找
            return searchBST(currentRoot:currentRoot?.leftChild, parentNode: currentRoot, key: key)
        } else { //在右子树继续查找
            return searchBST(currentRoot:currentRoot?.rightChild, parentNode: currentRoot, key: key)
        }
 }

  • 图示查找过程

二叉排序树插入

  • Swift代码实现

/**
 * 二叉排序树插入
 * @param parentNote 待插入结点的父母结点
 * @param key        待插入的数据
 */
fileprivate func insertBST(parentNode: BinaryTreeNode?, key: Int) {
        //创建结点
        let node = BinaryTreeNode(data: key)
        
        //如果parentNote为nil,说明当前二叉排序树为空树
        guard parentNode != nil else {
            rootNode = node //待插入结点更新为整个二叉排序树的根结点
            return
        }
        
        if key < parentNode!.data { //插入为左孩子
            parentNode?.leftChild = node
        } else { //插入为右孩子
            parentNode?.rightChild = node
        }
}

  • 图示插入过程

二叉排序树创建

  • Swift代码实现
    二叉排序树的创建就是不断查找和插入的过程。

/**
 * 根据提供的集合创建二叉排序树
 */
fileprivate func createBST() {
        for key in items {
            //查找key
            let searchResult = searchBST(currentRoot: rootNode, parentNode: nil, key: key)
            
            //如果查找失败,则插入到二叉排序树上
            if !searchResult.isFound {
                insertBST(parentNode: searchResult.parentNode, key: key)
            }
        }
}

二叉排序树删除

删除叶子结点或仅有左右子树之一的结点
  • Swfit代码实现

/**
 * 待删除的结点是叶子结点或者只有一个孩子
 * @param searchResult 待删除结点搜索结果
 * @param subNote      待删除结点孩子
 */
fileprivate func deleteNodeWithZeroOrOneChild(searchResult: SearchResult, subNode: BinaryTreeNode?) {
        //将待删除结点的左右孩子指针置空
        searchResult.searchNode?.leftChild = nil
        searchResult.searchNode?.rightChild = nil
        
        guard let parentNode = searchResult.parentNode else { //如果待删除结点为整个二叉排序树的根结点
            rootNode = subNode //更新根结点
            return
        }
        
        if searchResult.searchNode!.data < parentNode.data { //待删除结点的孩子成为待删除结点父母结点的左孩子
            parentNode.leftChild = subNode
        } else { //待删除结点的孩子成为待删除结点父母结点的右孩子
            parentNode.rightChild = subNode
        }
}
    
  • 图示删除过程

删除左右子树都有的结点
  • Swift代码实现

/**
 * 待删除的结点有左右子树
 *
 * 这边以待删除结点右子树最左边的结点(最小)覆盖、删除为例。然取左子树最右边的结点亦可!!!
 */
fileprivate func deleteNodeWithTwoChild(searchResult: SearchResult) {
        //初始化游标结果对象,用于存储右子树最小结点(最左边)
        let cursorResult = SearchResult()
        cursorResult.parentNode = searchResult.searchNode
        cursorResult.searchNode = searchResult.searchNode?.rightChild
        cursorResult.isFound = false
        
        //寻找待删除结点右子树最左边的结点
        while cursorResult.searchNode?.leftChild != nil {
            cursorResult.parentNode = cursorResult.searchNode
            cursorResult.searchNode = cursorResult.searchNode?.leftChild
        }
        
        //将右子树最左边的结点赋值给待删除结点
        searchResult.searchNode!.data = cursorResult.searchNode!.data
        
        //删除右子树最左边的结点
        deleteBST(searchResult: cursorResult)
}
    
  • 图示删除过程

总结

  • 二叉排序树是以链接的方式存储,保持了链接存储结构在执行插入或删除操作时不用移动元素的优点,只要找到合适的插入和删除位置后,仅需修改链接指针即可。插入删除的时间性能比较好。
  • 而对于二叉排序树的查找,走的就是从根结点到要查找结点的路径,其比较次数等于给定值的结点在二叉排序树的层数。极端情况,最少为1次,即根结点就是要找的结点,最多也不会超过数的深度。
  • 也就是说,二叉排序树的查找性能取决于二叉排序树的形状。因插入和删除亦依赖于查找,故而,如何构建一棵平衡的二叉排序树(深度与完全二叉树相同,即深度最小)显得尤为重要。
  • 本篇博客只对二叉排序树的核心代码进行了介绍,完整实例请移步github
在 Windows 10 中通过 WSL2 安装 vLLM 部署本地大模型的方法和步骤 通过 WSL2 在 Windows 10 中部署 vLLM 的核心优势是兼顾 Windows 生态与 Linux 环境的 GPU 加速能力,适合需要在 Windows 下开发但依赖 vLLM 高性能推理的场景。相比原生 Windows 部署(Ollama 等工具),该方案性能更优(接近原生 Ubuntu),且支持更大模型和量化优化。若追求极致性能,建议直接使用 Ubuntu 系统;若必须依赖 Windows 工具链,WSL2 + vLLM 是当前最优选择。 阅读详情

相关推荐

手把手教你:在联想/戴尔笔记本上安装华为电脑管家,实现多屏协同(附详细避坑步骤)

本文详细指导如何在联想、戴尔等非华为笔记本上安装华为电脑管家,实现多屏协同功能。从硬件兼容性检查到定制化安装流程,再到功能调优与异常处理,提供了一套完整的解决方案,帮助用户突破品牌限制,享受华为生态的高效办公体验。

weixin_30251829的博客 856

数据结构——二叉排序树的删除操作(非递归)

二叉排序树的删除操作

xinzhi1992的博客 5464

STM32+4G模块+MQTT协议:从零构建稳定可靠的物联网通讯链路

本文详细介绍了如何利用STM32、4G模块和MQTT协议构建稳定可靠的物联网通讯链路。通过硬件选型、AT指令配置和MQTT连接实战,帮助开发者实现低功耗、高可靠性的数据传输,特别适合户外和移动场景应用。

weixin_29191081的博客 334

排序二叉树的删除

排序二叉树的删除

weixin_45761237的博客 2831

科研生产力革命:手把手教你打造基于大模型的Research Agent(文献调研+论文写作+思路激发)

本文介绍了如何利用Research Agent(科研智能体)提升科研效率。Research Agent能自主完成文献检索、信息整合和报告生成全流程,省去50%以上的基础工作时间。文章详细讲解了搭建运行环境的方法,包括工具准备和MetaGPT配置,并提供了两种实战方案:基础版Search-O1和专业版MetaGPT Research Agent。此外,还介绍了如何为垂直领域定制Agent,以及优化检索效果、改善报告逻辑等技巧。最后列举了学术研究、行业分析、内容创作和个人学习四大应用场景,帮助用户将AI从聊天工

LXY_LOVE36的博客 267

挖矿病毒解决实例(隐藏进程,文章较好)(入侵)

CPU起飞了 最近有朋友在群里反馈,自己服务器的CPU一直处于高占用状态,但用top、ps等命令却一直找不到是哪个进程在占用,怀疑中了挖矿病毒,急的团团转。 根据经验,我赶紧让他看一下当前服务器的网络连接,看看有没有可疑连接,果然发现了有点东西: 上Shodan查一下这IP地址: 反向查找,发现有诸多域名曾经解析到这个IP地址: 这是一个位于德国的IP地址,开放了4444,5555,7777等数个特殊的服务端口: 其中这位朋友服务器上发现的连接到的是7777端口,

墨痕诉清风的博客 1万+

二叉排序树的删除

一点睛 二叉排序树的删除情况比较复杂,有下面三种情况需要考虑。 1 删除叶子节点。(比如:2,5,9,12)。 2 删除只有一颗子树的节点。(比如:1)。 3 删除有两颗子树的节点.。(比如:7,3,10 )。 二 思路分析 对删除结点的有三种情况需要分析。 第一种情况:删除叶子节点。(比如:2,5,9,12)。 (1) 需求先去找到要删除的结点 targetNode。 (2) 找到 targetNode 的 父结点 parent。 (3) 确定 targetNode 是 pare.

实践求真知 3951

基于YOLO26深度学习框架的人脸识别门禁系统的算法研究实现方法

本文研究了基于YOLO26深度学习框架的人脸识别门禁系统实现方法。系统采用YOLO26目标检测算法,通过CSPDarknet53主干网络、特征金字塔结构和注意力机制实现高效人脸检测。研究内容包括数据预处理、模型训练优化和身份验证等关键技术,使用迁移学习策略和CIoU损失函数提升检测精度。该系统可应用于智能安防场景,具有实时性强、识别准确的特点,为门禁管理提供了智能化解决方案。

一键难忘的博客 766

二叉排序树的删除操作

二叉排序树的删除操作

IT1995的博客 6617

【异常】Openclaw Gateway进程异常停止问题分析与解决方案

本文分析了Gateway服务异常停止的问题,提出了三种解决方案。核心问题是缺乏进程守护和自动恢复机制,导致服务崩溃后无法自行重启。推荐方案是使用PM2进程管理工具(方案1),提供进程监控、自动重启和开机自启功能。替代方案包括自定义守护脚本(方案2)和supervisord管理(方案3)。这些方案都能有效解决当前服务脆弱性问题,显著提升服务可用性,其中PM2方案成熟度高、配置简单,是首选解决方案。实施后可将服务从人工干预转变为自动恢复,确保业务连续性。

奶爸的编程之路,也就一周冷个三天 458

YOLOv8训练流程-原理解析[目标检测理论篇]

本篇文章主要介绍了YOLOv8训练的流程,主要介绍了Task Aligned Assigner正负样本匹配策略以及YOLOv8的损失计算。

ice 4517

二叉排序树

算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版) 在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找、折半查找、插入查找以及Fibonacci查找。上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就是我们今天要聊的二叉排序树。今天主要聊的是二叉排序树的查找、插入与删除的内容,二叉排序的创建过...

sudo_feng的博客 356

USB 网卡——RNDIS 控制消息流程

在其控制端点上获取控制消息时,设备必须在通信类接口的中断 IN 端点上返回通知,每当设备可以返回控制消息时,主机就会轮询该通知。需要注意的是,如果设备由于某种原因收到GET_ENCAPSULATED_RESPONSE,并且无法使用控制端点上的有效数据做出响应,则应返回设置为 0x00 的单字节数据包,而不是 stall 控制端点。下表中定义了此传输。收到 RESPONSE_AVAILABLE 通知后,主机使用下表中定义的GET_ENCAPSULATED_RESPONSE 传输从控制端点读取控制消息。

tyustli 371

算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版)

在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找、折半查找、插入查找以及Fibonacci查找。上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就是我们今天要聊的二叉排序树。今天主要聊的是二叉排序树的查找、插入与删除的内容,二叉排序的创建过程其实就是不断查找与插入的过程,也就是说当我们在创建二叉排序树时,我们会先搜索该节点在二叉排序树中的位置,...

weixin_34354945的博客 436

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

算法与数据结构(十一) 平衡二叉树(AVL树)(Swift版)

今天的博客是在上一篇博客的基础上进行的延伸。上一篇博客我们主要聊了二叉排序树,详情请戳《二叉排序树的查找、插入与删除》。本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,AVL是发明平衡二叉树的两个科学家的名字的缩写,在此就不做深究了。其实平衡二叉树就是二叉排序树的一种,比二叉排序树多了一个平衡的条件。在一个平衡二叉树中,一个结点的左右子树的深度差不超过1。 本篇博客我们就依照平...

weixin_30455067的博客 103

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

删除二叉搜索树中的某一节点

给定一个二叉搜索树的根节点和要删除的节点的值,使得该节点删除后二叉搜索树性质不变。 struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x):val(x),left(NULL),right(NULL){} }; class Solution { public: v...

weixin_43086349的博客 238

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

二叉树(排序树)的创建、遍历、插入、删除以及查找

二叉树(排序树)的创建、遍历、插入、删除以及查找 原理:二叉树的先序创建(递归)按先序遍历的顺序,依次 输入结点的信息建成立二叉链表的算法。该算法的基本思想是:首先对一般的二叉树添加若干个虚结点,使每一个节点都有左右两个孩子,然后依次输入结点信息。若输入的结不是虚结点,则建立一个新结点;先序创建左子树;先序创建右子树 在这里插入代码片 ...

weixin_43126491的博客 3761

二叉排序树的创建

二叉排序树,又称为二叉查找树。它或者是一棵空树,或者是具有以下性质的二叉树。 1、若它的左子树不为空,则左子树上的所有节点的值均小于他的根的值 2、若他的右子树不为空,则右子树的所有节点的值均大于它的根的值 3、它的左右子树也分别为二叉排序树 二叉树的结构: //二叉树的二叉链表节点结构定义 typedef struct BiTNode { int data; struct BiTN...

qq_43633585的博客 3572

二叉排序树的删除详细解剖

前言 网上的很多博客稂莠不齐,讲的也是参差不齐。我看了百度排名靠前的几篇博客,大概都存在没有把各种情况分析完全的问题,虽然有代码,但还是看的不明不白。 于是我就参考了黑皮书《算法导论(第三版)》做个笔记。同时,对比了与国内教材的不同。 这里只讲二叉排序树的删除。 二叉排序树的删除 二叉排序树,又称为二叉搜索树,设为 T ,删除结点 z 可分为三种大情况: z 为叶子结点,直接删除。类似下图: z 只有左孩子或者右孩子,直接删掉,让其孩子代替。类似下图: z 同时拥有左孩子和右孩子,那么就要找

生命不息,Coding不止 8427

20张图带你彻底搞懂二叉树的删除操作

最近在学习数据结构与算法,记录下二叉树的删除操作是如何实现的,相对于其他的插入,排序等操作。删除操作逻辑上稍微比较复杂,今天通过图形化的方式帮你们彻底搞懂到底是怎么实现删除操作的。话不多说,直接开始。注:本文采用js语言作为演示。

kzj0916的博客 5111

(数据结构)二叉排序树的插入、删除

关于插入不多说,主要讲讲删除操作的第三种情况吧。 前面的两种情况比较简单,包含了只有左或者只有右还有左右都没 有的 第三个情况就比较复杂,左右子树都存在,想删除这个节点(设为P)我们采 用取代的方法,在P的左右子树里面找到 合适的一个节点代替它,根据二叉排序树的特点,可以找P的左子树中最大 的或者右子树中最小的,这里我们讲讲前者。 假设一个二叉排序树如图: 我们要删除节点47,执行玩第50行时P,q,s分别指向47,47,35 跳出while循环时,P不变,s指向37,q一直指向s的父节点,即35,如

qq_51281451的博客 7035

二叉排序树节点删除详解

摘要:本篇笔记作为补充笔记,主要讲解在二叉排序树中的节点删除这一行为的操作

云杉木屋 1万+

二叉树的二叉链表存储结构的建立及操作的实现

要求:利用书本上的二叉树的二叉链表存储结构的定义, typedef struct BiTNode { // 结点结构 TElemType data; struct BiTNode *lchild, *rchild; // 左右孩子指针 } BiTNode, *BiTree; 1)编写完成下列功能的函数:(1)构建二叉树;(2)中序遍历二叉树;(3)求二叉树的深度;(4)求二叉树中叶子结点个数;(5)求二叉树中结点的个数;(6)求二叉树中度为1的结点个数。 2)要求...

m0_56804824的博客 3955
上一篇: Java开发日常-eclipse去掉无用的validation,提升编译速度
下一篇: iOS开发日常-Git版本管理之如何解决fatal: refusing to merge unrelated histories错误
Clumsy-Bird
博客等级 码龄11年 5粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值