二叉排序树(BST)的算法分析以及基本操作(结点的查询,插入,删除)

1.二叉排序树的定义

二叉排序树,又称二叉查找树(BST,Binary Search Tree)
默认不允许两个结点的关键字相同。

1.二叉排序树的性质:

任意一棵二叉排序树的子树的结点大小都满足“左小右大”。

  • 左子树上所有结点的关键字均小于根结点的关键字。
  • 右子树上所有结点的关键字均大于根结点的关键字。
  • 左子树和右子树又各是一棵二叉排序树。

例如下面这棵二叉排序树:
在这里插入图片描述

2.二叉排序树的特点:

  1. 左子树结点值<根结点值<右子树结点值。
  2. 进行中序遍历,可以得到一个递增的有序序列。
  3. 二叉排序树可用于元素的有序组织、搜索。

2.查找操作

从根节点开始,目标值更小往左找,目标值更大往右找。
在这里插入图片描述

根据二叉排序树的特点:左子树结点值<根结点值<右子树结点值

1.查找步骤:

  1. 若树非空,目标值与根结点的值比较:
  2. 若相等,则查找成功;
  3. 若小于根结点,则在左子树上查找,否则在右子树上查找。
  4. 查找成功,返回结点指针;
  5. 查找失败返回NULL.

2.代码实现

1.二叉排序树结点设计:

//二叉排序树结点
typedef struct BSTNode {int key;struct BSTNode *lchild, *rchild;
} BSTNode, *BSTree;

2.查找函数设计:
非递归的实现:
最坏空间复杂度为O(1)

//在二叉排序树中查找值为key 的结点
BSTNode *BST_Search(BSTree T,int key){while(T!=NULL&&key !=T->key) {//若树空或等于根结点值,则结束循环if( key<T->key) T=T->lchild;//小于,则在左子树上查找else T=T->rchild;//大于,则在右子树上查找}return T;
}

递归实现:
最坏空间复杂度为O(h)

//在二叉排序树中查找值为key 的结点(递归实现)
BSTNode *BSTSearch(BSTree T, int key) {if (T == NULL)return NULL;//查找失败if (key == T->key)return T;//查找成功else if (key < T->key)return BSTSearch(T->lchild, key);//在左子树中找elsereturn BSTSearch(T->rchild, key);//在右子树中找
}

3.插入操作

找到应该插入的位置(一定是叶子结点),一定要注意修改其父节点指针。

1.实现步骤:

  1. 若原二叉排序树为空,则直接插入结点;
  2. 否则,若关键字k小于根结点值,则插入到左子树,
  3. 若关键字k大于根结点值,则插入到右子树

2.代码实现(递归插入)

最坏空间复杂度为O(h)

//在二叉排序树插入关键字为k的新结点(递归实现)
int BST_Insert(BSTree &T, int k) {if (T == NULL) {//原树为空,新插入的结点为根结点T = (BSTree) malloc(sizeof(BSTNode));T->key = k;T->lchild = T->rchild = NULL;return 1;//返回1,插入成功} else if (k == T->key)//树中存在相同关键字的结点,插入失败return 0;else if (k < T->key)//插入到T的左子树return BST_Insert(T->lchild, k);else//插入到T的右子树return BST_Insert(T->rchild, k);
}

3.通过插入操作构造一棵二叉排序树

//按照str[] 中的关键字序列建立二叉排序树
void Creat_BST(BSTree &T, int str[], int n) {T = NULL;//初始时T为空树int i = 0;while (i < n) {//依次将每个关键字插入到二叉排序树中BST_Insert(T, str[i]);i++;}
}

给定不同的关键字序列可能得到同款二叉排序树,也可能得到不同款二叉排序树。

4.删除操作

1.实现步骤:

  1. 先搜索找到目标结点

  2. 若被删除结点z是叶结点,则直接删除,不会破坏二叉排序树的性质。

  3. 若结点z只有一棵左子树或右子树,则让z的子树成为z父结点的子树,替代z的位置。

  4. 若结点z有左、右两棵子树,则令z的直接后继(或直接前驱)替代z,然后从二叉排序树中删去这个直接后继(或直接前驱),这样就转换成了第一或第二种情况。(采用的是中序遍历)

  5. z的直接后继:z的右子树中最左下结点(该节点一定没有左子树)
    在这里插入图片描述

  6. z的直接前驱:z的左子树中最右下结点(该节点一定没有右子树)
    在这里插入图片描述

5.查找效率分析

查找长度――在查找运算中,需要对比关键字的次数称为查找长度,反映了查找操作时间复杂度。

评估指标:
查找成功的平均查找长度ASL (Average Search Length)

1.查找成功的情况

  • 若是树高为H,找到最小层的一个结点需要对比H次。
  • 最好情况:n个结点的二叉树最小高度为 [ l o g 2 n ] + 1 [log_2n]+1 [log2n]+1
  • 平均查找长度=O( l o g 2 n log_2n log2n)
  • 最坏情况: 每个结点只有一个分支,树高h=结点数n,平均查找长度=O(n)。

2.查找失败的情况

需要补充失败结点的情况。

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

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

相关文章

基于Python和mysql开发的智慧校园答题考试系统(源码+数据库+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python和mysql开发的智慧校园答题考试系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都…

二分算法(超详细)

快速排序 题目1-整数二分-数的范围 给定一个按照升序排列的长度为 n 的整数数组&#xff0c;以及 q 个查询。 对于每个查询&#xff0c;返回一个元素 k 的起始位置和终止位置&#xff08;位置从 0 开始计数&#xff09;。 如果数组中不存在该元素&#xff0c;则返回 -1 -1。…

【动手学深度学习】--长短期记忆网络LSTM

文章目录 长短期记忆网络LSTM1.门控记忆元1.1输入门、忘记门、输出门1.2候选记忆元1.3记忆元1.4隐状态 2.从零实现2.1加载数据集2.2初始化模型参数2.3定义模型2.4 训练与预测 3.简洁实现 长短期记忆网络LSTM 学习视频&#xff1a;长短期记忆网络&#xff08;LSTM&#xff09;【…

redis 常用数据结构2

目录 list LPUSH LRANGE LPUSHX RPUSH RPUSHX LPOP RPOP LINDEX LINSERT LLEN LREM LTRIM LSET BLPOP / BRPOP 编码方式 set SADD SMEMBERS SISMEMBER SPOP SCARD SRANDMEMBER SMOVE SREM SINTER SINTERSTORE SUNION SUNIONSTORE SDIFF SDIFFSTO…

leetcode面试题:交换和(三种方法实现)

交换和&#xff1a; 给定两个整数数组&#xff0c;请交换一对数值&#xff08;每个数组中取一个数值&#xff09;&#xff0c;使得两个数组所有元素的和相等。 返回一个数组&#xff0c;第一个元素是第一个数组中要交换的元素&#xff0c;第二个元素是第二个数组中要交换的元…

白鲸开源 X SelectDB 金融大数据联合解决方案公布!从源头解决大数据开发挑战

业务挑战与痛点 随着互联网技术的发展、云计算技术的成熟、人工智能技术的兴起和数字化经济的崛起&#xff0c;数据已成为企业的核心资产。在金融行业中&#xff0c;数字化已成为了支撑各类业务场景的核心力量&#xff0c;包括个人理财、企业融资、股票交易、保险理赔、贷款服…

如何构建一个简单的前端框架

先让我来解释一下什么是前端框架。所谓的前端框架&#xff0c;就是一种能够让我们避免去写常规的HTML和JavaScript代码 <p id"cool-para"></p> <script>const coolPara Test;const el document.getElementById(cool-para);el.innerText coolPa…

TensorFlow 02(张量)

一、张量 张量Tensor 张量是一个多维数组。与NumPy ndarray对象类似&#xff0c;tf.Tensor对象也具有数据类型和形状。如下图所示: 此外&#xff0c;tf.Tensors可以保留在GPU中。TensorFlow提供了丰富的操作库 (tf.add&#xff0c;tf.matmul,tf.linalg.inv等)&#xff0c;它们…

文字点选验证码识别(下)-训练一个孪生神经网络模型

声明 本文以教学为基准、本文提供的可操作性不得用于任何商业用途和违法违规场景。 本人对任何原因在使用本人中提供的代码和策略时可能对用户自己或他人造成的任何形式的损失和伤害不承担责任。 如有侵权,请联系我进行删除。 文章中没有代码,只有过程思路,请大家谨慎订阅。…

HarmonyOS Codelab 优秀样例——溪村小镇(ArkTS)

一、介绍 溪村小镇是一款展示溪流背坡村园区风貌的应用&#xff0c;包括园区内的导航功能&#xff0c;小火车行车状态查看&#xff0c;以及各区域的风景展览介绍&#xff0c;主要用于展示HarmonyOS的ArkUI能力和动画效果。具体包括如下功能&#xff1a; 打开应用时进入启动页&a…

哪种IP更适合你的数据抓取需求?

程序员大佬们好&#xff01;今天我要和大家分享一个关于数据抓取的话题&#xff0c;那就是Socks5爬虫ip和动态IP之间的比较。在进行数据抓取时&#xff0c;选择适合自己需求的工具和技术是非常重要的。Socks5爬虫ip和动态IP都是常见的网络工具&#xff0c;它们在数据抓取方面都…

Spring Boot 中的参数验证和自定义响应处理,使用 @Valid 注解

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; Spring Boot 中的参数验证和自定义响应处理&#xff0c;使用 Valid 注解…

【sgCreateAPI】自定义小工具:敏捷开发→自动化生成API接口脚本(接口代码生成工具)

<template><div :class"$options.name"><div class"sg-head">接口代码生成工具</div><div class"sg-container"><div class"sg-start "><div style"margin-bottom: 10px;">接口地…

如何进行函数的递归调用?

函数的递归调用是一种强大而常见的编程技巧&#xff0c;它允许函数在自身内部调用自己。递归在解决问题的分而治之策略中非常有用&#xff0c;可以将大问题分解为更小的、相同或类似的子问题&#xff0c;然后通过逐步解决这些子问题来解决原始问题。在本文中&#xff0c;我将详…

信息化发展39

IT 服务管理 1 、IT 服务管理是通过主动管理和流程的持续改进来确保IT 服务交付有效且高效的一组活动。 2 、IT 服务管理由若干不同的活动组成&#xff1a; 服务台、事件管理、问题管理、变更管理、配置管理、发布管理、服务级别管理、财务管理、容量管理、服务连续性管理和可…

做期权卖方一般会怎么选择合约?

我们知道期权有多种获利方式&#xff0c;其中靠时间能赚钱的是做期权卖方策略&#xff0c;虽然赚得慢&#xff0c;但可以稳稳地收入权利金&#xff0c;适合某些稳健风格的投资者&#xff0c;胜率对比买方也是高了很多&#xff0c;那么做期权卖方一般会怎么选择合约&#xff1f;…

Unity——JSON的读取

一、读取JSON 在实际中&#xff0c;读取JSON比保存JSON重要得多。因为存档、发送数据包往往可以采用其他序列化方法&#xff0c;但游戏的配置文件使用JSON格式比较常见。游戏的配置数据不属于动态数据&#xff0c;属于游戏资源&#xff0c;但很适合用JSON表示。 下面以一个简…

Mybatis---第二篇

系列文章目录 文章目录 系列文章目录一、#{}和${}的区别是什么?二、简述 Mybatis 的插件运行原理,如何编写一个插件一、#{}和${}的区别是什么? #{}是预编译处理、是占位符, KaTeX parse error: Expected EOF, got # at position 27: …接符。 Mybatis 在处理#̲{}时,会将…

Linux之Socket函数(详细篇)

本篇是基于Linux man手册的一些总结 socket作用&#xff1a; create an endpoint for communication 函数结构 c #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol); 描述 socket() …

LeetCode(力扣)45. 跳跃游戏 IIPython

LeetCode45. 跳跃游戏 II 题目链接代码 题目链接 https://leetcode.cn/problems/jump-game-ii/description/ 代码 class Solution:def jump(self, nums: List[int]) -> int:if len(nums) 1:return 0curdis 0nextdis 0step 0for i in range(len(nums)):nextdis max(…