二叉搜索树的实现(C++)
前言
二叉搜索树(搜索二叉树,Binary search tree)是一种特殊的二叉树。其规则为:左子树的值一定小于等于根,右子树的值一定大于等于根,并且左右子树也为搜索二叉树。
二叉搜索树的插入
1.若树为空,插入的数据为根节点的数据
2.若树不为空,按照二叉搜索树的性质,判断节点的值与插入值的大小关系。若大于节点的值则往右边走。若小于节点的值则往左边走
二叉搜索树的搜索
1.从根节点开始查找,小于节点值则往左边,大于节点值则往右边。找到就返回
2.若遍历完都没有找到,即返回找不到
二叉搜索树的删除(重点)
1.删除叶子节点(既没有左右孩子),直接删除然后将其父亲节点的指针赋值为nullptr
2.删除只有一个孩子的节点,直接删除然后将孩子连接至父亲节点
3.删除有两个孩子的节点,不能直接删除。从这个节点出发寻找左子树的最大值(既最右节点)或者右子树的最小值(既最左节点)。将找到的值的赋值给要删除的节点,然后删除我们找到的节点,这样就能保证不会破坏二叉搜索树的性质。
补充:若删除根节点的话,要单独处理一下
代码实现
template<class K>
struct BSNode
{K _val;BSNode<K>* _left;BSNode<K>* _right;BSNode(const K& key):_val(key), _left(nullptr), _right(nullptr){ }
};template<class K>
class BSTree
{//typedef BSNode<K> Node;using Node = BSNode<K>;//新的重命名方式
public:void Insert(const K& key)//搜索二叉树的插入(不允许冗余){Node* cur = _root;if (!cur){_root = new Node(key);}else{Node* parent = cur;while (cur){if (cur->_val < key){parent = cur;cur = cur->_right;}else{parent = cur;cur = cur->_left;}}if (parent->_val < key){parent->_right = new Node(key);}else if (parent->_val > key){parent->_left = new Node(key);}elsereturn;}}bool Search(const K& key)//查找{Node* cur = _root;while (cur){if (cur->_val < key){cur = cur->_right;}else if (cur->_val > key){cur = cur->_left;}elsereturn true;}return false;}//搜索二叉树的删除void Erase(const K& key){Node* cur = _root;Node* parent = cur;//先找到相应位置while (cur){if (cur->_val < key){parent = cur;cur = cur->_right;}else if (cur->_val > key){parent = cur;cur = cur->_left;}elsebreak;}if (!cur)return;//进行删除if (!cur->_left && !cur->_right)//没有孩子{if (cur == _root)//若删除根节点{delete _root;_root = nullptr;}else{if (parent->_left == cur)parent->_left = nullptr;elseparent->_right = nullptr;delete cur;cur = nullptr; // 显式置空}}else if (!cur->_left || !cur->_right)//有一个孩子{if (cur == _root)//若删除根节点{if (cur->_left){_root = cur->_left;delete cur;cur = nullptr; // 显式置空}else{_root = cur->_right;delete cur;cur = nullptr; // 显式置空}}else{if (!cur->_left){if (parent->_left == cur){parent->_left = cur->_right;delete cur;cur = nullptr; // 显式置空}else{parent->_right = cur->_right;delete cur;cur = nullptr; // 显式置空}}else{if (parent->_left == cur){parent->_left = cur->_left;delete cur;cur = nullptr; // 显式置空}else{parent->_right = cur->_left;delete cur;cur = nullptr; // 显式置空}}}}else//有两个孩子{//寻找左子树最大值(或右子树最小值)来替换curNode* Replace = cur->_left;Node* Replacep = cur;while (Replace->_right){Replacep = Replace;Replace = Replace->_right;}swap(Replace->_val, cur->_val);if(Replacep->_right == Replace)Replacep->_right = Replace->_left;elseReplacep->_left = Replace->_left;delete Replace;}}void Inorder()//中序遍历{_Inorder(_root);cout << endl;}private:void _Inorder(Node* root)//中序遍历{if (!root)return;_Inorder(root->_left);cout << root->_val<<" ";_Inorder(root->_right);}Node* _root = nullptr;
};
相关文章:
二叉搜索树的实现(C++)
前言 二叉搜索树(搜索二叉树,Binary search tree)是一种特殊的二叉树。其规则为:左子树的值一定小于等于根,右子树的值一定大于等于根,并且左右子树也为搜索二叉树。 二叉搜索树的插入 1.若树为空…...
vue2老版本 npm install 安装失败_安装卡主
vue2老版本 npm install 安装失败_安装卡主 特别说明:vue2老版本安装慢、运行慢,建议升级vue3element plus vite 解决方案1: 第一步、修改npm 镜像为国内镜像 使用淘宝镜像: npm config set registry https://registry.npmmir…...
【MySQL】索引篇
1.什么时候适用索引? 字段有唯一限制,比如商品编码经常用于where查询条件的字段经常用于group by和order by 的字段 2.什么时候不需要创建索引? 字段中存在大量重复经常更新的字段表数据太少的时候 where条件、group by,order by里…...
Arduino 第十六章:pir红外人体传感器练习
Arduino 第十六章:PIR 传感器练习 一、引言 在 Arduino 的众多有趣项目中,传感器的应用是非常重要的一部分。今天我们要学习的主角是 PIR(被动红外)传感器。PIR 传感器能够检测人体发出的红外线,常用于安防系统、自动…...
鸿蒙面试题
1.0penHarmony的系统架构是怎样的? 2.电话服务的框架? 3.OpenHarmony与HarmonyOS有啥区别?...
Rust 语言入门(一):打印与格式化输出
对于初学者来说,掌握 Rust 的基本 I/O 操作是入门的第一步。本篇博客将介绍 Rust 语言的打印机制,包括基本的 print!、println! 宏,格式化输出方式,并探讨其底层原理。 Rust 的基本打印 在 Rust 中,最常见的输出方式…...
vue3.x 的 toRef详细解读
在 Vue 3.x 中,toRef 是一个用于创建响应式引用的工具函数。它可以将一个响应式对象的某个属性转换为一个独立的 ref 对象,同时保持与原始属性的响应式连接。以下是 toRef 的详细解读和示例。 1. toRef 的作用 核心功能 toRef 用于从响应式对象&#x…...
wordpress资讯类网站整站打包
wordpress程序,内置了价值499元的模板.但是有了模板没有全自动采集相信大多数人都搞不懂,目录那么多,全靠原创几乎是不可能的事情,除非你是大公司,每人控制一个板块, 这套源码里面最有价值的应该是这个采集…...
GitHub基本操作及Git简单命令
GitHub简介 GitHub就是一个远程仓库,远程仓库可以理解为就是一个可以保存自己代码的地方,在实际开发当中一个项目往往是有多个人来共同协作开发完成的,那么就需要一个统一代码保存的地方,而GitHub就是起到一个共享和汇总代码的作…...
记一次MySQL故障解决
记一次MySQL故障解决 1 故障现象2 故障排查2.1 查看MySQL服务状态2.2 查看服务日志 3 解决方法3.1 增加 wait_timeout 和 interactive_timeout 参数的值,确保连接不会因超时而被关闭:3.2 检查服务已经恢复正常,不过以上只是临时修改ÿ…...
DeepSeek-R1私有化部署教程 | Linux服务器搭建AI大语言模型
**云服务器用LinuxDockerOllamaOpenWebUI部署DeepSeek-R1大语言模型(LLMs),DeepSeek本地化部署教程(在自己电脑上部署也可以参考此教程)。**超详细教程,手把手。 在当今数字化时代,大型语言模型…...
「软件设计模式」桥接模式(Bridge Pattern)
深入解析桥接模式:解耦抽象与实现的艺术 一、模式思想:正交维度的优雅解耦 桥接模式(Bridge Pattern)通过分离抽象(Abstraction)与实现(Implementation),使二者可以独立…...
【Flink快速入门-5.流处理之多流转换算子】
流处理之多流转换算子 实验介绍 前面实验中介绍的算子已经能够满足我们的大部分开发需求了,但是在实际工作中有时候还会遇到一些业务场景,例如需要摄入多个输入流并将其合并处理,或者需要将一条输入流分割为多条子流,在不同的子…...
react传递函数与回调函数原理
为什么 React 允许直接传递函数? 回调函数核心逻辑 例子:父组件控制 Modal 的显示与隐藏 // 父组件 (ParentComponent.tsx) import React, { useState } from react; import { Modal, Button } from antd; import ModalContent from ./ModalContent;co…...
华为云kubernetes基于keda自动伸缩deployment副本(监听redis队列长度)
1 概述 KEDA(Kubernetes-based Event-Driven Autoscaler,网址是https://keda.sh)是在 Kubernetes 中事件驱动的弹性伸缩器,功能非常强大。不仅支持根据基础的CPU和内存指标进行伸缩,还支持根据各种消息队列中的长度、…...
Spring源码分析のBean扫描流程
文章目录 前言一、scanCandidateComponents1.1 isCandidateComponent1.1.1、排除/包含过滤器1.1.2、条件装配1.1.3、重载一1.1.4、重载二1.1.5、补充:Lookup注解 总结 前言 原生的Spring在构造ApplicationContext时,会调用refresh方法。其中就包含了扫描…...
Ubuntu安装docker:docker-desktop : 依赖: docker-ce-cli 但无法安装它、无法定位软件包 docker-ce-cli
具体错误 sudo apt-get install ./docker-desktop-amd64.deb [sudo] password for weiyu: 正在读取软件包列表... 完成 正在分析软件包的依赖关系树... 完成 正在读取状态信息... 完成 注意,选中 docker-desktop 而非 ./docker-desktop-amd64.de…...
基于大数据的奥运会获奖数据分析系统设计与实现
【大数据】基于大数据的奥运会获奖数据分析系统设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统通过集成先进的数据抓取、处理、存储与可视化技术,为深入理解奥运会…...
数据结构 堆和priority_queue
一、堆的定义 堆(heap),是⼀棵有着特殊性质的完全⼆叉树,可以⽤来实现优先级队列(priorityqueue)。 堆需要满⾜以下性质: 1. 是⼀棵完全⼆叉树; 2. 对于树中每个结点,如…...
Dockerfile 编写推荐
一、导读 本文主要介绍在编写 docker 镜像的时候一些需要注意的事项和推荐的做法。 虽然 Dockerfile 简化了镜像构建的过程,并且把这个过程可以进行版本控制,但是不正当的 Dockerfile 使用也会导致很多问题。 docker 镜像太大。如果你经常使用镜像或者…...
Synopsys AXI VIP 2021.09 保姆级配置避坑指南:从环境搭建到Slave响应序列实战
Synopsys AXI VIP 2021.09 实战配置全解析:从零搭建到Slave响应优化 第一次接触Synopsys AXI VIP时,面对密密麻麻的配置参数和复杂的文档结构,大多数验证工程师都会感到无从下手。作为AMBA总线验证的核心工具,AXI VIP的灵活性和强…...
Supermodel MCP Server:为AI编程助手构建代码知识图谱,实现深度架构感知
1. 项目概述:当AI助手需要“理解”你的代码库 如果你是一名开发者,并且已经开始在日常工作中使用像Claude Code、Cursor这类AI编程助手,你可能会发现一个瓶颈:当你的项目代码量达到几万甚至几十万行时,AI助手对代码的…...
Cursor Rules:为AI编程助手定制团队开发规范,提升代码质量与一致性
1. 项目概述:为AI编程助手打造一套“开发宪法”如果你和我一样,深度使用Cursor IDE进行现代应用开发,尤其是涉及AWS无服务器、Next.js或React Native这类技术栈,那你一定有过这样的体验:每次开启一个新的Chat会话&…...
PotPlayer字幕翻译插件终极指南:免费实现外语视频实时翻译
PotPlayer字幕翻译插件终极指南:免费实现外语视频实时翻译 【免费下载链接】PotPlayer_Subtitle_Translate_Baidu PotPlayer 字幕在线翻译插件 - 百度平台 项目地址: https://gitcode.com/gh_mirrors/po/PotPlayer_Subtitle_Translate_Baidu 还在为看不懂的外…...
云原生应用多集群管理:从设计到实践
云原生应用多集群管理:从设计到实践 一、多集群管理的概念与价值 1.1 多集群管理的定义 多集群管理是指在云原生环境中,对多个 Kubernetes 集群进行统一管理和协调的实践。随着企业规模的扩大和业务需求的增长,单一集群往往难以满足所有需求&…...
数字时代的记忆守护者:重新定义你的聊天数据价值
数字时代的记忆守护者:重新定义你的聊天数据价值 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg …...
基于MCP协议构建安全可控的AI浏览器自动化工具
1. 项目概述:一个让AI安全“上网”的桥梁最近在折腾AI应用开发,特别是想让大语言模型(LLM)能像人一样操作浏览器,去获取实时信息、执行网页任务。这听起来很酷,但实际操作起来,安全性和可控性是…...
如何用 cursor.continue 实现本地海量数据的分页查询加载
cursor.continue()实现分页的核心是游标递进定位而非跳过前N条,通过lastKey参数seek到指定键或更大键的下一条记录,配合索引顺序(如倒序)实现高效“下一页”加载,避免循环调用导致性能问题。用 cursor.continue() 实现…...
2026 代际领先・纯视觉定义室外无感新范式
2026 代际领先・纯视觉定义室外无感新范式镜像视界室外无感定位实时孪生坐标生成技术白皮书一、方案摘要2026空间智能迈入代际变革新阶段,室外场景长期存在GPS信号遮挡、依赖穿戴标签、基站部署成本高昂、跨摄像头轨迹断裂脱节、数字孪生静态滞后、空间无法量化计算…...
泉盛UV-K5/K6对讲机固件终极解析:从开源定制到专业级通信系统
泉盛UV-K5/K6对讲机固件终极解析:从开源定制到专业级通信系统 【免费下载链接】uv-k5-firmware-custom 全功能泉盛UV-K5/K6固件 Quansheng UV-K5/K6 Firmware 项目地址: https://gitcode.com/gh_mirrors/uvk5f/uv-k5-firmware-custom 泉盛UV-K5/K6对讲机固件…...
