C++二叉搜树的实现(递归和非递归)

目录

1.什么是二叉搜索树

2.二叉搜索树的查找

3.二叉搜索树插入

4.二叉搜索树的删除

1.删除的节点只有左子树或者右子树

2.删除节点左右子树都有的情况

5.代码


1.什么是二叉搜索树

左节点的值小于根节点

右节点大于根节点

左右子树也满足上面两个条件

例:arr[] = {5,2,1,3,4,7,6,8} 转化为二叉搜索树

2.二叉搜索树的查找

思路:寻找44比5小去左子树寻找-> 4比2大去右子树寻找->4比3大去右子树寻找->找到4。

3.二叉搜索树插入

思路:查找插入元素可以存储的位置 ,插入。

例:插入9, 9比5大去右子树寻找->9比7大去右子树寻找->9比8大去右子树寻找->找到9可以插入的位置->将9插入8的右子树。

4.二叉搜索树的删除

二叉搜索树删除的情况可以分成两种

1.删除的节点只有左子树或者右子树

 如果删除节点是删除节点父亲节点的左子树,那就把删除节点的左子树或者右子树,托付给父亲节点的左子树。

 如果删除节点是删除节点父亲节点的右子树,那就把删除节点的左子树或者右子树,托付给父亲节点的右子树。

例:删除3就把4托付给2的右子树

       删除4就把空节点托付给3的右子树

2.删除节点左右子树都有的情况

左子树的最右节点或者右子树的最左节点替换删除节点,再将左子树最右节点或者右子树最左节点删除,因为最右节点一定没有右子树,最左节点一定没有左子树就把问题转化为情况1了

例:删除2

用右子树的最左节点:3为右子树最左节点,把3赋值给2,去右子树把3删除,把4托付给3的右子树 。

用左子树的最右节点:1为左子树最右节点,把1赋值给2,去左子树把1删除,把空节点托付给1的左子树。

5.代码

#pragma oncenamespace V
{template<class K>struct BinarySearchTreeNode//节点{typedef struct BinarySearchTreeNode<K> Node;BinarySearchTreeNode():_val(){}BinarySearchTreeNode(const K& val):_val(val){}Node* _left = nullptr;Node* _right = nullptr;K _val;};template <class K>class BST//二叉搜索树{typedef struct BinarySearchTreeNode<K> Node;public:BST()//构造函数:_root(nullptr){}BST(const BST<K> &t){_root = Copy(t._root);}Node* Copy(Node* root){if (nullptr == root){return nullptr;}Node* newNode = new Node(root->_val);newNode->_left = Copy(root->_left);newNode->_right = Copy(root->_right);return newNode;}BST<K>& operator=(BST<K> t){std::swap(_root,t._root);return *this;}bool Insert(const K& key){if (nullptr == _root){_root = new Node(key);return true;}Node* cur = _root;Node* parent = nullptr;while (nullptr != cur){if (key > cur->_val){parent = cur;cur = cur->_right;}else if (key < cur->_val){parent = cur;cur = cur->_left;}else { return  false; }}Node* newNode = new Node(key);if (parent->_val > newNode->_val){parent->_left = newNode;return true;}else{parent->_right = newNode;return true;}}Node* Find(const K& key){Node* cur = _root;while (nullptr != cur){if (cur->_val > key){cur = cur->_left;}else if (cur->_val < key){cur = cur->_right;}else if (cur->_val == key){return cur;}}return nullptr;}bool Erase(const K& key){Node* cur = _root;Node* parent = _root;while (nullptr != cur){if (cur->_val > key){parent = cur;cur = cur->_left;}else if (cur->_val < key){parent = cur;cur = cur->_right;}else if (cur->_val == key)//找到key{if (nullptr == cur->_left)//当key左子树为空{if (_root == cur){_root = cur->_right;}else if (cur == parent->_left)//当cur是父亲的左子树{parent->_left = cur->_right;}else if(cur == parent->_right)//cur是父亲的右子树{parent->_right = cur->_right;}delete cur;cur = nullptr;return true;}else if (nullptr == cur->_right)//key的右子树为空{if(cur == _root){ _root = cur->_left;}else if (cur == parent->_left){parent->_left = cur->_left;}else{parent->_right = cur->_left;}delete cur;cur = nullptr;return true;}else //左右子树都不为空 {Node* LNode = cur->_left;Node* LParent = cur;while (LNode->_right)//找左子树的最右节点 替换cur {LParent = LNode;LNode = LNode->_right;}cur->_val = LNode->_val;//修改值//最右节点没有右子树if (LNode == LParent->_left){LParent->_left = LNode->_left;}else{LParent->_right = LNode->_left;}delete LNode;LNode = nullptr;return true;}}}return false;}void InOrder(){return _InOrder(_root);}void Destory(){_Destory(_root);}~BST(){Destory();}///递归实现bool FindR(const K &val){return _FindR(_root,val);}bool InsertR(const K& val){return _InsertR(_root,val);}bool EraseR(const K& val){return _EraseR(_root, val);}private:Node* _root;void _InOrder(Node* root){if (nullptr == root){return;}std::cout << root->_val << " ";_InOrder(root->_left);_InOrder(root->_right);}void _Destory(Node * root){if (nullptr == root){return;}_Destory(root->_left);_Destory(root->_right);delete root;}bool _InsertR(Node * &root, const K &val){if (nullptr == root){root = new Node(val);return true;}if (root->_val > val)_InsertR(root->_left, val);else if (root->_val < val)_InsertR(root->_right, val);return false;}bool _FindR(Node * root,const K&val){if (nullptr == root)return false;if (root->_val > val)_FindR(root->_left, val);else if (root->_val < val)_FindR(root->_right, val);else return true;}bool _EraseR(Node * &root,const K&val){if (root == nullptr){return false;}if(root->_val > val){_EraseR(root->_left,val);}else if (root->_val < val){_EraseR(root->_right, val);}else{Node* del = root;//当左孩子为空,if (nullptr == root->_left){root = root->_right;}else if (nullptr == root->_right){root = root->_left;}else {Node* leftmax = root->_left;while (leftmax->_right)//左子树的最右节点{leftmax = leftmax->_right;}swap(leftmax->_val, root->_val);return _EraseR(root->_left,val);}delete del;return true;}}};}

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

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

相关文章

平台工程与安全

平台工程不是为了取代DevOps&#xff0c;而是DevOps的进一步演进和发展。本文介绍了DevOps和平台工程&#xff0c;以及对于安全的意义。原文: Platform Engineering and Security: A Very Short Introduction 中国云南大理的日落 我是一名 DevOps 工程师&#xff0c;个人还是希…

c# 调用存储过程

1.调用返回OUT的存储过程 a.调用OUT字符串的存储过程&#xff1b; #region 连接数据库/// <summary>/// 连接数据库/// </summary>/// <param name"connStatus"></param>/// <param name"dbNode"></param>/// <ret…

Android WebView访问网页+自动播放视频+自动全屏+切换横屏

一、引言 近期&#xff0c;我发现电视家、火星直播等在线看电视直播的软件都已倒闭&#xff0c;而我奶奶也再无法通过这些平台看电视了。她已六十多岁&#xff0c;快七十岁啦。这些平台的倒下对我来说其实没有多大的影响&#xff0c;但是对于文化不多的她而言&#xff0c;生活中…

Linux下的时间同步,以及ntp时间服务器配置流程

Linux下的时间同步&#xff0c;以及ntp时间服务器配置流程 概论常见时间操作命令Linux下的系统时间配置Linux硬件的时间的设置系统时间和硬件时间的同步NTP服务器时间的同步NTP服务的安装NTP的时间同步定时任务里的时间同步配置文件同步时间 概论 但在Linux下&#xff0c;系统…

SpringBoot中间件简介

Spring Boot是一个Java框架&#xff0c;它提供了一系列中间件来简化应用程序的开发和集成。以下是一些常见的Spring Boot中间件&#xff1a; Web中间件&#xff1a; Servlet容器&#xff08;内嵌Tomcat、Jetty或Undertow&#xff09; Spring MVC&#xff08;用于构建Web应用程…

HBuilderX创建uniapp项目使用 tailwindcss

文章目录 一、创建package.json文件二、打开终端 yarn / npm 安装依赖三、创建 vue.config.js文件四、创建postcss.config.js文件五、创建tailwind.config.js文件六、App.vue文件的style中引入tailwindcss 一、创建package.json文件 {"devDependencies": {"aut…

蓝桥杯算法 一.

分析&#xff1a; 本题记录&#xff1a;m个数&#xff0c;异或运算和为0&#xff0c;则相加为偶数&#xff0c;后手获胜。 分析&#xff1a; 369*99<36500&#xff0c;369*100>36500。 注意&#xff1a;前缀和和后缀和问题

知识(202402)

1.Conditional Conditional来源于spring-context包下的一个注解。Conditional中文是条件的意思&#xff0c;Conditional注解它的作用是按照一定的条件进行判断&#xff0c;满足条件给容器注册bean。 可以控制一个配置类是否注入到容器中&#xff0c;比如控制xxl-job不自动注册…

【wpf】关于绑定的一点明悟

背景简介 软件功能为&#xff0c;读取一个文件夹下的所有子文件夹&#xff0c;每个文件夹对自动对应生成 一组 “按键四个勾选” 按键点击触发&#xff0c;可以发送与其对应文件夹中的一些内容。这个绑定的过程我在之前的文章有过详细的介绍&#xff0c;非常的简单。 这里回顾…

3月1日做题总结(静态库与动态库)

前言 最近学到了静态库和动态库的相关知识&#xff0c;就顺便整理了一下相关题目。如果对静态库和动态库知识不熟悉的同学&#xff0c;推荐看这篇文章——《静态库与动态库》&#xff0c;讲的很详细。 第一题 关于静态库与动态库的区别&#xff0c;以下说法错误的是&#xff…

mac jupyter使用现有的python环境

mood&#xff1a;python 编程真的是在反复的与自己和解啊 本来超级的畏难情绪 读会儿书 计算机博士的书 感觉还是要坚强的。《研磨记》--一位博士生的回忆录 作者技术真的强啊 正文开始&#xff1a; 聚焦搜索&#xff0c;打开终端激活虚拟环境&#xff1a;conda activate pyt…

力扣爆刷第83天之hot100五连刷1-5

力扣爆刷第83天之hot100五连刷1-5 文章目录 力扣爆刷第83天之hot100五连刷1-5一、1. 两数之和二、49. 字母异位词分组三、128. 最长连续序列四、283. 移动零五、11. 盛最多水的容器 一、1. 两数之和 题目链接&#xff1a;https://leetcode.cn/problems/two-sum/description/?…

javascript中使用‘use strict’和不使用的区别

错误处理&#xff1a; 严格模式使得 JavaScript 对某些可能的问题抛出错误&#xff0c;而在非严格模式下&#xff0c;这些问题可能会被忽略。例如&#xff0c;未声明的变量&#xff08;即全局变量&#xff09;在非严格模式下会被隐式地创建为全局变量&#xff0c;而在严格模式…

十一、 二进制位运算

描述 Python有位运算&#xff0c;是直接将数字看成二进制&#xff0c;直接对二进制数字的每一位进行运算。现输入两个十进制整数x、y&#xff0c;请计算它们的位与、位或&#xff0c;输出按照十进制的形式。 输入描述&#xff1a; 一行输入两个整数x、y&#xff0c;以空格间…

git:合并两个不同仓库的代码

有两个代码仓库&#xff1a;代码仓库A、代码仓库B&#xff0c;其中一个仓库的代码是为了新项目拉取的新分支&#xff0c;所以分支的部分修改历史是相同的 现在要将代码仓库B 的代码合并到代码仓库A 实现思路&#xff1a;分支合并 实现步骤&#xff1a; # 1、clone代码仓库A…

外汇天眼:ASIC 获得针对前 Blockchain Global 董事的临时出行限制令

澳大利亚证券与投资委员会&#xff08;ASIC&#xff09;已经针对前Blockchain Global Limited&#xff08;清算中&#xff09;董事梁国&#xff08;又名Allan Guo&#xff09;获得了临时旅行限制令。这些命令在其他方面&#xff0c;阻止郭先生在2024年8月20日或进一步命令之前离…

(done) 如何计算 Hessian Matrix 海森矩阵 海塞矩阵

参考视频1&#xff1a;https://www.bilibili.com/video/BV1H64y1T7zQ/?spm_id_from333.337.search-card.all.click 参考视频2&#xff08;正定矩阵&#xff09;&#xff1a;https://www.bilibili.com/video/BV1Ag411M76G/?spm_id_from333.337.search-card.all.click&vd_…

【JGit】 AddCommand 新增的文件不能添加到暂存区

执行git.add().addFilepattern(".").setUpdate(true).call() 。新增的文件不能添加到暂存区&#xff0c;为什么&#xff1f; 在 JGit 中&#xff0c;setUpdate(true) 方法用于在调用 AddCommand 的 addFilepattern() 方法时&#xff0c;将已跟踪文件标记为需要更新。…

C语言基础—习题及代码(一)

1.读取一个65到122之间的整型数&#xff0c;然后以字符形式输出它&#xff0c;比如读取了97&#xff0c;输出字符a #include <stdio.h> int main(){int n;scanf("%d",&n);if(n>65 && n<122){printf("%c\n",n);} } 2.判断某个年份…

windows安装部署node.js以及搭建运行第一个Vue项目

一、官网下载安装包 官网地址&#xff1a;https://nodejs.org/zh-cn/download/ 二、安装程序 1、安装过程 如果有C/C编程的需求&#xff0c;勾选一下下图所示的部分&#xff0c;没有的话除了选择一下node.js安装路径&#xff0c;直接一路next 2、测试安装是否成功 【winR】…