C++实现二叉搜索树的增删查改(非递归玩法)

文章目录

    • 一、二叉搜索树的概念结构和时间复杂度
    • 二、二叉搜索树的插入
    • 三、二叉搜索树的查找
    • 四、二叉搜索树的删除(最麻烦,情况最多,一一分析)
      • 3.1首先我们按照一般情况下写,不考虑特殊情况下
        • 4.1.1左为空的情况(与右为空的情况差不多)
        • 4.1.2两边都不为空的情况下
      • 4.1其次我们考虑极端情况,如果刚好是整体树的根要删除
    • 五、二叉搜索树的中序遍历
    • 六、二叉搜索树的拷贝构造函数,析构函数,赋值操作
      • 6.1 赋值操作(比较简单)
      • 6.2拷贝构造
      • 6.3析构函数
    • 七、全部源码展现(递归玩法的代码也传进来了,下次讲解)

在这里插入图片描述


先赞后看,养成习惯!!!^ _ ^<3 ❤️ ❤️ ❤️
码字不易,大家的支持就是我坚持下去的动力。点赞后不要忘了关注我哦!
所属专栏:C++进阶
在这里插入图片描述

一、二叉搜索树的概念结构和时间复杂度

二叉搜索树(Binary Search Tree)又称二叉排序树(Binary Sort Tree),是一种特殊类型的二叉树,它所有的根节点大于左子树的节点,小于右子树的节点,对二叉搜索树进行中序遍历,即可得到有序的数列。二叉搜索树的时间复杂度由树的高度决定,其搜索、插入和删除的时间复杂度均为 O(log n),其中 n 是节点数。在最坏的情况下,仍然会有 O(n)的时间复杂度。
在这里插入图片描述

二、二叉搜索树的插入

首先定义一个命名空间作用域,在域中进行插入操作,构造一个二叉树的节点,对节点进行初始化构造

namespace key
{template<class K>struct BSTreeNode{typedef BSTreeNode<K> Node;BSTreeNode(const K& key):left(nullptr), right(nullptr),_key(key){}Node* left;Node* right;K _key;};template<class K>class BSTree{public:bool Insert(const K& key){Node* root = new Node(key);if (_root == nullptr){_root = root;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key > root->_key){parent = cur;cur = cur->left;}else if (cur->_key < root->_key){parent = cur;cur = cur->right;}else{return false;}}if (parent->_key < root->_key)parent->right = root;elseparent->left = root;return true;}
}

代码图解:
在这里插入图片描述

三、二叉搜索树的查找

查找非常简单按照流程找就行了

typedef BSTreeNode<K> Node;
bool Find(const K& key)
{Node* cur = _root;while (cur){if (cur->_key < key){cur = cur->right;}else if (cur->_key > key){cur = cur->left;}else{return true;}}return false;
}

四、二叉搜索树的删除(最麻烦,情况最多,一一分析)

3.1首先我们按照一般情况下写,不考虑特殊情况下

bool Erase(const K& key)
{assert(_root);Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key > key){parent = cur;cur = cur->left;}else if (cur->_key < key){parent = cur;cur = cur->right;}else{if (cur->left == nullptr){if (parent->left == cur){parent->left = cur->right;}else{parent->right = cur->right;}delete cur;return true;}else if (cur->right == nullptr){if (parent->left == cur){parent->left = cur->left;}else{parent->right = cur->left;}delete cur;return true;}else{Node* pminleft = cur;Node* minleft = cur->right;while (minleft->left){pminleft = minleft;minleft = minleft->left;}cur->_key = minleft -> _key;if (minleft == pminleft->left)pminleft->left = minleft->right;elsepminleft->right = minleft->right;delete minleft;return true;}}}return false;
}

代码图解(解释找到时候的情况)

4.1.1左为空的情况(与右为空的情况差不多)

在这里插入图片描述

4.1.2两边都不为空的情况下

在这里插入图片描述

4.1其次我们考虑极端情况,如果刚好是整体树的根要删除

在这里插入图片描述
调整代码如下

				if (cur->left == nullptr){if (cur == _root){_root = cur->right;}else{if (parent->left == cur){parent->left = cur->right;}else{parent->right = cur->right;}}delete cur;return true;}else if (cur->right == nullptr){if (cur == _root){_root = cur->left;}else{if (parent->left == cur){parent->left = cur->left;}else{parent->right = cur->left;}}delete cur;return true;
}

五、二叉搜索树的中序遍历

这里我们用了一个小技巧,就是通过类里面的函数调用类里面的私有成员

//中序遍历
void _Inorder()
{Inorder(_root);
}
private://中序遍历void Inorder(Node* root){if (root == nullptr)return;Inorder(root->left);cout << root->_key << ' ';Inorder(root->right);}Node* _root = nullptr;

六、二叉搜索树的拷贝构造函数,析构函数,赋值操作

6.1 赋值操作(比较简单)

BSTree<K>& operator=(const BSTree& root)
{swap(_root, root->_root);return *this;
}

6.2拷贝构造

BSTree(const BSTree<K>& t)
{_root = Copy(t._root);
}
Node* Copy(Node* root)
{if (root == nullptr)return nullptr;Node* newroot = new Node(root->_key);newroot->left = Copy(root->left);newroot->right = Copy(root->right);return newroot;
}

6.3析构函数

~BSTree()
{Distroy(_root);
}
void Distroy(Node* root)
{if (root == nullptr)return;Distroy(root->left);Distroy(root->right);delete root;
}

七、全部源码展现(递归玩法的代码也传进来了,下次讲解)

#pragma once
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;namespace key
{template<class K>struct BSTreeNode{typedef BSTreeNode<K> Node;BSTreeNode(const K& key):left(nullptr), right(nullptr),_key(key){}Node* left;Node* right;K _key;};template<class K>class BSTree{public://查BSTree() = default;//自动生成默认构造~BSTree(){Distroy(_root);}BSTree(const BSTree<K>& t){_root = Copy(t._root);}BSTree<K>& operator=(const BSTree& root){swap(_root, root->_root);return *this;}typedef BSTreeNode<K> Node;bool Find(const K& key){Node* cur = _root;while (cur){if (cur->_key < key){cur = cur->right;}else if (cur->_key > key){cur = cur->left;}else{return true;}}return false;}//增bool Insert(const K& key){Node* root = new Node(key);if (_root == nullptr){_root = root;return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key > root->_key){parent = cur;cur = cur->left;}else if (cur->_key < root->_key){parent = cur;cur = cur->right;}else{return false;}}if (parent->_key < root->_key)parent->right = root;elseparent->left = root;return true;}//删bool Erase(const K& key){assert(_root);Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key > key){parent = cur;cur = cur->left;}else if (cur->_key < key){parent = cur;cur = cur->right;}else{if (cur->left == nullptr){if (cur == _root){_root = cur->right;}else{if (parent->left == cur){parent->left = cur->right;}else{parent->right = cur->right;}}delete cur;return true;}else if (cur->right == nullptr){if (cur == _root){_root = cur->left;}else{if (parent->left == cur){parent->left = cur->left;}else{parent->right = cur->left;}}delete cur;return true;}else{Node* pminleft = cur;Node* minleft = cur->right;while (minleft->left){pminleft = minleft;minleft = minleft->left;}cur->_key = minleft -> _key;if (minleft == pminleft->left)pminleft->left = minleft->right;elsepminleft->right = minleft->right;delete minleft;return true;}}}return false;}/		//递归玩法//增bool _InsertR(const K& key){_Insert(_root,key);}bool _EraseR(const K& key){_Erase(_root, key);}bool _FindR(const K& key){_Find(_root,key);}void Distroy(Node* root){if (root == nullptr)return;Distroy(root->left);Distroy(root->right);delete root;}//中序遍历void _Inorder(){Inorder(_root);}private://中序遍历void Inorder(Node* root){if (root == nullptr)return;Inorder(root->left);cout << root->_key << ' ';Inorder(root->right);}bool _Insert(Node*& root,const K& key){if (root == nullptr){Node* newroot = new Node(key);root = newroot;return true;}if (root->_key > key){_Insert(root->left, key);}else if (root->_key < key){_Insert(root->right, key);}elsereturn false;}Node& _Find(Node*& root, const K& key){if (root == nullptr)return nullptr;if (root->_key > key){_Find(root->left);}else if (root->_key < key){_Find(root->right);}else{return root;}}Node* Copy(Node* root){if (root == nullptr)return nullptr;Node* newroot = new Node(root->_key);newroot->left = Copy(root->left);newroot->right = Copy(root->right);return newroot;}bool _Erase(Node*& root, const K& key){if (root == nullptr)return false;if (root->_key > key){return _Erase(root->left,key);}else if(root->_key < key){return _Erase(root->right ,key);}else{Node* minright = root->right;while (minright->left)minright = minright->left;swap(root->_key,minright->_key);minright->right = minright->right;delete minright;return true;}}Node* _root = nullptr;};
}

在这里插入图片描述

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

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

相关文章

【HTML】简单制作一个动态3D正方体

目录 前言 开始 HTML部分 JS部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;JS的文件名改…

数据仓库——聚集

数据仓库基础笔记思维导图已经整理完毕&#xff0c;完整连接为&#xff1a; 数据仓库基础知识笔记思维导图 聚集 在对性能不断探索的过程中&#xff0c;聚集是最强大最、有效的数据处理工具。通过仔细规划和集成&#xff0c;聚集将队数据仓库性能产生巨大影响。无需针对特定的…

win11安装wsl报错:无法解析服务器的名称或地址

一 说明 项目开发中&#xff0c;需要用到wsl&#xff0c;因此根据wsl官方&#xff08;WSL安装教程&#xff09;命令 wsl --install 进行wsl的安装。而本文主要是记录自己在安装wsl中遇到的问题 “无法解析服务器的名称或地址” 的解决办法。 二 方法一&#xff1a;更改DNS&…

在Go语言中如何避免接口污染

在设计和构造代码时,接口是Go语言的基石之一。然而,就像许多工具或概念一样,滥用它们通常不是一个好主意。接口污染就是用不必要的抽象使我们的代码变得难以理解。这是来自另一种编程语言具有不同习惯的开发人员经常犯的错误。在深入讨论这个话题之前,让我们重新思考一下Go…

Java文件内容查找:简单实现与应用

一、Java文件内容查找的基本原理 在Java中&#xff0c;文件内容查找可以通过读取文件并逐行检查每一行内容来实现。基本的流程包括以下几个步骤&#xff1a; 打开文件&#xff1a;使用Java的文件操作类&#xff08;如FileInputStream&#xff09;打开要查找的文件。 逐行读取…

算法练习----力扣每日一题------6

原题链接&#xff1a; 1379. 找出克隆二叉树中的相同节点 - 力扣&#xff08;LeetCode&#xff09; 题目解析&#xff1a; 给两个二叉树&#xff0c;original和它的克隆树cloned,二者存的数据和数据的相对位置完全一样&#xff0c;给一个o树里的节点target&#xff0c;求对应的…

Kotlin作用域函数:let、also、run、apply、with

​​​​​​​ let函数 使用场景&#xff1a;可空变量的操作&#xff0c;无需判空 p?.let {it.name "lily"it.age "21"} also函数 使用场景&#xff1a;多个扩展函数链式调用&#xff08;返回值是本身&#xff09; p?.also {it.name "den…

HCIA-RS基础-VLAN技术原理和配置

目录 VLAN 技术原理和配置1. VLAN 技术的背景2. VLAN 标签的产生方法3. VLAN 标签的应用规则4. VLAN 的配置总结 VLAN 技术原理和配置 1. VLAN 技术的背景 VLAN&#xff08;Virtual Local Area Network&#xff09;是一种逻辑上划分网络的技术&#xff0c;可以将一个物理局域…

Postman 请求参数传递指南:Query、Path 和 Body 详解

Postman 是一个非常流行的 API 开发环境&#xff0c;它允许开发者测试、开发和文档化他们的 API。在 Postman 中&#xff0c;当你发送一个请求时&#xff0c;你可能需要将参数传递给服务器。这些参数可以通过不同的方式传递&#xff0c;例如 Query Parameters&#xff08;查询参…

使用 select 标签,1 分钟完成一个简单的下拉菜单

在网上冲浪时&#xff0c;我们经常遇到需要做出选择的情况&#xff0c;比如选择你喜爱的电影类型、预订酒店的房间类型或者在网购时挑选衣服的尺码。 这些选择往往通过一个简洁明了的下拉菜单来实现&#xff0c;让我们的决策过程变得轻松愉快。这个神奇的下拉菜单&#xff0c;…

算法打卡day25

今日任务&#xff1a; 1&#xff09;491.递增子序列 2&#xff09;46.全排列 3&#xff09;47.全排列 II 491.递增子序列 题目链接&#xff1a;491. 非递减子序列 - 力扣&#xff08;LeetCode&#xff09; 给定一个整型数组, 你的任务是找到所有该数组的递增子序列&#xff0c…

composure合成透明通道

composure合成透明通道 2022-05-23 08:59 [技巧分享]使用配有HDRI的背板的进行合成 Using Composure with a Bac - 1.Using Composure with a Backplate and H.mp41启用插件2线性色彩空间3打开合成面板4面板新建合成新建三个图层 FG前面物体&#xff0c;背景物体 去掉阴影 flo…

Zabbix6 - Web管理网络拓扑/端口流量监控配置手册

Zabbix6 - Web管理网络拓扑/端口流量监控配置手册 概述: 1)Zabbix能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 Zabbix由两部分构成,Zabbix Server与可选组件Zabbix Agent。通过C/S模式采集数据,通过B…

60道Java经典面试题总结

1、Spring 有几种配置方式&#xff1f; 1、xml 配置文件 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:…

量化交易入门(四十一)ASI指标Python实现和回测

老规矩先上图&#xff0c;看看ASI指标使用苹果数据回测后的结果如何。 一、策略运行结果 执行的结果&#xff1a; Starting Portfolio Value: 100000.00 Final Portfolio Value: 92514.82 Annualized Return: -1.93% Sharpe Ratio: -0.27 Max Drawdown: 25.34% Max Drawdown …

【教学类-09-04】20240401细线迷宫图03(A4横版一页-4份横版)

作品展示&#xff1a; 背景需求&#xff1a; 【教学类-09-02】20240331细线迷宫图01&#xff08;A4横版一页1份横版&#xff09;-CSDN博客文章浏览阅读779次&#xff0c;点赞28次&#xff0c;收藏6次。【教学类-09-02】20240331细线迷宫图01&#xff08;A4横版一页1份横版&…

pm2进程监控

pm2 npm install -g pm2 npm install -g pm2-web //linux有效 command pm2 logs&#xff0c;实时显示日志pm2 list&#xff0c;查看启动进程pm2 stop id[name]&#xff0c;关闭进程&#xff0c;all所有pm2 kill&#xff0c;关闭所有pm2 monit&#xff0c;查看详细信息pm2 star…

汽车电子行业知识:UWB技术及应用

文章目录 1.什么是UWB技术1.1.UWB测距原理1.2.UWB数据传输原理2.汽车UWB技术应用2.1.UWB雷达2.1.1.信道的冲击响应CIR2.2.舱外检测目标2.3.舱内检测活体2.3.1.活体检测原理2.4.脚踢尾箱开门2.4.1.脚踢检测原理1.什么是UWB技术 UWB(ultra wideband)也叫超宽带技术,是一种使用…

机器学习周记(第三十二周:文献阅读-时空双通路框架)2024.3.25~2024.3.31

目录 摘要 ABSTRACT 1 论文信息 1.1 论文标题 1.2 论文摘要 1.3 论文模型 1.3.1 Spatial Encoder&#xff08;空间编码器&#xff09; 1.3.2 Temporal Encoder&#xff08;时间编码器&#xff09; 2 相关代码 摘要 本周阅读了一篇运用GNN进行时间序列预测的论文。论文…

【数据处理包Pandas】分组及相关操作

目录 一、初步认识分组并查看分组信息&#xff08;一&#xff09;通过聚合函数查看分组信息&#xff08;二&#xff09;转换成列表查看所有组的信息&#xff08;三&#xff09;通过循环查看各组的名称和组中的数据信息&#xff08;四&#xff09;通过get_group()方法直接获得一…