当前位置: 首页 > news >正文

数据结构复习 (二叉查找树,高度平衡树AVL)

1.二叉查找树:

为了更好的实现动态的查找(可以插入/删除),并且不超过logn的时间下达成目的

定义: 二叉查找树(亦称二叉搜索树、二叉排序树)是一棵二叉树,其各结点关键词互异,且中根序列按其关键词递增排列。

等价描述: 二叉查找树中任一结点P,其左子树中结点的关键词都小于P的关键词,右子树中结点的关键词都大于P的关键词,且结点P的左右子树也都是二叉查找树。

节点:
BTSTreenode,有左右子树,有键值

有的操作是:

查找,插入和删除,

其他的创建和排序都可以通过上述完成

1,查找:

通过和当前的节点比较大小,来确定之后是:F.返回答案S.去更小的左边,T.去更大的右边

BSTnode* Search(BSTnode* root, int K){

if (root == NULL || root->key == K) return root;

if (K < root->key) return Search(root->left, K);

else return Search(root->right, K);

}

2,插入

根据和左右比较的方法来选择左边还是右边插入,但是不会插入相同的节点

可以引用实现,也可以是返回值实现

引用:
void insert(node*& root,int k){

If(root==NULL||root->val==k){

root=new node(k);

Return;

}
If(k>root->k)insert(root->left,k);

Else insert(root->right,k);

}

返回:
node* insert(node* root,int k){

If(root==NULL)return new node(k);

If(root->val==k)return root;

If(root->val>k)root->right=insert(root->right,k);

Else root->left=insert(root->left,k);

Return root;

}

3,删除,就是通过查找,然后判断:

,没有子树,直接删除

,有一个子树,直接上提

,两个子树,让右边最小的节点s上提到当前位置,之后删除S

void remove(BSTnode* &root, int K) {

if(root==NULL) return;

if(K<root->key) remove(root->left, K); //在左子树删K

else if(K>root->key) remove(root->right, K); //在右子树删K

else if(root->left!=NULL && root->right!=NULL){ //非根节点删除

BSTnode *s=root->right;

while(s->left!=NULL) s=s->left;

root->key=s->key; //s为t右子树中根序列第一个结点

remove(root->right, s->key);

}

else{ //根节点删除

BSTnode* oldroot=root;

root=(root->left!=NULL)? root->left:root->right;

delete oldroot;

}

}

numofBST

F[i]=f[i-1]*(4*i-2)/(i+1)

二叉查找树总结

➢则由n个互异关键词随机生成的二叉查找树,平均高度为O(logn) 

➢查找、插入、删除平均时间复杂度O(logn),但最坏情况时间复杂度为O(n)

2,高度平衡树:(AVL)

为了防止出现二叉查找树发生左/右偏的情况出现的,让一个树的左右高度相差不大于1

平衡系数:左子树高度-右子树高度

高度为h的AVL至少有

所以n>=2^(h/2),同理,h<=2logn

一颗AVL平均比完全二叉树高44%

节点AVLnode 记录的信息是键值,高度,左右子树

初始的时候每个节点的高度是0,空节点的高度为-1

具体操作:

1,计算高度

Int update_H(node* t){

If(t==NULL)return -1;

Int l=update_H(t->left);

Int r=update_H(t->right);

  1. >height=max(l,r)+1;

Return t->height;

}

Int Height(node* a){

Return a==NULL?-1”a->height;

}

2,旋转操作:

当前子树为root
左边的子树的高度为l1,右边为r1

2.1左边更高

2.1.1 左边的左边发生了插入,让左边提升

我们需要把B提升,A下降然后b右子树变成a的左子树

插入前后我们发现,高度没变

Void LL(node* & A){

Node* B=a->left;

  1. >left=B->right;
  2. >right=A;

Update_H(A);

Update_H(B);

A=B;

}

2.1.2左边的右边发生了插入,让左边的右边提升

将C的更低的子树交给B,然后让C提升,然后让C再次提升,将高的子树交给A

void LR(node* &A) {

RR(A->left);

LL(A);

}

2.2.1右边的右边发生了插入

void RR(AVLnode* &A) {

AVLnode *B = A->right;

A->right = B->left;

B->left = A;

UpdateHeight(A);

UpdateHeight(B);

A = B;

}

2.2.2右边的左边发生了插入

先让A的右子树的左子树上提,然后再让右子树上移动

void RL(AVLnode* &A){

LL(A->right);

RR(A);

注意;我们在插入节点时我们需要从下面向上去调整

比如:依次插入关键字5, 4, 2, 8, 6, 9

插入2时:

--->

插入6时:

--->

再插入一个9:

使平衡:

void ReBalance(AVLnode* &t) {

if(t==NULL) return;

if(Height(t->left) - Height(t->right)==2){      //左边更深

if(Height(t->left->left) >= Height(t->left->right)) //左边的左边更深

LL(t);

else                              //右边更深

LR(t);

}else if(Height(t->right) - Height(t->left)==2){

if(Height(t->right->right) >= Height(t->right->left))

RR(t);

else

RL(t);

}

Update_H(t);                         //更新高度

}

插入:
void Insert(AVLnode* &root, int K) {

if(root==NULL) root=new AVLnode(K);

else if(K < root->key) //在左子树插入

Insert(root->left, K);

else if(K > root->key) //在右子树插入

Insert(root->right, K);

ReBalance(root);

}

删除

和二叉树的删除差不多,需要注意的是删除之后的平衡的保持

所以代码是一样的,只是最后需要加一个使平衡

void remove(AVLnode* &root, int K) {

if(root==NULL) return;

if(K<root->key) remove(root->left, K);

//在左子树删K

else if(K>root->key) remove(root->right, K); //在右子树删K

else if(root->left!=NULL && root->right!=NULL){

AVLnode *s=root->right;

while(s->left!=NULL) s=s->left;

root->key=s->key; //s为t右子树中根序列第一个结点

remove(root->right, s->key);

}else{

AVLnode* oldroot=root;

root=(root->left!=NULL)? root->left:root->right;

delete oldroot;

}

ReBalance(root);

}

高度平衡树总结

➢AVL树的高度为O(logn),因此使插入、删除、查找的最坏时间复杂度均为O(logn)。

➢删除操作最坏情况下需要做O(logn)次旋转。

➢对任意连续多次删除操作,每次删除所需的均摊旋转次数为O(1)[1]。对于任意多次插入和删除的混合序列,存在精心构造出的特定操作序列,使每次删除所需的均摊旋转次数为O(logn)

相关文章:

数据结构复习 (二叉查找树,高度平衡树AVL)

1.二叉查找树: 为了更好的实现动态的查找(可以插入/删除),并且不超过logn的时间下达成目的 定义: 二叉查找树&#xff08;亦称二叉搜索树、二叉排序树&#xff09;是一棵二叉树&#xff0c;其各结点关键词互异&#xff0c;且中根序列按其关键词递增排列。 等价描述: 二叉查找…...

FreeSWITCH 简单图形化界面39 - Windows安装FreeSWITCH For IPPBX(WSL环境)

FreeSWITCH 简单图形化界面39 - Windows安装FreeSWITCH For IPPBX&#xff08;WSL环境&#xff09; 0、界面预览1、部署WSL1.1 安装WSL1.2 安装Windows Terminal1.3 安装WSL配置工具 2、安装Ubuntu24.043、安装FreeSWITCH4、登录Web4.1 80端口占用了 5、测试6、卸载 0、界面预览…...

uniapp - 小程序实现摄像头拍照 + 水印绘制 + 反转摄像头 + 拍之前显示时间+地点 + 图片上传到阿里云服务器

前言 uniapp&#xff0c;碰到新需求&#xff0c;反转摄像头&#xff0c;需要在打卡的时候对上传图片加上水印&#xff0c;拍照前就显示当前时间日期地点&#xff0c;拍摄后在呈现刚才拍摄的图加上水印&#xff0c;最好还需要将图片上传到阿里云。 声明 水印部分代码是借鉴的…...

Qt天气预报系统设计界面布局第四部分左边

Qt天气预报系统设计 1、第四部分左边的第一部分1.1添加控件1.2修改控件名字 2、第四部分左边的第二部分2.1添加控件2.2修改控件名字 3、第四部分左边的第三部分3.1添加控件3.2修改控件名字 4、对整个widget04l调整 1、第四部分左边的第一部分 1.1添加控件 拖入一个widget&…...

VS无法找到低版本的.net,vs2022创建不了.net6的项目

很多人会遇到安装完vs最新版(目前是2022)之后&#xff0c;创建不了旧版本的.net项目了&#xff0c;比如我在学习.net core 6&#xff0c;我的2022无法创建&#xff0c;只能创建.netcore8的项目&#xff0c;以及又安装了2019&#xff0c;同样无法创建&#xff0c;接下来介绍怎么…...

C++软件设计模式之解释器模式

解释器模式的目的和意图 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为设计模式&#xff0c;主要用于定义一种语言的文法&#xff0c;并通过该文法解释语言中的句子&#xff08;表达式&#xff09;。解释器模式的核心思想是将一个特定的语言表示为其文法规…...

小程序发版后,用户使用时,强制更新为最新版本

为什么要强制更新为最新版本&#xff1f; 在小程序的开发和运营过程中&#xff0c;强制用户更新到最新版本是一项重要的策略&#xff0c;能够有效提升用户体验并保障系统的稳定性与安全性。以下是一些主要原因&#xff1a; 1. 功能兼容 新功能或服务通常需要最新版本的支持&…...

如何使用AI工具cursor(内置ChatGPT 4o+claude-3.5)

⚠️温馨提示&#xff1a; 禁止商业用途&#xff0c;请支持正版&#xff0c;充值使用&#xff0c;尊重知识产权&#xff01; 免责声明&#xff1a; 1、本教程仅用于学习和研究使用&#xff0c;不得用于商业或非法行为。 2、请遵守Cursor的服务条款以及相关法律法规。 3、本…...

说说缓存使用的具体场景都有哪些?缓存和数据库一致性问题该如何解决?缓存使用常见问题有哪些?

面试官&#xff1a;说说缓存使用的具体场景都有哪些&#xff1f;缓存和数据库一致性问题该如何解决&#xff1f;缓存使用常见问题有哪些&#xff1f; 缓存的具体使用场景有这些&#xff1a; 数据频繁读取&#xff1a; 当某些数据频繁被读取而不常变化时&#xff0c;可以将这些…...

2025-01-01 NO2. XRHands 介绍

文章目录 软件配置1 XR Hands 简介2 XRHand2.1 Pose2.2 Handedness 3 XRHandJoint3.1 XRHandJointID3.2 XRHandJointTrackingState 4 XRHandSubsystem4.1 数据属性4.1.1 UpdateSuccessFlags4.1.2 UpdateType 4.2 处理器管理&#xff1a;注册和注销4.3 更新手部数据&#xff1a;…...

Java开发-后端请求成功,前端显示失败

文章目录 报错解决方案1. 后端未配置跨域支持2. 后端响应的 Content-Type 或 CORS 配置问题3. 前端 request 配置问题4. 浏览器缓存或代理问题5. 后端端口未被正确映射 报错 如下图&#xff0c;后端显示请求成功&#xff0c;前端显示失败 解决方案 1. 后端未配置跨域支持 …...

未来20年在大语言模型相关研究方向--大语言模型的优化与改进

未来20年在大语言模型相关研究方向 模型性能优化 模型架构创新:研究新型的模型架构,如探索更高效的Transformer变体、融合递归神经网络(RNN)和卷积神经网络(CNN)的优点,以提高模型的性能、可扩展性和适应性,满足不同应用场景对模型效率和效果的要求。高效训练算法:开…...

[react] 纯组件优化子

有组件如下,上面变化秒数, 下面是大量计算的子组件,上面每一秒钟变化一次,这时候子组件会不断重新渲染, 浪费资源 父组件如下 import React, { memo, useEffect, useMemo, useState } from react; import type { ReactNode, FC } from react; import HugeCount from ./Te; int…...

美观强大的文件保险库Chibisafe

简介 什么是 Chibisafe &#xff1f; Chibisafe 是一款用 Typescript 编写的快速文件上传服务&#xff0c;非常实用。它接受文件、照片、文档以及您能想到的任何内容&#xff0c;并返回可共享的链接&#xff0c;供您发送给其他人。它易于使用、易于部署、免费且开源&#xff0…...

详细教程:SQL2008数据库备份与还原全流程!

数据的安全性至关重要&#xff0c;无论是操作系统、重要文件、磁盘存储&#xff0c;还是企业数据库&#xff0c;备份都是保障其安全和完整性的关键手段。拥有备份意味着即使发生误删、系统崩溃或病毒攻击等问题&#xff0c;也能迅速通过恢复功能解决&#xff0c;避免数据丢失带…...

HTML——49.header和footer标签

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>header和footer标签</title></head><body><!--header和footer标签:是html5中新标签--><!--header:定义文档的页眉&#xff0c;通常用来定义可见…...

【蓝桥杯选拔赛真题87】python输出字符串 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python输出字符串 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python输出字符串 第十五届蓝桥杯青少年组python比赛选拔赛真题详细解析…...

OpenStack-Dashboard界面简单修改

OpenStack Dashboard界面替换图片 一、dashboard界面Logo的路径及文件 dashboard的Logo存放&#xff08;在Controller节点&#xff09;的路径&#xff1a; /usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/涉及需要修改的文件&#xff08;3个&…...

DevOps工程技术价值流:Ansible自动化与Semaphore集成

在DevOps的浪潮中&#xff0c;自动化运维工具扮演着举足轻重的角色。Ansible&#xff0c;作为一款新兴的自动化运维工具&#xff0c;凭借其强大的功能和灵活性&#xff0c;在运维领域迅速崭露头角。本文将深入探讨Ansible的特点、架构、工作原理&#xff0c;以及其应用场景&…...

【服务器】上传文件到服务器并训练深度学习模型下载服务器文件到本地

前言&#xff1a;本文教程为&#xff0c;上传文件到服务器并训练深度学习模型&#xff0c;与下载服务器文件到本地。演示指令输入&#xff0c;完整的上传文件到服务器&#xff0c;并训练模型过程&#xff1b;并演示完整的下载服务器文件到本地的过程。 本文使用的服务器为云服…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...