查找——数据结构与算法 总结7

news2024/12/25 12:45:45

目录

7.1 查找的相关概念

7.2 线性表的查找

7.2.1 顺序查找(Linear Search)

7.2.2 折半查找(Binary Search)

判定树(折半查找判定树):描述折半查找判定过程的二叉树

7.3 树表的查找

7.31 二叉排序树

7.32 平衡二叉树

7.4 哈希表查找

7.4.1 哈希函数构造方法:

7.4.2 解决哈希冲突的方法


7.1 查找的相关概念

查找的基本概念:一般情况下,被查找的对象称为查找表(线性表、树表和哈希表)。

查找表包含一组元素(或记录),每个元素由若干个数据项组成,并假设有能唯一标识元素的数据项,称为主关键字(默认按主关键字查找)。

查找基于的数据模型是集合、

线性表:适用于静态查找,顺序查找、折半查找等技术

树表:适用于动态查找,二叉排序树的查找技术

散列表:静态查找和动态查找均适用,采用散列技术

  • 静态查找表只作查找操作的查找表,主要操作有查询某个“特定的”数据元素是否在查找表中,检索某个“特定的”数据元素及其属性。
  • 动态查找表是在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素。
  • 若整个查找过程都在内存进行,则称之为内查找。
  • 反之,若查找过程中需要访问外存,则称之为外查找。

查找算法中的主要操作是关键字之间的比较,所以通常把查找过程中关键字平均比较次数也就是平均查找长度作为衡量一个查找算法效率优劣的依据。

7.2 线性表的查找

三种线性表查找方法,即顺序查找、折半查找和分块查找算法。

7.2.1 顺序查找(Linear Search)

思路:

  • 从顺序表的一端开始依次遍历,将遍历的元素关键字和给定值k相比较,
  • 若两者相等,则查找成功,返回该元素的序号。
  • 若遍历结束后,仍未找到关键字等于k的元素,则查找失败,返回-1。
  • 默认从顺序表的前端开始遍历。

原本顺序查找每次都要判断index是否小于总长。改进:将待查值放在查找方向的尽头,就避免了每次判断是否越界。

时间复杂度:O(n)

7.2.2 折半查找(Binary Search)

思路:数组排好序,选择中间数(low+high)/2作为基准,判断查找值与中间数的大小关系,来判断查找值在哪个区间。将区间逐渐细化直到low>=high

折半查找时间复杂度:O(log_2n)

判定树(折半查找判定树):描述折半查找判定过程的二叉树

  • 折半查找任一记录的过程,即是判定树中从根结点到该记录结点的路径。比较次数等于该记录结点在树中的层数
  • 当n不等于2^h-1时(h表示树的高度),其折半查找判定树不一定为满二叉树,但可以证明n个结点的判定树的高度与n个结点的完全二叉树的高度相等,即h为\left \lfloor log_2(n+1) \right \rfloor或者\left \lfloor log_2n \right \rfloor +1

内部结点是mid的元素值(如果没给就用下标)

外部节点表示查找不成功时元素对应的范围

 (因为外部结点比较次数 = 外部结点层数-1)

折半查找判定树和二叉排序树的区别:折半查找判定树是基于有序集合的,二叉排序树是基于无序集合的

7.3 树表的查找

7.31 二叉排序树

几种特殊树形结构统称为树表。这里树表采用链式存储结构,属于动态查找表。

1. 二叉排序树(BST)的定义:

      二叉排序树或者是空树,或者是满足如下性质的二叉树:

    (1) 若左子树非空,则左子树上所有结点值(默认为结点关键字)均小于根结点值

    (2) 若右子树非空,则右子树上所有结点值均大于根结点值

    (3) 左、右子树本身又各是一棵二叉排序树

特点:中序序列是一个递增有序序列

2. 二叉排序树的构建:

定义二叉排序树的结点类:有四个属性:key关键字,data数据项,lchild左孩子指针,rchild右孩子指针

定义二叉排序树类:有两个属性:r根节点,f待删除结点的双亲结点(删除操作时用)

3. 二叉排序树的插入:

在根节点r的二叉排序树中插入关键字为k的结点的过程:

    若r为空,创建一个key=k的结点,将它作为根结点

    若k<r.key,将k插入r结点的左子树

    若k>r.key,将k插入r结点的右子树

    若k=r.key,说明树中已有关键字k

4. 二叉排序树的生成:

先创建根节点,之后每用上面插入的方法逐个将关键字k插入到二叉排序树中。

5. 二叉排序树的查找:

查找定值k的过程:

    若r是空树,则查找失败

    若k=r.key,则查找成功

    若k<r.key,则在r的左子树上查找

    若k>r.key,则在r的右子树上查找

算法上用递归查找

查找中关键字比较次数不超过树的高度

6. 二叉排序树的删除:

删除通过修改双亲的相关指针实现

删除结点p的几种情况:

    若p是叶子结点:直接删除,将双亲结点中相应指针域的值改为空

    若p只有左孩子:将双亲结点中相应指针域指向p的左子树

    若p只有右孩子:将双亲结点中相应指针域指向p的右子树

    若p有两个孩子:将双亲结点中相应指针域指向p的左子树中关键字最大的结点

7. 时间复杂度:

平均情况:O(n)~O(log2n)

最好情况:相当于折半查找

最坏情况:相当于线性查找

关键字序列不同,二叉排序树也不同,查找性能不同。高度最小的二叉排序树性能为O(log2n),高度最大的二叉排序树性能为O(n)

插入、删除、查找的时间复杂度相同

 (因为外部结点比较次数 = 外部结点层数-1)

【例题】按照序列(50,38,30,45,40,48,70,60,75,80)构造一棵二叉排序树

 = 2.9

 = 3.55

7.32 平衡二叉树

  • 平衡二叉树定义:或者是一棵空的二叉排序树,或者是具有下列性质的二叉排序树

        根结点的左子树和右子树的深度最多相差1

        根结点的左子树和右子树也都是平衡二叉树

  • 平衡因子:该结点的左子树的深度减去右子树的深度。在平衡二叉树中,结点的平衡因子是1、0或-1.(叶子结点平衡因子为0,其余往上算)
  • 最小不平衡子树:以距离插入结点最近的、且平衡因子的绝对值大于1的结点为根的子树
  • 含有n个结点的AVL树对应的查找时间复杂度为O(log2n)

推荐视频:【AVL树的定义 .调整 .插入操作】如何理解AVL树这个数据结构_哔哩哔哩_bilibili

1. 调整平衡二叉树:如果一次插入后,树不平衡,就调整最小不平衡子树,不影响其他结点。

调整分为LL型、RR型、LR型、RL型

2. 构造AVL树:每插入一次就判断是否平衡,如果不平衡就调整

【例题】

3. 删除AVL树结点:

删除结点x方法:

如果x左子树为空,用右孩子替换它

如果x右子树为空,用左孩子替换它

如果x同时有左右子树:

    如果左子树较高,用左子树中最大结点q的值替换x的值,删除q结点

    如果右子树较高,用右子树中最小结点q的值替换x的值,删除q结点

如果x没有左右子树,直接删除。

以上哪一步中出现不平衡就调整

【例题】

7.4 哈希表查找

哈希表(Hash Table)又称散列表的基本概念:

设要存储的元素个数为n,设置一个长度为m (m>=n)的连续内存单元

以每个元素的关键字ki(0≤i≤n-1)为自变量,通过一个哈希函数h把ki映射为内存单元的地址(或相对地址)h(ki)。并把该元素存储在这个内存单元中。

  • 对于两个不同的关键字ki和kj(i≠j)出现h(ki)=h(kj),这种现象称为哈希冲突。
  • 将具有不同关键字而具有相同哈希地址的元素称为“同义词”,这种冲突也称为同义词冲突。

7.4.1 哈希函数构造方法:

1. 直接定址法

    以关键字k本身或关键字加上某个数值常量c作为哈希地址的方法。即h(k)=k+c。

    优点:这种哈希函数计算简单,并且不可能有冲突发生。

    缺点:若关键字分布不连续将造成内存单元的大量浪费。

2. 数字分析法

    提取关键字中取值较均匀的数字位作为哈希地址的方法。

    适合于所有关键字值都已知的情况,并需要对关键字中每一位的取值分布情况进行分析。

3. 除留余数法

    用关键字k除以某个不大于哈希表长度m的数p所得的余数作为哈希地址的方法。

    除留余数法的哈希函数h(k)为:h(k)=k mod p (mod为求余运算,p≤m) 

    p的选取:不大于m且接近m的素数。

           p≤m 来保证地址有效

           p为质数 来保证冲突尽可能小

发生哈希冲突有关的三个因素:

1)与装填因子有关。所谓装填因子α是指哈希表中已存入的元素数n与哈希地址空间大小m的比值,即α=n/m。

α越小,冲突的可能性就越小; 但α越小,存储空间的利用率就越低。

2)与所采用的哈希函数有关。

3)与解决冲突的哈希冲突函数有关。

7.4.2 解决哈希冲突的方法

解决哈希冲突可分为开放定址法和拉链法两大类

1 开放定址法

发生冲突时查找周围一个空位置存放记录。

设置一个查找周围一个空位置的函数。

1)线性探测法

  • 从发生冲突的地址(设为d0 )开始,依次循环探测d的下一个地址(当到达下标为m-1的哈希表表尾时,下一个探测的地址是表首地址0),直到找到一个空闲单元为止。
  • 描述公式为: d_0 = h(k), \: d_i = (d_{i-1} +1)\, mod \: m \: \: \: \: \: (1\leq i \leq m-1)

哈希函数值不相同的多个记录争夺同一个后继哈希地址称为非同义词冲突, 导致出现堆积。

2)平方探测法

  • 发生冲突时前后查找空位置。
  • 描述公式为:d_0 = h(k), \: d_i = (d_0 \pm i^2)\, mod \: m \: \: \: \: \: (1\leq i \leq m-1)

平方探测法可以避免出现堆积问题。

缺点是不能探测到哈希表上的所有单元,但至少能探测到一半单元。

【例题】

2. 拉链法

​​​​​

 

 

  • 拉链法是把所有的同义词用单链表链接起来的方法。
  • 在这种方法中,哈希表每个单元中存放的不再是记录本身,而是相应同义词单链表的头指针
  • 由于单链表中可插入任意多个结点,所以此时装填因子α根据同义词的多少既可以设定为大于1,也可以设定为小于或等于1,通常取α=1。
  • 插入时插入到头指针后一个位置

哈希表查找及性能分析:

1. 采用开放定址法建立的哈希表的查找:在哈希表内顺序查找

2. 采用拉链法建立的哈希表的查找:在对应下标的链表中顺序查找

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

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

相关文章

WBCE CMS v1.5.2 远程命令执行漏洞(CVE-2022-25099)

前言 CVE-2022-25099 是一个影响 WBCE CMS v1.5.2 的严重安全漏洞&#xff0c;具体存在于 /languages/index.php 组件中。该漏洞允许攻击者通过上传精心构造的 PHP 文件在受影响的系统上执行任意代码。 技术细节 受影响组件&#xff1a;/languages/index.php受影响版本&…

伯克利、斯坦福和CMU面向具身智能端到端操作联合发布开源通用机器人Policy,可支持多种机器人执行多种任务

不同于LLM或者MLLM那样用于上百亿甚至上千亿参数量的大模型&#xff0c;具身智能端到端大模型并不追求参数规模上的大&#xff0c;而是指其能吸收大量的数据&#xff0c;执行多种任务&#xff0c;并能具备一定的泛化能力&#xff0c;如笔者前博客里的RT1。目前该领域一个前沿工…

LabVIEW环境下OCR文字识别的实现策略与挑战解析

引言 在自动化测试领域&#xff0c;OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术扮演着重要角色&#xff0c;它能够将图像中的文字转换成机器可编辑的格式。对于使用LabVIEW约5个月&#xff0c;主要进行仪器控制与数据采集的你而言…

蓝牙模块功耗优化技术研究

蓝牙模块作为无线通信技术的重要组成部分&#xff0c;在智能家居、可穿戴设备、医疗健康等领域得到了广泛应用。然而&#xff0c;随着设备功能的不断增加和用户对续航能力的日益关注&#xff0c;蓝牙模块的功耗问题逐渐凸显。因此&#xff0c;对蓝牙模块功耗优化技术的研究具有…

两次叛国投敌,没有祸及子孙反而家族长盛不衰的传奇

这个人就是韩国国王韩王信&#xff0c;汉朝八大异姓王之一。 第一次叛国投敌&#xff0c;发生在楚汉争霸时期。有一次他的军队被项羽包围&#xff0c;于是选择了投降。不过&#xff0c;这是权宜之计&#xff0c;不久就借机回到刘邦阵营。 第二次叛国投敌&#xff0c;发生在西…

Docker Desktop 简易操作指南 (Windows, macOS, Linux)

1. 下载最新版本 Docker Desktop https://www.docker.com/products/docker-desktop/ 2.启动 Docker Desktop 3.常用命令&#xff08;在 cmd 或 Terminal 中执行&#xff09; #列出所有镜像&#xff08;Images&#xff09; docker images #列出所有容器&#xff08;Containers&…

发现CPU占用过高,该如何排查解决?

1.使用top命令 查看cpu占用最多的进程 2.使用 top -H -p pid 发现有两个线程占用比较大 3.将线程id转换为16进制 使用命令 printf 0x%x\n pid 4.使用 jstack pid | grep 线程id(16进制&#xff09; -A 20 &#xff08;显示20行&#xff09; 根据代码显示进行错误排查

android2024 gradle8 Processor和ksp两种编译时注解实现

android编译时注解&#xff0c;老生常谈&#xff0c;外面的例子都是bindView&#xff0c;脑壳看疼了&#xff0c;自己学习和编写下。 而且现在已经进化到kotlin2.0&#xff0c;google也逐渐放弃kapt&#xff0c;进入维护状态。所以要好好看看本贴。 参考我的工程&#xff1a; h…

国信华源全力守护湖南水库安全,汛期坚守岗位

连日来&#xff0c;湖南省遭受持续强降雨侵袭&#xff0c;部分地区暴雨倾盆&#xff0c;山塘河库水位急剧上升&#xff0c;防汛形势极为严峻。面对这场防汛大考&#xff0c;北京国信华源公司迅速响应&#xff0c;技术团队以高度的责任感和使命感&#xff0c;全力投入防汛减灾工…

2007年下半年软件设计师【上午题】试题及答案

文章目录 2007年下半年软件设计师上午题--试题2007年下半年软件设计师上午题--答案2007年下半年软件设计师上午题–试题

WEB04MyBatis

Mybatis mybatis查询 准备 准备工作 在目前的数据库中添加一张数据表emp 将资料中提供的day04-01-mybatis导入的目前的工程中 修改配置文件中的数据库的账户和密码 观察实体类中的属性和数据表中的字段的对应关系 查询结果封装 查询所有 SQL语句 select * from emp; …

【源码+文档+调试讲解】智能仓储系统 JSP

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;智能仓储系统当然也不能排除在外。智能仓储系统是以实际运用为开发背景&#xff0c;运用软件工程开发方法&#xff0c;采…

昇思MindSpore学习总结九——FCN语义分割

1、语义分割 图像语义分割&#xff08;semantic segmentation&#xff09;是图像处理和机器视觉技术中关于图像理解的重要一环&#xff0c;AI领域中一个重要分支&#xff0c;常被应用于人脸识别、物体检测、医学影像、卫星图像分析、自动驾驶感知等领域。 语义分割的目的是对图…

简单的git pull fail Can‘t update has no tracked branch解决记录

简单的git pull fail Can‘t update has no tracked branch解决记录 1. 问题描述 上午同事使用idea拉取代码的时候&#xff0c;发现拉取不了&#xff0c;提示用户权限问题&#xff0c;之后修改了git用户信息&#xff0c;发现还是拉取不了分支代码&#xff0c;然后删除了git r…

[pwn]静态编译

静态编译 1. 栈足够大的情况下 程序在ida打开后&#xff0c;左侧的函数栏目没有红色&#xff08;系统调用的函数&#xff09;&#xff0c;而只有一些静态函数&#xff0c;通常这类文件的大小会必普通的pwn题程序要大得多。 这种静态编译的题没有调用库函数&#xff0c;也就没…

nginx部署多个项目;vue打包项目部署设置子路径访问;一个根域名(端口)配置多个子项目

本文解决&#xff1a; vue打包项目部署设置子路径访问&#xff1b;nginx部署多个子项目&#xff1b;一个ip/域名 端口 配置多个子项目&#xff1b;配置后&#xff0c;项目能访问&#xff0c;但是刷新页面就丢失的问题 注&#xff1a;本文需要nginx配置基础。基础不牢的可见文…

springboot + mybatis 多数据源切换

参考的b站博主写的 配置文件: spring:datasource:db1:jdbc-url: jdbc:mysql://localhost:3306/interview_database?useUnicodetrue&characterEncodingutf-8&useSSLfalseusername: rootpassword: 12345driver-class-name: com.mysql.cj.jdbc.Driverdb2:jdbc-url: jdbc…

gda动态调试-cnblog

忽的发现gda有动态调试功能 动态监听返回值 框柱指定方法&#xff0c;选择调试方法&#xff0c;gda会自动监听函数的返回值&#xff0c;例如 自定义frida脚本 gda会自动生成hook该函数的frida脚本

RH850系列芯片深度剖析 1.8-内存管理之MPU

RH850系列芯片深度剖析 1.8-内存管理之MPU 文章目录 RH850系列芯片深度剖析 1.8-内存管理之MPU一、MPU简介1.1 功能特性1.2 系统保护标识符(SPID)二、保护区域设置2.1 保护区域属性设置2.2 保护区域设置注意事项2.2.1 跨越保护区域边界2.2.2 无效的保护区域设置2.2.3 保护违规…

LeetCode热题100刷题4:76. 最小覆盖子串、239. 滑动窗口最大值、53. 最大子数组和、56. 合并区间

76. 最小覆盖子串 滑动窗口解决字串问题。 labuladong的算法小抄中关于滑动窗口的算法总结&#xff1a; class Solution { public:string minWindow(string s, string t) {unordered_map<char,int> need,window;for(char c : t) {need[c];}int left 0, right 0;int …