什么是BST二叉排序(搜索)树?

news/2024/4/27 4:27:08/文章来源:https://blog.csdn.net/qq_53830608/article/details/128420128

目录

一、概念

1.定义

2.BST的优点

二、C++代码实现

1.先创建二叉树

2.二叉树中查找value值

添加判断最大值和最小值功能


引言:

        对于有序的查找,查找可以用折半、插值、斐波那契等查找算法来实现,找到后返回该位置,没找到插入到该位置,但是插入的话把后面元素全部后移,因为有序,在插入和删除操作上,就需要耗费大量的时间。无序的查找更是麻烦。

        而二叉排序树就是一种既可以使得插入和删除效率不错,又可以比较高效率地实现查找的算法

一、概念

1.定义

BST--二叉排序树(二叉搜索树)要么是空树,要么是具有下列性质的二叉树

  1. 如果有左子树,则左子树上所有节点的值都小于根节点
  2. 如果有右子树,则右子树上所有节点的值都大于根节点(左小右大)
  3. 左子树和右子树分别也是BST
  4. 对BST进行中序遍历,则是按照从小到大排序好的
  5. 最左侧的节点是值最小的节点
  6. 最右侧的节点是值最大的节点

2.BST的优点

        不是仅仅为了查找,还为了插入元素和删除元素的方便(插入和删除不用移动)

二、C++代码实现

1.先创建二叉树

思路:

  1. 把有序集合用二叉树的结构进行创建。该树叫做二叉排序树BST/二叉搜索树。
  2. 然后比根小放左子树,比根大放右子树。

创建BST树代码:

#include<iostream>
using namespace std;class Node
{
public:Node() :m_left(NULL), m_right(NULL) {}Node(int v) :m_value(v), m_left(NULL), m_right(NULL) {}int m_value;//根节点的值Node* m_left;//指向左孩子指针Node* m_right;//指向有孩子指针
};
class BSTree
{
public:BSTree() :m_root(NULL) {}void InsertBSTValue(int v)//每次的根节点都不一样,所以需要两个insert(),两个sort(){InsertBSTValue(m_root, v);}void InsertBSTValue(Node*& root, int v);Node* SearchValue(int v){return SearchValue(m_root, v);}Node* SearchValue(Node* root, int v);void Sort(){Sort(m_root);}void Sort(Node* root);//排序不改值,无需设计为&引用void DelValue(int v){DelValue(m_root, v);}private:Node* m_root;
};//排序即是进行中序遍历
void BSTree::Sort(Node* root)
{if (root != NULL){Sort(root->m_left); //左cout << root->m_value << " "; //根Sort(root->m_right); //右}
}//插入节点数
void BSTree::InsertBSTValue(Node*& root, int v)//要修改Node,设计为引用类型&,每个节点其实都是根
{if (root == NULL) //作为根节点{root = new Node(v);}else if (v > root->m_value) //比根节点大,则作为根的右子树{InsertBSTValue(root->m_right, v);}else if (v < root->m_value)//比根节点小,则作为根的左子树{InsertBSTValue(root->m_left, v);}
}void main()
{int num[] = { 62,88,58,47,35,73,51,99,37,93 };BSTree bst;//创建空树//插入数据到二叉树int n = sizeof(num) / sizeof(num[0]);for (int i = 0; i < n; i++)bst.InsertBSTValue(num[i]);cout << "Sort:" << endl;bst.Sort();cout << endl;
}

2.二叉树中查找value值

  1. 待查找的值vlaue和根节点比较
    1. 比根大,往右走
    2. 比跟小,往左走
  2. 没有找到返回空,调用insert()插入该值

代码如下,还添加了删除的功能

#include<iostream>
using namespace std;class Node
{
public:Node() :m_left(NULL), m_right(NULL) {}Node(int v) :m_value(v), m_left(NULL), m_right(NULL) {}int m_value;//根节点的值Node* m_left;//指向左孩子指针Node* m_right;//指向有孩子指针
};
class BSTree
{
public:BSTree() :m_root(NULL) {}void InsertBSTValue(int v)//每次的根节点都不一样,所以需要两个insert(),两个sort(){InsertBSTValue(m_root, v);}void InsertBSTValue(Node*& root, int v);Node* SearchValue(int v){return SearchValue(m_root, v);}Node* SearchValue(Node* root, int v);void Sort(){Sort(m_root);}void Sort(Node* root);//排序不改值,无需设计为&引用void DelValue(int v){DelValue(m_root, v);}void DelValue(Node*& root, int v);bool IsEmpty()const{return m_root == NULL;}
private:Node* m_root;
};Node* BSTree::SearchValue(Node* root, int v)
{if (root == NULL) //已经找到叶子节点的孩子了,还没有找到,则没有{return NULL;}else if (v > root->m_value) //在当前root的右子树进行查找{SearchValue(root->m_right, v);}else if (v < root->m_value) //在当前root的左子树进行查找{SearchValue(root->m_left, v);}elsereturn root;
}
//排序即是进行中序遍历
void BSTree::Sort(Node* root)
{if (root != NULL){Sort(root->m_left); //左cout << root->m_value << " "; //根Sort(root->m_right); //右}
}//插入节点数
void BSTree::InsertBSTValue(Node*& root, int v)//要修改Node,设计为引用类型&,每个节点其实都是根
{if (root == NULL) //作为根节点{root = new Node(v);}else if (v > root->m_value) //比根节点大,则作为根的右子树{InsertBSTValue(root->m_right, v);}else if (v < root->m_value)//比根节点小,则作为根的左子树{InsertBSTValue(root->m_left, v);}
}void BSTree::DelValue(Node*& root, int v)
{Node* temp = NULL;if (root != NULL){if (v < root->m_value)DelValue(root->m_left, v);else if (v > root->m_value)DelValue(root->m_right, v);else if (root->m_left != NULL && root->m_right != NULL){/*temp = root->m_right;while (temp->m_left != NULL)temp = temp->m_left;root->m_value = temp->m_value;DelValue(root->m_right, root->m_value);*/temp = root->m_left;while (temp->m_right != NULL)temp = temp->m_right;root->m_value = temp->m_value;DelValue(root->m_left, root->m_value);}else{temp = root;if (root->m_left == NULL)root = root->m_right;elseroot = root->m_left;delete temp;temp = NULL;}}
}
void main()
{int num[] = { 62,88,58,47,35,73,51,99,37,93 };BSTree bst;//创建空树//插入数据到二叉树int n = sizeof(num) / sizeof(num[0]);for (int i = 0; i < n; i++)bst.InsertBSTValue(num[i]);cout << "Sort:" << endl;bst.Sort();cout << endl;cout << "查找元素,如果没有找到,则进行插入,找到了,则输出" << endl;Node* p = bst.SearchValue(60);if (p == NULL){cout << "没找到,则进行插入,结果为" << endl;bst.InsertBSTValue(60);bst.Sort();cout << endl;}else{cout << "找到了" << p->m_value << endl;}cout << "删除节点" << endl;bst.DelValue(62);bst.Sort();
}

添加判断最大值和最小值功能

判断最大值:右子树最右侧

最小值:左子树最左侧

代码:

#include<iostream>
using namespace std;class Node
{
public:Node() :m_left(NULL), m_right(NULL) {}Node(int v) :m_value(v), m_left(NULL), m_right(NULL) {}int m_value;//根节点的值Node* m_left;//指向左孩子指针Node* m_right;//指向有孩子指针
};
class BSTree
{
public:BSTree() :m_root(NULL) {}void InsertBSTValue(int v)//每次的根节点都不一样,所以需要两个insert(),两个sort(){InsertBSTValue(m_root, v);}void InsertBSTValue(Node*& root, int v);Node* SearchValue(int v){return SearchValue(m_root, v);}Node* SearchValue(Node* root, int v);void Sort(){Sort(m_root);}void Sort(Node* root);//排序不改值,无需设计为&引用void DelValue(int v){DelValue(m_root, v);}void DelValue(Node*& root, int v);Node* GetMax()const;Node* GetMin()const;bool IsEmpty()const{return m_root == NULL;}
private:Node* m_root;
};
Node* BSTree::GetMax()const
{Node* p = m_root;if (p != NULL){while (p->m_right != NULL)p = p->m_right;return p;}
}
Node* BSTree::GetMin()const
{Node* p = m_root;if (p != NULL){while (p->m_left != NULL){p = p->m_left;}return p;}
}
Node* BSTree::SearchValue(Node* root, int v)
{if (root == NULL) //已经找到叶子节点的孩子了,还没有找到,则没有{return NULL;}else if (v > root->m_value) //在当前root的右子树进行查找{SearchValue(root->m_right, v);}else if (v < root->m_value) //在当前root的左子树进行查找{SearchValue(root->m_left, v);}elsereturn root;
}
//排序即是进行中序遍历
void BSTree::Sort(Node* root)
{if (root != NULL){Sort(root->m_left); //左cout << root->m_value << " "; //根Sort(root->m_right); //右}
}//插入节点数
void BSTree::InsertBSTValue(Node*& root, int v)//要修改Node,设计为引用类型&,每个节点其实都是根
{if (root == NULL) //作为根节点{root = new Node(v);}else if (v > root->m_value) //比根节点大,则作为根的右子树{InsertBSTValue(root->m_right, v);}else if (v < root->m_value)//比根节点小,则作为根的左子树{InsertBSTValue(root->m_left, v);}
}void BSTree::DelValue(Node*& root, int v)
{Node* temp = NULL;if (root != NULL){if (v < root->m_value)DelValue(root->m_left, v);else if (v > root->m_value)DelValue(root->m_right, v);else if (root->m_left != NULL && root->m_right != NULL){/*temp = root->m_right;while (temp->m_left != NULL)temp = temp->m_left;root->m_value = temp->m_value;DelValue(root->m_right, root->m_value);*/temp = root->m_left;while (temp->m_right != NULL)temp = temp->m_right;root->m_value = temp->m_value;DelValue(root->m_left, root->m_value);}else{temp = root;if (root->m_left == NULL)root = root->m_right;elseroot = root->m_left;delete temp;temp = NULL;}}
}
void main()
{int num[] = { 62,88,58,47,35,73,51,99,37,93 };BSTree bst;//创建空树//插入数据到二叉树int n = sizeof(num) / sizeof(num[0]);for (int i = 0; i < n; i++)bst.InsertBSTValue(num[i]);cout << "Sort:" << endl;bst.Sort();cout << endl;cout << "查找元素,如果没有找到,则进行插入,找到了,则输出" << endl;Node* p = bst.SearchValue(60);if (p == NULL){cout << "没找到,则进行插入,结果为" << endl;bst.InsertBSTValue(60);bst.Sort();cout << endl;}else{cout << "找到了" << p->m_value << endl;}cout << "删除节点" << endl;bst.DelValue(62);bst.Sort();cout << endl;if (!bst.IsEmpty()){cout << "最小值为:" << bst.GetMin()->m_value << endl;cout << "最大值为:" << bst.GetMax()->m_value << endl;}
}

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

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

相关文章

Yolo v1 笔记

个人不太懂的点 1.损失函数的4与5项 【论文解读】Yolo三部曲解读——Yolov1 - 知乎 https://www.youtube.com/watch?vNkFENlEb4kM&t672s 训练阶段&#xff1a; C_i 预测值&#xff1a;由网络输出出来7*7*30中第一个bbox和第二个bbox的置信度confidence C_i^hat 标签值…

PTA L2-046 天梯赛的赛场安排 (25 分)

天梯赛使用 OMS 监考系统&#xff0c;需要将参赛队员安排到系统中的虚拟赛场里&#xff0c;并为每个赛场分配一位监考老师。每位监考老师需要联系自己赛场内队员对应的教练们&#xff0c;以便发放比赛账号。为了尽可能减少教练和监考的沟通负担&#xff0c;我们要求赛场的安排满…

C++ 类和对象(中)构造函数 和 析构函数

上篇链接&#xff1a;C 类和对象&#xff08;上&#xff09;_chihiro1122的博客-CSDN博客 类的6个默认成员函数 我们在C当中&#xff0c;在写一些函数的时候&#xff0c;比如在栈的例子&#xff1a; 如上述例子&#xff0c;用C 返回这个栈是否为空&#xff0c;直接返回的话&am…

利用Python操作Mysql数据库

我们在进行Python编程的时候&#xff0c;时常要将一些数据保存起来&#xff0c;其中最方便的莫过于保存在文本文件了。但是如果保存的文件太大&#xff0c;用文本文件就不太现实了&#xff0c;毕竟打开都是个问题&#xff0c;这个时候我们需要用到数据库。提到数据库&#xff0…

json模块和pickle模块

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 json和pickle模块 json模块序列化与反序列化json模块中的方法 pickle模块 专栏&#xff1a;《python从…

JAVAweb开发学习

六、MybatisPlus快速上手 数据库操作 注意&#xff01;注意&#xff01;注意&#xff01;springboot版本选择2.7.2 1.ORM介绍&#xff08;对象关系映射&#xff09; 既包含存储&#xff0c;又包含映射。将java类映射到数据库 2.MybatisPlus介绍 ORM框架 数据库操作来啦…

【计算机网络】为什么 TCP 每次建立连接时,初始化序列号都要不一样呢?

【计算机网络】为什么 TCP 每次建立连接时&#xff0c;初始化序列号都要不一样呢&#xff1f; 为什么 TCP 每次建立连接时&#xff0c;初始化序列号都要不一样呢&#xff1f; 主要原因是为了防止历史报文被下一个相同四元组的连接接收。 TCP 四次挥手中的 TIME_WAIT 状态不是会…

机械键盘、口袋打印机,万元奖金等你拿!「万象格新」AI绘画X海报设计大赛即将开启...

号外&#xff01;「万象格新」大赛开启 如果阳光暖到你心里&#xff0c;那一定是一格在想你~ 春夏交替&#xff0c;万物焕发生机&#xff0c;明媚色彩娱情惬意 在这样一个美好的时节 如果你&#xff1a; 心中荡漾着色彩斑斓的 AI 绘画创意 想要 show 出独到的审美与非凡设计能力…

吴恩达团队AI诊断心律失常研究:准确率超人类医生

2019年&#xff0c;吴恩达团队在AI医疗领域实现了一项革命性的突破&#xff0c;他们成功地让AI诊断心律失常&#xff0c;其准确率高达83.7%&#xff0c;超过了人类心脏病医生的78.0%。这项研究成果已经发表在了知名期刊Nature Medicine上。 一、如何让AI学会诊断心律失常&…

闲谈【Stable-Diffusion WEBUI】的插件:美不美?交给AI打分

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;咖啡店艺术评价&#xff08;Cafe Aesthetic&#xff09; &#xff08;零&#xff09;前言 本篇主要提到了WEBUI的Cafe Aesthetic插件&#xff0c;这是一个相对独立的插件&#xff0c;单独标签页&#xff0c;…

Python小姿势 - Python基础知识

Python基础知识 Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。 Python的创始人为吉多范罗苏姆&#xff08;Guido van Rossum&#xff09;&#xff0c;于1989年底发布第一个公开发行版本——0.9.0。 自2004年以来&#xff0c;Python已经成为顶级开源项目&…

希尔排序的实现

希尔排序是插入排序的一种升级&#xff0c;其基本思想是&#xff1a; 先选定一个整数&#xff0c;把待排序文件中所有记录分成个组&#xff0c;所有距离为的记录分在同一组内&#xff0c;并对每 一组内的记录进行排序。然后&#xff0c;取&#xff0c;重复上述分组和排序的工 作…

使用Linux运维常识

一.基础操作 1.终端常用快捷键 快捷键描述ctrl键盘左键向左跳一个单词ctrl键盘右键向右跳一个单词Ctrl c停止当前正在运行的命令。Ctrl z将当前正在运行的命令放入后台并暂停它的进程。Ctrl d关闭当前终端会话。Ctrl l清屏&#xff0c;也可以用clear命令实现Tab自动补全当…

Asp.NET CORE实验室信息管理系统源码,支持IIS独立部署,Docker部署

技术架构&#xff1a;Asp.NET CORE 3.1 MVC SQLserver Redis等 基于B/S架构的实验室管理系统源码&#xff0c;整个系统的运行基于WEB层面&#xff0c;只需要在对应的工作台安装一个浏览器软件有外网即可访问。全套系统采用云部署模式&#xff0c;部署一套可支持多家医院检验…

自定义RecyclerView.LayoutManager实现类实现卡片层叠布局的列表效果

一.前言 先看效果&#xff08;大佬们请忽略水印&#xff09;&#xff1a; 卡片层叠列表的实现效果已经发布成插件&#xff0c;集成地址&#xff1a;implementation ‘com.github.MrFishC:YcrCardLayoutHepler:v1.1’&#xff1b; 先讲解如何快速实现&#xff0c;然后再来讲解…

托福高频真词List05 // 附托福TPO阅读真题

目录 4月23日单词 生词 熟词 4月24日真题 4月23日单词 生词 sparsethinly distributedadj 稀疏的sparselythinlyadv 稀疏地congestion / kənˈdʒestʃən / overcrowdingn 拥挤continuallyregularlyadv 持续的eradicateeliminatev 消除facilitatemake easiereasev 使..…

《面试1v1》java泛型

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a;小伙子,说实话,泛型这个机制一开始我也是一头雾水,搞不太明白它到底要解决什么问题。你能不能不那么书呆子,给我普普通通地讲一讲泛型? 候选人…

如何测试信号源或者发射机的回波损耗

信用源或者发射机的return loss测试过程 1.用网分线缆的第一步就是看线的抖动情况&#xff0c;后面还是要多注意 经过一系列排查后&#xff0c;选用两个抖动比较小的线缆&#xff0c;然后开始测试另外一台仪器。 2.检查测试仪器的输出功率&#xff0c;见图1 打开信号源或者发射…

可以一学的代码优化小技巧:减少if-else冗余

前言 if-else 语句对于程序员来说&#xff0c;是非常非常熟悉的一个判断语句&#xff0c;我们在日常开发和学习中都经常看见它&#xff0c;if-else语句主要用于需要做出选择的地方进行判断&#xff0c;这里就不再赘述if-else语法和特点了。 ​ 我们在写代码&#xff08;如图下…

PC1 - 搭建项目

先看路由&#xff0c;可以查看功能模块划分。熟悉什么看什么 router文件夹下routerConfig.tsx 配置路由&#xff0c;创建模块文件&#xff08;写好内容模块&#xff09;&#xff0c;lazy可懒加载导入。App.tsx配置一级路由&#xff0c;配置二级路由出口 { path:/, element: …