数据结构——7.17.2 查找的基本概念、顺序查找和折半查找

2024-04-21 08:04

本文主要是介绍数据结构——7.17.2 查找的基本概念、顺序查找和折半查找,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

7.1&7.2 查找的基本概念、顺序查找和折半查找

1. 基本概念

1.  关键字:数据元素中标识该元素的某个数据项的值,使用基于关键字的查找,查找结果应该是唯一的。2.  查找表的常见操作1.  查找符合条件的数据元素:查得快即可2.  插入、删除某个数据元素:兼顾查找速度和操作便捷3.  查找算法的评价指标1.  查找长度——在查找运算中,需要对比关键字的次数称为查找长度2.  平均查找长度(ASL,Average Search Length)——所有查找过程中进行关键字的比较次数的平均值

2. 顺序查找

也称:线性查找,即遍历,常用于线性表(顺序、链表)

顺序查找,是一种简单的查找方式。这种查找方法从列表的一端开始,顺序搜索直到找到所需的元素为止。

顺序查找的基本思想是:从列表的第一个元素开始,逐个检查每个元素,直到找到所需的元素或搜索到列表的末尾为止。

顺序查找的步骤如下:
  1. 从列表的第一个元素开始,与所要查找的元素进行比较。
  2. 如果相等,则查找成功,返回该元素在列表中的位置。
  3. 如果不相等,则继续向后查找下一个元素。
  4. 重复以上步骤,直到找到所需元素或搜索到列表的末尾。

顺序查找的时间复杂度是O(n),其中n是列表中元素的数量。这是因为在最坏的情况下,可能需要检查列表中的每个元素。虽然顺序查找在某些情况下可能不是最高效的查找方法,但它简单易懂,适用于小型列表或对效率要求不高的场景。

优化思路:将大概率要被查询的值放到前面来;该方法适用于经常需要查询的情况

顺序查找虽然简单易懂,但在处理大型数据集时效率较低。为了优化顺序查找的性能,可以考虑以下几种方法:

  1. 减少比较次数

    • 预处理数据:在搜索前对数据进行排序,可以减少平均情况下的比较次数。虽然排序本身需要时间,但对于多次查找的情况,排序可能是一个值得的预处理步骤。
    • 利用数据的特性:如果数据具有某种模式或分布,可以设计更高效的查找策略。
  2. 使用哨兵或标记

    • 在列表的末尾添加一个哨兵值或标记,这样当查找的元素不存在时,可以更快地停止查找。
  3. 分块查找

    • 将列表分成多个块,每个块内部可以是无序的,但块之间是有序的。首先确定目标元素可能存在的块,然后在该块内进行顺序查找。这种方法结合了顺序查找和索引查找的优点。
  4. 使用更好的数据结构

    • 如果可能的话,使用更高效的数据结构(如哈希表、二分查找树等)来存储和查找数据。这些数据结构提供了更快的查找时间复杂度。
  5. 并行化

    • 在多核处理器或多计算机环境下,可以并行地进行查找操作。将数据分割成多个部分,每个部分由一个处理单元同时搜索。
  6. 缓存优化

    • 对于顺序访问的列表,确保数据在物理内存中是连续的,以减少缓存未命中的次数。
  7. 算法层面的优化

    • 使用更高效的比较算法,比如对于大型整数或浮点数,可以使用更快速的比较方法。

需要注意的是,优化顺序查找的性能通常需要根据具体的应用场景和数据特点来选择合适的方法。在某些情况下,优化可能并不总是值得的,因为可能会增加代码的复杂性和维护成本。因此,在进行优化之前,需要仔细评估需求和性能要求,并确定最合适的优化策略。

3. 折半查找

折半查找,又称“二分查找”,仅适用于有序的顺序表,这是因为顺序表具有随机存储的特性,而链表没有

折半查找,是一种在有序数组中查找某一特定元素的搜索算法。其基本原理是从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或小于中间元素,则在数组大于或小于中间元素的那一半中继续查找,每次查找都从中间元素开始比较。这样,每一次比较都能使搜索范围缩小一半,因此它是一种效率较高的查找方法。

使用折半查找的前提是对有序数组进行查找,其主要应用场景是查找数组中某个切实存在的数字,也可以稍微变化一些应用场景,如查找有序的字符数组中的某个字符,或者是查找某个数值所在的区间。

折半查找的过程包括建立要查找的有序数组,定义起点、中间点、终点变量和要查找的常量,然后进入查找循环,编写查找逻辑。如果在某一步骤数组为空,则代表找不到目标元素。

折半查找的效率

折半查找(二分查找)的效率非常高,其时间复杂度为O(log n),其中n是数组中的元素数量。这是因为每次查找都能将搜索范围缩小一半,所以查找次数与数组大小的对数成正比。这种高效的查找效率使得折半查找在处理大型有序数组时特别有用。

然而,值得注意的是,折半查找的前提是数组必须是有序的。如果数组无序,那么折半查找将无法进行,此时需要使用其他查找算法,如顺序查找。此外,虽然折半查找的查找效率很高,但其插入和删除操作的效率却相对较低,因为需要保持数组的有序性。

在实际应用中,如果数据量大且经常需要进行查找操作,且可以预先对数据进行排序,那么使用折半查找将是非常合适的选择。然而,如果数据量较小,或者数据的插入和删除操作频繁,那么可能需要考虑使用其他数据结构或算法来平衡查找和更新操作的效率。

4. 分块查找

分块查找,也称为块查找或索引顺序查找,是一种查找算法。它是折半查找和顺序查找的一种改进方法,特别适合于节点动态变化的情况。

分块查找的基本思想是将数据划分为多个块,并对每个块进行排序。每个块内的数据元素有序排列,而块与块之间是有序的,即第i+1块的所有记录关键字均大于(或小于)第i块记录关键字。在查找时,首先确定待查记录所在块,再在块内进行顺序查找。

分块查找的优点在于,由于只要求索引表是有序的,对块内节点没有排序要求,因此可以跳过一些不必要的块,从而提高查找效率。然而,由于需要预处理数据集,因此在数据集经常变化的情况下,它的效率可能会降低。因此,分块查找更适用于数据较多但数据不会发生变化的情况。

总之,分块查找结合了顺序查找和二分查找的优点,使得在大规模数据集中进行查找更加高效。

- 理解

  1. 折半查找过程对应的判定树一定是一棵平衡二叉树

  2. 折半查找和二叉排序树的性能比较

    1. 折半查找是二叉排序树最好的情况,复杂度O(log₂n)

    2. 二叉排序树如果形成单树,则与顺序查找相似,复杂度O(n)

  3. 对于一个长度为n的有序顺序表,如果采用折半查找一个不存在的元素,比较次数最多即为树高【log₂(n+1)】,最少即为树高减去1

  4. 计算折半查找平均失败查找时间,每个失败点的比较次数即为该点父节点的高度,即为该结点高度减一

  5. 判断空白二叉树是否是折半二叉树的办法

    1. 按照排序二叉树规则,从小到大为各空白结点标上数字

    2. 根据折半规则,判断每个树是向上折半取整还是向下折半取整、

    3. 判断各根节点是否符合折半规则、取整规则

      1. 向上取整都是优先排在左边,左子树比右子树最多多一个结点

      2. 向下取整都是优先排在右边,右子树比左子树最多多一个结点

- 技巧

  1. 顺序查找,无论是有序表还是无序表,平均查找时间相同

  2. 折半查找的判定树是一棵二叉排序树,因此,给出一定的比较值序列,如果不满足二叉排序树的规则(左<根<右)则不是折半的比较序列

这篇关于数据结构——7.17.2 查找的基本概念、顺序查找和折半查找的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922566

相关文章

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消

AOP编程的基本概念与idea编辑器的配合体验过程

《AOP编程的基本概念与idea编辑器的配合体验过程》文章简要介绍了AOP基础概念,包括Before/Around通知、PointCut切入点、Advice通知体、JoinPoint连接点等,说明它们... 目录BeforeAroundAdvise — 通知PointCut — 切入点Acpect — 切面

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图

redis数据结构之String详解

《redis数据结构之String详解》Redis以String为基础类型,因C字符串效率低、非二进制安全等问题,采用SDS动态字符串实现高效存储,通过RedisObject封装,支持多种编码方式(如... 目录一、为什么Redis选String作为基础类型?二、SDS底层数据结构三、RedisObject

Python中高级文本模式匹配与查找技术指南

《Python中高级文本模式匹配与查找技术指南》文本处理是编程世界的永恒主题,而模式匹配则是文本处理的基石,本文将深度剖析PythonCookbook中的核心匹配技术,并结合实际工程案例展示其应用,希... 目录引言一、基础工具:字符串方法与序列匹配二、正则表达式:模式匹配的瑞士军刀2.1 re模块核心AP

Spring Bean初始化及@PostConstruc执行顺序示例详解

《SpringBean初始化及@PostConstruc执行顺序示例详解》本文给大家介绍SpringBean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的... 目录1. Bean初始化执行顺序2. 成员变量初始化顺序2.1 普通Java类(非Spring环境)(

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

C++作用域和标识符查找规则详解

《C++作用域和标识符查找规则详解》在C++中,作用域(Scope)和标识符查找(IdentifierLookup)是理解代码行为的重要概念,本文将详细介绍这些规则,并通过实例来说明它们的工作原理,需... 目录作用域标识符查找规则1. 普通查找(Ordinary Lookup)2. 限定查找(Qualif