【C++】实现一个二叉搜索树

 


目录

二叉搜索树的概念

1.结点定义

2.构造、析构、拷贝构造、赋值重载

3.插入、删除、查找、排序

3.1插入

3.2插入递归版

3.3查找指定值

3.3查找指定值递归版

3.4中序遍历

3.5删除

最后


二叉搜索树的概念

二叉搜索树又称为二叉排序树或二叉查找树,它或者是一棵空树,或者是具有以下性质的二叉树:

  • 非空左子树上所有结点的值都小于根结点的值。
  • 非空右子树上所有结点的值都大于根结点的值。
  • 左右子树都是二叉搜索树。

1.结点定义

template<class K>
struct BSTreeNode
{BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_key(key),_left(nullptr),_right(nullptr){}
};

2.构造、析构、拷贝构造、赋值重载

    //构造函数BSTree(): _root(nullptr){}//析构函数~BSTree(){//递归删除Destroy(_root);_root = nullptr;}//拷贝构造BSTree(const BSTree<K>& t){//递归去拷贝_root = Copy(t._root);}//赋值重载BSTree<K>& operator=(BSTree<K> t)//注意这里传参,传值传参,默认已经拷贝构造新的一份了{swap(_root, t._root);//这里直接交换return 就好return *this;}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;}void Destroy(Node* root){if (root == nullptr){return;}Destroy(_root->_left);Destroy(_root->_right);delete(root);}

3.插入、删除、查找、排序

3.1插入

bool Insert(const K& key){//不允许相等数据插入版本,减少冗余//空树if (_root == nullptr){_root = new Node(key);return true;}//正常插入Node* cur = _root;Node* parent = _root;while (cur != nullptr){if (key > cur->_key){parent = cur;cur = cur->_right;}else if (key < cur->_key){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(key);if (key > parent->_key){parent->_right = cur;}else{parent->_left = cur;}return true;}

3.2插入递归版

bool InsertR(const K& key)//注意参数{return _InsertR(_root, key);}
bool _InsertR(Node* &root,const K& key){if (root == nullptr){root = new Node(key);return true;}if (root->_key > key){return _InsertR(root->_left, key);}else if (root->_key < key){return _InsertR(root->_right, key);}else{//相等return false;}}

3.3查找指定值

bool Find(const K& key){Node* cur = _root;while (cur!=nullptr){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else{return true;}}return false;}

3.3查找指定值递归版

    bool FindR(const K& key){return _FindR(_root, key);}bool _FindR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key == key){return true;}if (root->_key > key){return _FindR(root->_left, key);}else {return _FindR(root->_right, key);}}

3.4中序遍历

    void InOrder(){_InOrder(_root);}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}

3.5删除

bool Erase(const K& key){Node* cur = _root;Node* parent = _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->_right == nullptr){if (parent->_left == cur){parent->_left = cur->_left;}if (parent->_right == cur){parent->_right = cur->_left;}if(parent==cur)//是根结点{parent = parent->_left;}delete(cur);return true;}else if(cur->_left==nullptr){if (parent->_left == cur){parent->_left = cur->_right;}if (parent->_right == cur){parent->_right = cur->_right;}if (parent == cur)//是根结点{parent = parent->_right;}delete(cur);return true;}else{//左右都不为空//替换法删除,找右子树的最小值Node* miniright = cur->_right;Node* minirightp = cur;while (miniright->_left != nullptr){minirightp = miniright;miniright = miniright->_left;}cur->_key = miniright->_key;if (minirightp->_left == miniright){minirightp->_left = miniright->_right;}if (minirightp->_right == miniright){minirightp->_right = miniright->_right;}delete(miniright);return true;}}}return false;}


最后

加油

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

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

相关文章

JVM垃圾回收机制及调优工具Arthas的使用

文章目录 1、JVM垃圾回收机制1.1 针对的内存区域1.2 怎么判断对象是否可以被回收&#xff1f;1.3 垃圾收集算法1.3.1 **标记-清除&#xff08;Mark-Sweep&#xff09;**1.3.2 复制&#xff08;Copying&#xff09;1.3.3 标记-整理&#xff08;Mark-Compact&#xff09;1.3.4 分…

百面嵌入式专栏(面试题)驱动开发面试题汇总1.0

沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍驱动开发面试题 。 1、Linux驱动程序的功能是什么? 对设备初始化和释放。进行内核与硬件的数据交互。检测和处理设备出现的错误。2、内核程序中申请内存使用什么函数? 答案:kmalloc()、kzalloc()、vm…

亚信安慧AntDB领航分布式数据库的突破之路

随着互联网技术的迅猛发展&#xff0c;大数据时代的到来&#xff0c;数据库的需求不断增长。在这样的背景下&#xff0c;国产分布式数据库正逐渐崭露头角&#xff0c;AntDB作为其中的重要代表&#xff0c;也积极参与到了这场竞争中。作为国内的技术创新者&#xff0c;AntDB不仅…

通过 docker-compose 部署 Flink

概要 通过 docker-compose 以 Session Mode 部署 flink 前置依赖 Docker、docker-composeflink 客户端docker-compose.yml version: "2.2" services:jobmanager:image: flink:1.17.2ports:- "8081:8081"command: jobmanagervolumes:- ${PWD}/checkpoin…

modelsim仿真使用到vivado的IP,该如何使用!

modelsim仿真时&#xff0c;如果使用到了vivado的IP就会报错&#xff0c;本次就告诉大家如何将vivado的IP添加到modelsim中直接仿真。 一、生成ini文件以及IP打包 打开vivado&#xff0c;点击上方的Tools-->Compile Simulation Libraries得到如下界面 simulator&#xff1…

【Flink入门修炼】1-2 Mac 搭建 Flink 源码阅读环境

在后面学习 Flink 相关知识时&#xff0c;会深入源码探究其实现机制。因此&#xff0c;需要现在本地配置好源码阅读环境。 本文搭建环境&#xff1a; Mac M1&#xff08;Apple Silicon&#xff09;Java 8IDEAFlink 官方源码 一、 下载 Flink 源码 github 地址&#xff1a;h…

日历功能——C语言

实现日历功能&#xff0c;输入年份月份&#xff0c;输出日历 #include<stdio.h>int leap_year(int year) {if(year % 4 0 && year % 100 ! 0 || year % 400 0){return 1;}else{return 0;} }int determine_year_month_day(int *day,int month,int year) {if(mo…

【刷题日记】最长定差子序列

给你一个整数数组 arr 和一个整数 difference&#xff0c;请你找出并返回 arr 中最长等差子序列的长度&#xff0c;该子序列中相邻元素之间的差等于 difference 。 子序列 是指在不改变其余元素顺序的情况下&#xff0c;通过删除一些元素或不删除任何元素而从 arr 派生出来的序…

挑战杯 python+深度学习+opencv实现植物识别算法系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的植物识别算法研究与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;4分 &#x1f9ff; 更多…

ElastAlert 错误日志告警

文章目录 前言一、ElastAlert 概览1.1 简介1.2 ElastAlert 特性 二、ElastAlert 下载部署2.1 安装 Python3 环境2.2 下载 ElastAlert2.3 部署 ElastAlert 三、接入平台3.1 对外接口层3.2 服务层 前言 ElastAlert 是 Yelp 公司基于 python 开发的 ELK 日志告警插件&#xff0c;…

JavaWeb后端——控制反转IOC/依赖注入DI

控制反转&#xff1a;why&#xff0c;目标是要做到控制反转 依赖注入&#xff1a;how&#xff0c;如何实现控制反转&#xff0c;控制反转有很多方法&#xff0c;依赖注入是其中一种方法 控制反转&#xff08;Inversion of Control, IoC&#xff09;和依赖注入&#xff08;Depe…

JavaEE企业级应用软件开发—Spring框架入门学习笔记(一)

一、认识框架 实际开发中&#xff0c;随着业务的发展&#xff0c;软件系统变得越来越复杂&#xff0c;如果所有的软件都从底层功能开始开发&#xff0c;那将是一个漫长而繁琐的过程。此外&#xff0c;团队协作开发时&#xff0c;由于没有统一的调用规范&#xff0c;系统会出现大…