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

news2024/11/22 22:30:59

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);//在左子树中找
    else
        return 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.coloradmin.cn/o/1006182.html

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

相关文章

廉价的全闪存雷电 NAS 折腾笔记:NUC9 操作系统踩坑

上一篇文章中&#xff0c;分享了关于低成本全闪存 NAS 的个人方案选择。 本篇文章&#xff0c;来聊聊硬件相关部分&#xff0c;以及软件的基础配置部分&#xff0c;也聊聊雷电组网的踩坑之旅。 写在前面 我使用的设备是 NUC9i5QNX&#xff0c;这台设备的硬件基础规格&#x…

【软件测试】selenium3

自动化测试的概念 自动化测试指软件测试的自动化&#xff0c;在预设状态下运行应用程序或者系统&#xff0c;预设条件包括正常和异常&#xff0c;最 后评估运行结果。将人为驱动的测试行为转化为机器执行的过程。 自动化测试就相当于将人工测试手段进行转换&#xff0c;让代码…

国产视觉检测设备崛起,以AI机器视觉及自研算法破解智造难题

机器视觉作为人工智能的前沿分支之一&#xff0c;被称为智能制造的“智慧之眼”&#xff0c;在工业领域中&#xff0c;能够代替人工完成识别、测量、定位、检测等工作&#xff0c;以实现对设备精密控制及产线智能化、自动化升级。 同时&#xff0c;深度学习和3D视觉的技术升级…

Java本地开发环境搭建

概述 Java语言是企业级应用软件开发语言&#xff0c;本文主要描述Java开发环境的搭建。 如上所示&#xff0c;TIOBE提供2023年9月份全球开发语言的排行榜&#xff0c;其中&#xff0c;Java排名第四&#xff0c;而Python已经跃升到第一位&#xff0c;因为&#xff0c;Python是人…

芯科蓝牙BG27开发笔记6-精简第一个程序

1. 这些IO的控制代码在哪里&#xff1f; 还是蓝牙点灯程序&#xff1a; 首先需要对pinout做一些精简&#xff1a; 为了简化工程&#xff0c;去掉了不必要的IO。 至于PTI接口是什么&#xff0c;怎么用&#xff0c;不知道&#xff0c;现在不考虑&#xff1a; 但是提出以下问题…

第6章_freeRTOS入门与工程实践之创建FreeRTOS工程

本教程基于韦东山百问网出的 DShanMCU-F103开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id724601559592 配套资料获取&#xff1a;https://rtos.100ask.net/zh/freeRTOS/DShanMCU-F103 freeRTOS系列教程之freeRTOS入…

应该下那个 ActiveMQ

最近在搞 ActiveMQ 的时候&#xff0c;发现有 2 个 ActiveMQ 可以下载。 应该下那个呢&#xff1f; JMS 即Java Message Service&#xff0c;是JavaEE的消息服务接口。 JMS主要有两个版本&#xff1a;1.1和2.0。 2.0和1.1相比&#xff0c;主要是简化了收发消息的代码。 所谓…

Redis——其他数据类型介绍

概要介绍 Redis中有10种不同的数据类型。之前的blog中介绍了Redis中常见的五大数据类型&#xff1a;String&#xff0c;List&#xff0c;Hash&#xff0c;Set&#xff0c;ZSet。而Redis中还有许多其他的数据类型&#xff0c;一般在特定的场景中使用 Stream 首先介绍一下什么…

笔记本多拓展出一个屏幕

一、首先要知道&#xff0c;自己的电脑有没有Type-c接口&#xff0c;支持不支持VGA 推荐&#xff1a; 自己不清楚&#xff0c;问客服&#xff0c;勤问。 二、显示屏与笔记本相连&#xff0c;通过VGA 三、连接好了&#xff0c;需要去配置 网址&#xff1a;凑合着看&#xff…

代码随想录算法训练营Day42 | 动态规划(4/17) 0-1背包问题理论基础 LeetCode 416.分割等和子集

开始背包问题的练习&#xff01; 1. 背包问题的理论基础 对于面试的话&#xff0c;其实掌握01背包&#xff0c;和完全背包&#xff0c;就够用了&#xff0c;最多可以再来一个多重背包。这里附上代码随想录的图&#xff0c;可以对背包问题进行一个分类。 1.1 十分重要的基础&a…

Java class 文件安全加密工具对比与ClassFinal实战

文章目录 前言常见加密方案对比XJarProGuardClassFinal ClassFinal实战纯命令方式maven插件方式 写在最后 前言 相信不少的同学开发的软件都是用户商业化&#xff0c;对于这些商业运营的项目很多都会直接部署在客户方&#xff0c;这样就可能会导致项目源码泄露。当然&#xff…

每日一题~中序后序遍历构造二叉树

题目描述&#xff1a; 思路分析&#xff1a; 后序遍历分析图 中序遍历分析图 不难看出后序遍历的结果中的最后一个元素就是根节点&#xff0c;倒数第二个元素则是根节点的右子树的根节点&#xff0c;而倒数第三个元素是右子树的新右子树的根节点&#xff0c;依次类推。我们可…

部署ik分词器

部署ik分词器 案例版本&#xff1a;elasticsearch-analysis-ik-8.6.2 ​ ES默认自带的分词器对中文处理不够友好&#xff0c;创建倒排索引时可能达不到我们想要的结果&#xff0c;然而IK分词器能够很好的支持中文分词 ​ 因为是集群部署&#xff0c;所以每台服务器中的ES都需…

springboot redisTemplate.opsForValue().setIfAbsent返回null原理

一、版本 springboot版本&#xff1a;spring-boot-starter-data-redis 2.1.6 redisson版本&#xff1a;redisson-spring-boot-starter 3.11.5 二、场景 Boolean res redisTemplate.opsForValue().setIfAbsent("key","value");以上代码同一时间多次执行…

【校招VIP】常用产品分析之数值分析能力

考点介绍&#xff1a; 产品的生命周期各个阶段都伴随着产品数据的变化&#xff0c;产品经理根据这些数据来判断产品所在阶段并对后期的产品演进进行合理的规划&#xff1b;在产品需求分析阶段&#xff0c;通过数据分析来鉴别用户需求的真伪&#xff1b;在产品上线后&#xff0c…

向量范数及其Python代码

【向量范数】 向量由于既有大小又有方向&#xff0c;所以不能直接比较大小。 向量范数通过将向量转化为实数&#xff0c;然后进行向量的大小比较。 所以&#xff0c;向量范数是用于度量“向量大小”的量。 设向量 &#xff0c;则有&#xff1a; ● 向量的 范数&#xff1a; ●…

IO和进程day06(线程续、同步线程互斥)

今日任务&#xff1a; 1.代码 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <pthread.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <u…

10分钟带你深入理解JavaScript的执行上下文和闭包机制

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4da; 前言 &#x1f4d8; 一. JavaScript中的闭包 &#x1f4d8; 二. 执行上下文与闭包 &#x1f4d…

03-Redis主从架构

上一篇&#xff1a;02-Redis持久化 1.主从架构搭建 配置从节点步骤&#xff1a; 1、复制一份redis.conf文件 2、将相关配置修改为如下值&#xff1a; port 6380 pidfile /var/run/redis_6380.pid # 把pid进程号写入pidfile配置的文件 logfile "6380.log" dir …

使用亚马逊云科技Amazon SageMaker,为营销活动制作广告素材

广告公司可以使用生成式人工智能和文字转图像根基模型&#xff0c;制作创新的广告素材和内容。在本篇文案中&#xff0c;将演示如何使用亚马逊云科技Amazon SageMaker从现有的基本图像生成新图像&#xff0c;这是一项完全托管式服务&#xff0c;用于大规模构建、训练和部署机器…