二叉排序树(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

相关文章

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

docker如何删除悬空镜像

《docker如何删除悬空镜像》文章介绍了如何使用Docker命令删除悬空镜像,以提高服务器空间利用率,通过使用dockerimage命令结合filter和awk工具,可以过滤出没有Tag的镜像,并将... 目录docChina编程ker删除悬空镜像前言悬空镜像docker官方提供的方式自定义方式总结docker

Python创建Excel的4种方式小结

《Python创建Excel的4种方式小结》这篇文章主要为大家详细介绍了Python中创建Excel的4种常见方式,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以学习一下... 目录库的安装代码1——pandas代码2——openpyxl代码3——xlsxwriterwww.cppcns.c

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

使用Python在Excel中创建和取消数据分组

《使用Python在Excel中创建和取消数据分组》Excel中的分组是一种通过添加层级结构将相邻行或列组织在一起的功能,当分组完成后,用户可以通过折叠或展开数据组来简化数据视图,这篇博客将介绍如何使... 目录引言使用工具python在Excel中创建行和列分组Python在Excel中创建嵌套分组Pyt

使用Python在Excel中插入、修改、提取和删除超链接

《使用Python在Excel中插入、修改、提取和删除超链接》超链接是Excel中的常用功能,通过点击超链接可以快速跳转到外部网站、本地文件或工作表中的特定单元格,有效提升数据访问的效率和用户体验,这... 目录引言使用工具python在Excel中插入超链接Python修改Excel中的超链接Python

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

C#实现添加/替换/提取或删除Excel中的图片

《C#实现添加/替换/提取或删除Excel中的图片》在Excel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更加美观,下面我们来看看如何在C#中实现添加/替换/提取或删除E... 在Excandroidel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更