数据结构—动态查找

动态查找介绍

1. 动态查找的引入:当查找表以线性表的形式组织时,若对查找表进行插入、删除或排序操作,就必须移动大量的记录,当记录数很多时,这种移动的代价很大。

2. 动态查找表的设计思想:表结构本身是在查找过程中动态生成的

若表中存在其关键字等于给定值key的记录,表明查找成功;否则插入关键字等于key的记录。

利用树的形式组织查找表,可以对查找表进行动态高效的查找。

二叉排序树

1. 动态查找表的典型数据结构是二叉排序树,又称二叉查找树,其中序遍历输出为有序序列

    二叉排序树是空树或者是具有如下特性的二叉树:

若它的左子树不空,则左子树上所有结点的值均小于根结点的值

若它的右子树不空,则右子树上所有结点的值均大于根结点的值

它的左、右子树也都分别是二叉排序树。

2. 二叉排序树的查找

给定值与根结点比较:

①.若相等,查找成功

②.若小于,查找左子树

③.若大于,查找右子树

                实现代码

BSTNode *BST_Serach(BSTNode *T , KeyType key)
{  if (T==NULL)  return(NULL) ;else {  if  (EQ(T->key, key) ) return(T) ;else if ( LT(key, T->key) )return(BST_Serach(T->Lchild, key)) ;else  return(BST_Serach(T->Rchild, key)) ;}
}

3. 二叉排序树的插入

二叉排序树是一种动态树表

当树中不存在查找的结点时,作插入操作

新插入的结点一定是叶子结点,只需改动一个结点的指针

该叶子结点是查找不成功时路径上访问的最后一个结点左孩子或右孩子(新结点值小于或大于该结点值)

实现代码

void  Insert_BST (BSTNode *T , KeyType  key)
{ BSTNode *x ;x=(BSTNode *)malloc(sizeof(BSTNode)) ;x->key=key; x->Lchild=x->Rchild=NULL ; if (T==NULL)  T=x ;else{  if (EQ(T->key, x->key) )     return  ;/*  已有结点  */else if (LT(x->key, T->key) )Insert_BST(T->Lchild, key) ;else   Insert_BST(T->Rchild, key) ;   }
}

4. 性能分析

        在最好的情况下,二叉排序树为一近似完全二叉树时,其查找深度为log2n量级,即其时间复杂性为O(log2n)

        在最坏的情况下,二叉排序树为近似线性表时(如以升序或降序输入结点时),其查找深度为n量级,即其时间复杂性为O(n)

5. 其他

        一个无序序列可以通过构造一棵二叉排序树而变成一个有序序列(通过中序遍历)

        插入新记录时,只需改变一个结点的指针,相当于在有序序列中插入一个记录而不需要移动其它记录

        二叉排序树既拥有类似于折半查找的特性O(log2n),又采用了链表作存储结构

        当插入记录的次序不当时(如升序或降序),则二叉排序树深度很深O(n),增加了查找的时间

6. 实现代码 

#include<iostream>using namespace std;class node {
public:int data;node *left, *right;node(int value) {data = value;left = right = nullptr;}
};class bitree {
private:bool flag = false;int l;node *root;
public:bitree() {cin >> l;root = nullptr;for (int i = 0; i < l; i++) {int tmp;cin >> tmp;root = insert(root, tmp);}pre_order(root);cout << endl;}//二叉树的创建和插入node *insert(node *q, int t) {if (q == nullptr) {q = new node(t);return q;}if (q->data <= t)q->right = insert(q->right, t);elseq->left = insert(q->left, t);return q;}//独立插入void insert_More() {int t;cin >> t;while (t--) {int tmp;cin >> tmp;insert(root, tmp);pre_order(root);cout << endl;}}//二叉排序树之查找void search_start() {int t;cin >> t;while (t--) {flag = false;int tmp;cin >> tmp;int num = 0;search(root, tmp, num);if (flag)cout << num << endl;elsecout << -1 << endl;}}void search(node *p, int tmp, int &num) {if (p == nullptr)return;num++;if (p->data == tmp) {flag = true;return;}if (tmp > p->data)search(p->right, tmp, num);elsesearch(p->left, tmp, num);}//先序遍历void pre_order(node *p) {if (p == nullptr)return;pre_order(p->left);cout << p->data << " ";pre_order(p->right);}};

平衡二叉树

1. 为解决而擦汗排序树的插入记录次序不当问题, 我们引入了二叉排序(查找)树的另一种形式—平衡二叉树,又被称为AVL树,其特点在于树中每个结点的左右子树深度之差的绝对值不大于1 

2. 平衡因子

每个结点附加一个数字, 给出该结点左子树的高度减去右子树的高度所得的高度差,这个数字即为结点的平衡因子balance

AVL树任一结点平衡因子只能取 -1, 0, 1

3. 平衡化旋转,又称为平衡化处理,如果在一棵平衡的二叉查找树中插入一个新结点或者删除一个旧结点,造成了不平衡,此时必须调整树的结构,使之平衡化

    平衡化旋转的操作:

每插入一个新结点时, AVL树中相关结点的平衡状态会发生改变

在插入一个新结点后,需要从插入位置沿通向根的路径回溯,检查各结点的平衡因子

如果在某一结点发现高度不平衡,停止回溯。

从发生不平衡的结点起,沿刚才回溯的路径取下两层的结点。对这三个结点进行平衡化处理

    平衡化旋转有四种:

单向右旋,LL型,LL是指不平衡的三结点是双亲-左孩子-左孩子

单向左旋,RR型,RR是指不平衡的三结点是双亲-右孩子-右孩子

先左后右双向旋转,LR型,LR是指不平衡的三结点是双亲-左孩子-右孩子

先右后左双向旋转,RL型,RL是指不平衡的三结点是双亲-右孩子-左孩子

注意:英文类型简称是指不平衡状态,不是指旋转方向

注意:中文旋转名称是指旋转方向

B树 

B树是一种多路平衡查找树,应用内存和磁盘间的查找

B树又分B-树、B+树,一般把B-树称为B树

B-树

1. m阶B-树规定:

                ⑴ 根结点或者是叶子,或者至少有两棵子树,至多有m棵子树;

                ⑵ 除根结点外,所有非终端结点至少有ém/2ù棵子树,至多有m棵子树

                ⑶ 所有叶子结点都在树的同一层上;        

                ⑷ 每个结点应包含如下信息:

               (n,A0,K1,A1,K2,A2,… ,Kn,An)

  n是n个关键字,A是孩子指针,K是关键字

                 (5) Ki<Ki+1 且Ai所指向的子树中所有结点的关键字都在Ki和Ki+1之间

2. B-树的特点

m阶B-树即m叉树,m是树的度

m是指树结点最多包含m个孩子指针

每个树结点中,关键字的数量比孩子指针数量少1

根结点可以有2到m个孩子指针

叶子结点的关键字数量不受限制,孩子指针都是空指针,数量无意义

中间结点包含ém/2ù到m个孩子指针,即包含ém/2ù-1到m-1个关键字

B+树 

1. 基本概念

在实际的文件系统中,基本上不使用B-树,而是使用B-树的一种变体,称为m阶B+树。

B+树与B-树的主要不同是叶子结点中存储记录。

在B+树中,所有的非叶子结点可以看成是索引,而其中的关键字是作为“分界关键字”,用来界定某一关键字的记录所在的子树。

即B+树中,所有结果信息都在叶子,查找结束必定在叶子

2. B+树的特点

与B-树相比,对B+树不仅可以从根结点开始按关键字随机查找,而且可以从最小关键字起,按叶子结点的链接顺序进行顺序查找。

在B+树上进行随机查找、插入、删除的过程基本上和B-树类似。

在B+树上进行随机查找时,若非叶子结点的关键字等于给定的K值,并不终止,而是继续向下直到叶子结点(只有叶子结点才存储记录), 即无论查找成功与否,都走了一条从根结点到叶子结点的路径。

平衡二叉树AVL-Tree的改进——红黑树RB-Tree

红黑树是一种不那么严格的平衡二叉树

它允许不平衡达到一倍,即左右子树高度差可以达到一倍

RBT是用非严格的平衡来换取增删结点时候旋转次数的降低,任何不平衡都会在三次旋转之内解决

AVL是严格平衡树,因此在增加或者删除结点的时候,根据不同情况,旋转的次数比红黑树要多。所以红黑树的插入效率更高!!

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

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

相关文章

Midjourney新功能介绍:风格参考(Style References)详解

引言 对于追求创意和一致性的艺术家和设计师们来说&#xff0c;Midjourney的最新功能——风格参考&#xff08;Style References&#xff09;&#xff0c;无疑是一个激动人心的消息。这项测试算法的发布&#xff0c;让我们得以通过简单的URL引用&#xff0c;将特定的风格应用于…

专项审计或鉴证报告

经具有资质并符合《工作指引》相关条件的中介机构出具的企业近三个会计年度&#xff08;实际年限不足三年的按实际经营年限&#xff09;研究开发费用专项审计或鉴证报告&#xff08;附研究开发活动说明材料&#xff09;、近一个会计年度高新技术产品&#xff08;服务&#xff0…

【论文速览_01】Awesome Few Shot Segmentation论文

Awesome Few Shot Segmentation Awesome Few Shot Segmentation论文CVPR 2023Hierarchical Dense Correlation Distillation for Few-Shot Segmentation文章内容 MIANet: Aggregating Unbiased Instance and General Information for Few-Shot Semantic Segmentation文章内容 I…

探讨深浅拷贝在js加密中的运用

深浅拷贝是JavaScript中常用的概念&#xff0c;用于复制对象或数组。它们在处理数据时有不同的用途&#xff0c;适用于不同的场景。在本文中&#xff0c;我们将详细介绍深浅拷贝的概念&#xff0c;提供案例代码&#xff0c;并探讨它们在JavaScript中的应用场景&#xff0c;以及…

linux如何知道运行的进程的运行目录,就可以了解自己的程序是否在运行。

目 录 一、背景 二、找到运行的进程的运行目录的方法 1、使用ps命令结合grep命令 2. 使用pgrep命令结合readlink命令 一、背景 在实际应用中&#xff0c;发现Linux中运行了多个nginx&#xff0c;不知道自己的应用程序的Nginx是否在正常运行&#xff1f; 如果知道这…

学习python第五天

一.判断语句 yourAge 20 myAge 18if yourAge > myAge:print("你的年龄比我大")""" 输出 你的年龄比我大 """ 1.冒号 判断语句的固定格式&#xff0c;用来表示这行判断条件的结束。 2.四个空格&#xff08;缩进&#xff09; …

MySQL原理(一)架构组成之逻辑模块(1)组成

总的来说&#xff0c;MySQL可以看成是二层架构&#xff0c;第一层我们通常叫做SQL Layer&#xff0c;在MySQL数据库系统处理底层数据之前的所有工作都是在这一层完成的&#xff0c;包括权限判断&#xff0c;sql解析&#xff0c;执行计划优化&#xff0c;query cache的处理等等&…

中二少年工具箱(PC端)简介

同学们可以私信我加入学习群&#xff01; 正文开始 简介一、功能模块1.node版本管理工具 总结 简介 中二少年开发的中二少年工具箱&#xff0c;相信博主&#xff0c;功能不孬。 辅助自己开发工作&#xff0c;帮助新人快速入门&#xff0c;提供交互式文档辅助学习……如果还不…

CSS3:最新特性和实例教程

今天简单复习一下css3的相关特性吧。 一&#xff1a;响应式设计 CSS3引入了媒体查询&#xff08;Media Queries&#xff09;和弹性盒子布局&#xff08;Flexbox&#xff09;等特性&#xff0c;使得响应式设计变得更加容易。媒体查询可以根据设备的屏幕大小、分辨率等属性来应…

拓展欧几里得法求逆元

板子&#xff1a; x即为最终答案&#xff0c;x可能为负数&#xff0c;加模数即可 乘法逆元 - OI Wiki (oi-wiki.org) void exgcd(int a, int b, int& x, int& y) {if (b 0) {x 1, y 0;return;}exgcd(b, a % b, y, x);y - a / b * x; } 使用: exgcd(a, n 1, x,…

什么是ISO21434网络安全中的汽车网络?-亚远景

在ISO 21434标准中&#xff0c;汽车网络指的是车辆内部和车辆与外部之间的所有电子控制单元&#xff08;ECU&#xff09;之间的连接和通信。这些电子控制单元包括车辆内部的各种系统和功能&#xff0c;例如引擎控制、刹车系统、驾驶辅助系统、娱乐系统等。 具体来说&#xff0c…

空间计算时代加速到来,需要的不只是苹果

近年来&#xff0c;科技行业一直在期待“寒武纪”时刻。伴随技术革命的深入推进&#xff0c;所有厂商都预感新的时代即将到来&#xff0c;并期待自己成为那个引爆点&#xff0c;轻轻一触&#xff0c;推开一扇新的未来之门。 今年开年&#xff0c;苹果就为科技圈锚定了一个可能…

学习C语言的第31天

全局函数和静态函数 全局函数 1、全局函数在作用域中唯一的&#xff1b; 2、作用域&#xff1a;在整个项目中使用文件中使用&#xff1b; 3、函数可以调用自己成为递归函数&#xff1b; #include<stdio.h> void bubblesort(int arr[],int len) {for(int i0;i<len…

Spring WebSocket实现实时通信

简介 WebSocket 是基于TCP/IP协议,独立于HTTP协议的通信协议。WebSocket 连接允许客户端和服务器之间的全双工通信,以便任何一方都可以通过已建立的连接将数据推送到另一方。 我们常用的HTTP是客户端通过「请求-响应」的方式与服务器建立通信的,必须是客户端主动触发的行为…

Hutool导入导出用法

整理了下Hutool导入导出的简单使用。 导入maven或jar包&#xff08;注意这里导入的poi只是为了优化样式&#xff09; <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --> <dependency><groupId>cn.hutool</groupId><artifactId&g…

【笔记】Helm-5 Chart模板指南-6 流控制

流控制 控制结构&#xff08;在模板语言中称为“actions”&#xff09;提供给您和模板作者控制模板迭代流的能力。Helm的模板语言提供了以下控制结构&#xff1a; if/else&#xff0c;用来创建条件语句 with&#xff0c;用来指定范围 range&#xff0c;提供“for each”类型…

2024技术发展洞察与趋势学习总结

2023技术发展洞察 2024技术发展趋势

QT假如有三个线程如何保证顺序执行

目录 1 QSemaphore 2 QMutex和QWaitCondition 3 QFuture 1 QSemaphore #include <QSemaphore> #include <QThread> #include <QDebug> QSemaphore sem1(1); QSemaphore sem2(0); QSemaphore sem3(0);class Thread1 : public QThread { public:void run()…

服务器为什么老是被攻击?被攻击了怎么办?

1、关闭端口&#xff0c;只打开必要的端口 服务器端口是攻击的主要入口&#xff0c;是服务器的外部窗口。服务器上的开放端口被黑客使用&#xff0c;他们通过这些开放端口攻击服务器。相对有效的预防方法是关闭一些不必要的端口&#xff0c;然后修改关键端口。如果你少开一个开…

《Lua程序设计》-- 学习10

环境&#xff08;Environment&#xff09; 具有动态名称的全局变量 全局变量的声明 由于Lua语言将全局变量存放在一个普通的表中&#xff0c;所以可以通过元表来发现访问不存在全局变量的情况。 正如前面所提到的&#xff0c;我们不允许值为nil的全局变量&#xff0c;因为值为…