二叉排序树(BST)的创建,查找,插入,删除及最大最小结点

2024-05-02 18:58

本文主要是介绍二叉排序树(BST)的创建,查找,插入,删除及最大最小结点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考:https://blog.csdn.net/happyjacob/article/details/82795560

1、什么是二叉排序树

二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树

二叉搜索树:一棵二叉树,可以为空;如果不为空,满足以下性质:

  1. 非空左子树的所有键值小于其根结点的键值。
  2. 非空右子树的所有键值大于其根结点的键值。
  3. 左、右子树都是二叉搜索树。

2、二叉搜索树的查找操作

  • 查找从根结点开始,如果树为空,返回NULL

  • 若搜索树非空,则根结点关键字和X进行比较,并进行不同处理:

    1. 若X小于根结点键值,只需在左子树中继续搜索;
    2. 如果X大于根结点的键值,在右子树中进行继续搜索;
    3. 若两者比较结果是相等,搜索完成,返回指向此结点的指针。

å¨è¿éæå¥å¾çæè¿°

递归实现

//查找,递归实现
BTNode * SearchBST(BTree pT, ElemType key) {if (pT == nullptr)return nullptr;if (key > pT->val) {SearchBST(pT->right, key);}else if(key < pT->val){SearchBST(pT->left, key);}else {return pT;}
}

由于非递归函数的执行效率高,可将“尾递归”函数改为迭代函数

非递归实现

//查找,非递归实现
BTNode * SearchBST(BTree pT, ElemType key) {while (pT != nullptr) {if (key < pT->val) {pT = pT->left;}else if (key > pT->val) {pT = pT->right;}else {return pT;}}return nullptr;
}

3、查找最大和最小元素

最大元素一定是在树的最右分枝的端结点上
最小元素一定是在树的最左分枝的端结点上

å¨è¿éæå¥å¾çæè¿°

//递归寻找最大值
BTNode * findMax(BTree pT) {if (pT == nullptr)return nullptr;else {if (pT->right != nullptr) {findMax(pT->right);}else {return pT;}}
}//非递归寻找最小值
BTNode * findMin(BTree pT) {if (pT == nullptr)return nullptr;while (pT->left != nullptr) {pT = pT->left;}return pT;
}

4、二叉搜索树的插入

关键是要找到元素应该插入的位置,可以采用与Find类似的方法

可以用二叉搜索树的插入来创建二叉搜索树

//二叉搜索树的插入
BTree Insert(BTree pT, ElemType key) {if (pT == nullptr) {BTNode *node = new BTNode(key);}else if (key < pT->val) {pT->left = Insert(pT->left, key);}else if (key > pT->val) {pT->right = Insert(pT->right, key);}else {//节点存在,什么都不做,或者打印信息cout << "节点已经存在" << endl;}return pT;
}

5、二叉搜索树的删除

考虑三种情况:

  1. 要删除的结点的左孩子为空:右孩子代替当前结点

å¨è¿éæå¥å¾çæè¿°

     2.要删除的结点的右孩子为空:左孩子代替当前结点

    3.要删除的结点有左、右两棵子树: 用另一结点替代被删除结点:右子树的最小元素 或者 左子树的最大元素

å¨è¿éæå¥å¾çæè¿°

//二叉搜索树的删除
BTree Delete(ElemType x, BTree pT) {if (pT == nullptr) {return nullptr;}if (x > pT->val) {pT->right = Delete(x, pT->right);}else if (x < pT->val) {pT->left = Delete(x, pT->left);}else {if (pT->left && pT->right) {BTNode *tp = findMin(pT->right);pT->val = tp->val;pT->right = Delete(tp->val, pT->right);}else {if (pT->left == nullptr) {pT = pT->right;}else if (pT->right == nullptr) {pT = pT->left;}}	}return pT;
}

完整代码:

#include <iostream>
#include <vector>
#include <deque>using ElemType = int;using namespace std;typedef struct BTNode {ElemType val;struct BTNode *left, *right;BTNode(ElemType x) :val(x), left(nullptr), right(nullptr) {}
}BTNode, *BTree;//查找,递归实现
BTNode * SearchBST(BTree pT, ElemType key) {if (pT == nullptr)return nullptr;if (key > pT->val) {SearchBST(pT->right, key);}else if(key < pT->val){SearchBST(pT->left, key);}else {return pT;}
}//查找,非递归实现
BTNode * SearchBSTNonrecursion(BTree pT, ElemType key) {while (pT != nullptr) {if (key < pT->val) {pT = pT->left;}else if (key > pT->val) {pT = pT->right;}else {return pT;}}return nullptr;
}//查找最大和最小元素
//最大元素一定在树的最右分支的端节点上
//最小元素一定在树的最左分支的端节点上//递归寻找最大值
BTNode * findMax(BTree pT) {if (pT == nullptr)return nullptr;else {if (pT->right != nullptr) {findMax(pT->right);}else {return pT;}}
}//非递归寻找最小值
BTNode * findMin(BTree pT) {if (pT == nullptr)return nullptr;while (pT->left != nullptr) {pT = pT->left;}return pT;
}//二叉搜索树的插入
BTree Insert(BTree pT, ElemType key) {if (pT == nullptr) {pT = new BTNode(key);}else if (key < pT->val) {pT->left = Insert(pT->left, key);}else if (key > pT->val) {pT->right = Insert(pT->right, key);}else {//节点存在,什么都不做,或者打印信息cout << "节点已经存在" << endl;}return pT;
}//二叉搜索树的删除
BTree Delete(ElemType x, BTree pT) {if (pT == nullptr) {return nullptr;}if (x > pT->val) {pT->right = Delete(x, pT->right);}else if (x < pT->val) {pT->left = Delete(x, pT->left);}else {if (pT->left && pT->right) {BTNode *tp = findMin(pT->right);pT->val = tp->val;pT->right = Delete(tp->val, pT->right);}else {if (pT->left == nullptr) {pT = pT->right;}else if (pT->right == nullptr) {pT = pT->left;}}	}return pT;
}void preOrder(BTree pT) {//如果pT == nullptr,则什么也不做if (pT != nullptr) {//此处打印其值,也可以执行其他操作cout << pT->val;preOrder(pT->left);preOrder(pT->right);}
}int main() {//创建一棵平衡二叉树,将以下节点依次插入平衡二叉树vector<int> ivec = { 6, 2, 8, 1, 5, 3, 4 };BTree ptree = nullptr;for (auto i : ivec) {ptree = Insert(ptree, i);}//前序遍历遍历二叉树cout << "前序遍历二叉树:";preOrder(ptree);cout << endl;//删除一个节点,前序遍历ptree = Delete(2, ptree);cout << "删除节点2,再前序遍历:";preOrder(ptree);cout << endl;}

output:

前序遍历二叉树:6215348
删除节点2,再前序遍历:631548
请按任意键继续. . .

 

 

 

 

 

 

 

 

这篇关于二叉排序树(BST)的创建,查找,插入,删除及最大最小结点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954943

相关文章

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图

Python中高级文本模式匹配与查找技术指南

《Python中高级文本模式匹配与查找技术指南》文本处理是编程世界的永恒主题,而模式匹配则是文本处理的基石,本文将深度剖析PythonCookbook中的核心匹配技术,并结合实际工程案例展示其应用,希... 目录引言一、基础工具:字符串方法与序列匹配二、正则表达式:模式匹配的瑞士军刀2.1 re模块核心AP

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

mybatisplus的逻辑删除过程

《mybatisplus的逻辑删除过程》:本文主要介绍mybatisplus的逻辑删除过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录myBATisplus的逻辑删除1、在配置文件中添加逻辑删除的字段2、在实体类上加上@TableLogic3、业务层正常删除即

MySQL的触发器全解析(创建、查看触发器)

《MySQL的触发器全解析(创建、查看触发器)》MySQL触发器是与表关联的存储程序,当INSERT/UPDATE/DELETE事件发生时自动执行,用于维护数据一致性、日志记录和校验,优点包括自动执行... 目录触发器的概念:创建触www.chinasem.cn发器:查看触发器:查看当前数据库的所有触发器的定

C++归并排序代码实现示例代码

《C++归并排序代码实现示例代码》归并排序将待排序数组分成两个子数组,分别对这两个子数组进行排序,然后将排序好的子数组合并,得到排序后的数组,:本文主要介绍C++归并排序代码实现的相关资料,需要的... 目录1 算法核心思想2 代码实现3 算法时间复杂度1 算法核心思想归并排序是一种高效的排序方式,需要用

MybatisPlus中removeById删除数据库未变解决方案

《MybatisPlus中removeById删除数据库未变解决方案》MyBatisPlus中,removeById需实体类标注@TableId注解以识别数据库主键,若字段名不一致,应通过value属... 目录MyBATisPlus中removeBypythonId删除数据库未变removeById(Se

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录