查找算法(一)顺序表查找

顺序表的查找(按位查找、按值查找)(数据结构与算法) 能够实现随机存储的基础就在于顺序表中所有的数据元素在内存里都是连续存放的,并且这些数据元素的数据类型相同,也就是说每个数据元素所占的内存空间一样大。所以我们只需要知道一个顺序表的起始地址,每个数据元素的大小,就可以立即找到第 i 个元素的位置。按值查找操作,在表L中查找具有给定关键字值的元素。GetElem(L, i) :按位查找,获取表L中第 i 个位置元素的值。如果换一个类型的指针,指向同一个地址,int *p;顺序表的按位查找---------动态分配。 阅读详情

参考:
博客 https://blog.youkuaiyun.com/sayhello_world/article/details/77200009
《大话数据结构》

顺序表查找分为:

  • 顺序查找

  • 有序查找

    • 折半查找
    • 插值查找
    • 斐波那契查找
  • 线性索引查找
    • 稠密索引查找
    • 分块索引查找
    • 倒序查找

1.顺序查找

基本思想:顺序查找是最基本的查找技术,查找过程是:从表中的第一个或者最后一个元素开始,依次将元素和待查找的值进行比较,若相同,则查找成功;若直到表尾或表头,元素和待查找的值都不相同,则查找不成功

代码实现:

public class SequentialSearch {

    public static void main(String[] args) {
        int[] a = {0,1,16,24,35,47,59,62,73,88,99};
        System.out.println(sequential(a,62));
    }

    public static int sequential(int[] a, int target){
        int len = a.length;

        for(int i=0;i<len;i++){
            if(a[i]==target){
                return i;
            }
        }
        return -1;
    }
}

复杂度分析:
查找成功的平均查找时间为(1+2+3+…+n)/n = (n+1)/2;
查找失败需要进行n+1次比较;
所以顺序查找的时间复杂度为O(n)

2.有序查找

2.1折半查找

折半查找又叫二分查找,其前提是序列为有序的,若为无需序列,需要先进行排序。

基本思想: 因为序列为有序序列,首先将待查找的数据k与序列中间元素a[mid]进行比较,如相同,则查找成功;若k > a[mid],则表明其存在于后半部分,否则在前半部分,由此继续递归查找,直到查找到或者查找失败。

代码实现:

import java.util.Arrays;

public class BinarySearch {

    public static void main(String[] args) {
        int[] a = {0,1,16,24,35,47,59,62,73,88,99};
        System.out.println(binary(a,62));

    }

    public static int binary(int[] a, int target){
        int len = a.length;
        int i = 0;
        int j = len-1;
        int mid;

        //首先对数据进行排序
        Arrays.sort(a);

        while(i<=j){
            mid = (i+j)/2;
            if(a[mid] == target)
                return mid;
            if(target > a[mid]){
                i = mid+1;
            }else{
                j = mid - 1;
            }
        }
        return -1;  
    }
}

时间复杂度分析: 每次比较可以排除掉一半的数据,所以时间复杂度为O(logn)。

注意:二分查找的前提是元素是有序的,所以对于静态表,一次排序后不再变化,其查找效率是不错的,但是对于需要频繁插入和删除的数据来说,单纯维护其序列有序就会带来不小的开销,所以在这种情况下,二分查找并不适用。

2.2 插值查找

插值查找是根据待查找的数据key和序列中最大最小值比较后的查找方法,是二分查找的一种变形。

基本思想: 对于折半查找来说,每次都从1/2处进行,但是例如对于1~10000中间的100数里查找数值5来说,首先需要考虑从数组下标较小的开始查找,而不是直接从1/2处,这样才可以提供查找的效率。
所以将查找点的计算改为:(key - a[low]) / (a[high] - a[low]);
所以 mid = low + (key - a[low]) * (high - low) / (a[high] - a[low])

代码实现:

只需要将二分查找中的mid = (i+j)/2 改为
mid = i + (j-i)*(target - a[i])/(a[j]-a[i]);

时间复杂度分析: 其平均时间复杂度O(logn),对于表较长,且数值均匀分布的序列来说,插值查找平均性能要比折半查找好得多,但是对于极端不均匀分布的数据,差值查找不一定是是合适的选择。

2.3斐波那契查找

斐波那契查找也是二分查找的一种变形,也是一种有序查找算法。
首先介绍下黄金分割:是指饰物各部分之间存在的一定数学比例关系,即将整体一分为二,较大部分/较小部分 = 整体 / 较大部分,其比值约为1.618:1。
对有斐波那契数列,后面每一个数是前面两个数字的和,并且可以发现,随着斐波那契数列的递增,前后两个数字的比值越来约接近0.618,在斐波那契查找中,便是利用到这一特性。

基本思想: 将黄金分割的概念运用在查找点的计算上,提高查找效率。
如下图所示(图片来源https://blog.youkuaiyun.com/sayhello_world/article/details/77200009,侵权删),序列的长度为斐波那契数列中的一个数值减1,即n = F(k) - 1; 那么插入点mid = low + (F(k-1) - 1)。
若 key == a[mid], 查找成功;
若 key > a[mid], 则在右半部分,所以有left = mid+1,且 k = k-2;
若 key < a[mid], 则在左半部分,所以有right = mid-1,且 k = k-1;
这里写图片描述

代码实现:

import java.util.Arrays;

public class FibonacciSearch {
    public static void main(String[] args) {
        int[] a = {0,1,16,24,35,47,59,62,73,88,99};
        System.out.println(Fibonacci(a,62));

    }

    public static int Fibonacci(int[] a, int target){
        int len = a.length;
        int[] F = creatFibonacci();

        int k = 0;
        //遍历斐波那契数列,找到k的值
        for(int i = 0;i<F.length;i++){
            if(len > F[k]-1){
                k++;
            }
        }

        //当F[k]-1>n的是否,需要不全待查找的序列,Arrays类中的copyOf方法将a数组补长到F[k]-1
        int[] temp = Arrays.copyOf(a, F[k]-1);
        for(int i = len;i<F[k]-1;i++){
            temp[i] = temp[len-1];
        }

        int left = 0;
        int right = F[k]-1;
        int mid;

        while(left<right){
            mid = F[k-1] - 1;
            if(temp[mid] == target)
                return mid;
            if(target > temp[mid]){
                left = mid+1;
                k -= 2;
            }else{
                right = mid - 1;
                k -= 1;
            }
        }

        return -1;
    }

    //初始化一个斐波那契数组,长度为20,F[19] = 6765,已经挺大的了,所以这里定义的长度20
    public static int[] creatFibonacci(){
        int[] F = new int[20];

        F[0] = 0;
        F[1] = 1;

        for(int i = 2;i<20;i++){
            F[i] = F[i-1] + F[i-2];
        }
        return F;
    }
}

复杂度分析: 时间复杂度为O(logn)

总结:顺序查找不需要序列为有序的;而折半查找、插值查找以及斐波那契查找则均是在序列有序的基础上进行的,只是查找点上有不同,各有各的优势,在实际使用当中,需要综合考虑来做出选择。

3.线性索引查找

在现实中,数据是不断处于动态增长且无序的,前面有序查找算法需要基于有序的基础上,所以对于大量增长非常快的数据集来说,维护数据有序的代价是非常非常大的。所以出现了索引。
索引就是把一个关键字与它对应的记录相关联的过程,加快查找速度。
线性索引查找就是将索引项集合组织为线性结构,称为索引表。

3.1稠密索引

稠密索引是指在现象索引中,将数据集中的每个记录对应一个索引项。
这里写图片描述
索引项按照关键码有序排列,当查找关键字时,可以通过折半、插值、斐波那契等有序算法进行查找,大大提高效率。
对于稠密所以,意味着索引和数据集具有同样的长度,当数据非常大时,稠密索引的查找效率大大降低。

3.2分块索引

为减少索引个数,将数据集进行分块,对每块建立索引项。
这些块需要满足一下两个条件:

  • 快内无序,即对每一块内的记录不要求有序,维护快内有序需要付出大量的时间和空间代价;
  • 块间有序,快间有序,才能在查找中带来效率。

这里写图片描述

分块索引查找步骤:
(1)在分块索引表中查找关键字所在块,因为块间有序,所以同样可以使用有序查找算法提高效率;
(2)根据块首指针找到相应的块,因为块中无序,所以在块中顺序查找的得到关键码。

分块查找的时间复杂度为:O(√n)

3.3倒序索引

倒序索引的典型应用就是搜索引擎。
倒序索引是建立被搜索的关键词和含这些关键字的页面之间的映射,其中倒序指的是从关键词中查找到对应的源,而不是从源中查找到相应的关键词。
将倒序索引表排序后,同样可以通过有序查找算法快速查找到关键字,进而查找到包含关键字的页。
例如:为了检索关键词java,首先从倒序索引表中,找到该关键词,然后便可以查找到java所在的页了。

【数据结构】算法9.1 顺序表查找-顺序查找 #include<stdio.h> #include<string.h> #include<stdlib.h>#define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2#define LIST_INIT_SIZE 100 //存储空间的初始分配量#defin 阅读详情

相关推荐

F280049C_HRPWM_死区时间高精度控制与MEP技术实战解析

本文深入解析了F280049C的HRPWM模块及其基于MEP技术的死区时间高精度控制。通过实测数据与TI官方代码对比,详细阐述了DBREDHR和DBFEDHR寄存器的配置技巧、精度优化方法及常见问题调试,为电源管理和电机控制应用提供了实用的实战指南。

yolo5detector的博客 216

顺序查找(算法学习)

查找就是从从某个数据结构中找出指定条件的元素,找到满足的条件元素便表示查找成功,反之代表查找失败,查找的方式也会根据元素所处的数据结构的不同而出现不同的查找方式。

weixin_44451672的博客 1万+

日语五十音图速记攻略:从形象联想法到实战训练

语言学习中的记忆编码与条件反射构建是高效掌握基础的关键。其核心原理在于通过将抽象符号与具象图像、故事或已知概念关联,利用大脑对视觉和叙事信息的天然高记忆效率,从而降低认知负荷,加速识别与反应速度。这一方法的技术价值在于将机械重复转化为意义联结,显著提升长期记忆的牢固度与提取速度。在日语学习这一具体应用场景中,五十音图作为表音文字系统,正是实践这一记忆技术的绝佳对象。通过系统化的形象联想、分组对比(如平假名与片假名的对应关系)以及间隔重复的实战训练,学习者可以高效攻克这一入门难关,为后续的词汇、语法学习铺设坚

weixin_29032489的博客 377

查找(一)—— 顺序查找

顺序查找(又称线性查找)是一种简单的查找算法,它按照数据元素的顺序从前往后依次查找目标元素。顺序查找的基本思路是将目标元素与当前位置的元素进行比较,若相等则查找成功;否则继续向后查找,直到找到目标元素或搜索到末尾位置为止。其中n为数据元素的个数。不论有序无序、连续存储还是离散存储,都能使用,使用范围广,但是速度慢,时间复杂度为O(n)。

qq_50685510的博客 6745

草莓成熟度与叶片病虫害智能检测数据集应用全解析

本文深入解析草莓成熟度与叶片病虫害智能检测数据集的应用价值,涵盖从绿草莓到红果转色的完整成熟周期及白粉病、炭疽病等7种病害的精准识别。通过实战案例展示如何提升病害识别率至94%,并介绍数据集的科研价值,包括跨品种迁移学习和多模态数据融合技术。

weixin_28366353的博客 274

Linux下Linpack测试GPU和CPU性能

前面的文章已经介绍了如何搭建Linpack环境:https://blog.youkuaiyun.com/liu_feng_zi_/article/details/107429720 接下来说明如何使用 一、编写运行脚本: 新建文件:run_linpack.sh,内容如下: export HPL_DIR =/root/LHC/Linpack/hpl-2.0_FERMI_v15 export MKL_NUM_THREADS=6 export OMP_NUM_THREADS=6 export MKL_DYNAMI.

liu_feng_zi_的专栏 4633

顺序表的查找

顺序表查找,顺序表特点,顺序表优缺点

m0_63341217的博客 2413

第一节:初识n8n与下一代工作流自动化

本章介绍了n8n的Fair-code理念与节点式架构,对比了其与Zapier/Make的核心差异,并引导读者在n8n Cloud上完成首次界面导览,建立了工作流自动化的宏观认知。

easeyoo的专栏 104

算法设计题目一 顺序表查找

/**/ #include "stdio.h" #include "malloc.h" #define LIST_SIZE 20   typedef struct{          charr[LIST_SIZE];          intlength; //length为表中元素的个数 }RecordList;   RecordList *SqLset(){  //建

中国好利鹏 3322

拼多多Android面试题及参考答案

Android 系统采用分层架构设计,从底层到上层依次为Linux 内核层硬件抽象层(HAL)系统运行时库层应用框架层应用层,共五层。位置:Linux 内核层与系统运行时库层之间,是“硬件与系统的隔离层”。核心作用:屏蔽硬件差异,为上层提供统一的硬件访问接口,解决 Android 开源与硬件厂商闭源的矛盾,具体功能如下:硬件能力抽象:将硬件的具体实现(如不同厂商的摄像头芯片、音频芯片)封装为标准化接口(如Camera HALAudio HAL。

大模型大数据攻城狮的专栏 1282

损失函数大汇总(八)(IoU Loss附公式推导与代码)

本文详细介绍了IoU Loss及其在图像分割中的应用。IoU(交并比)是衡量预测区域与真实区域重叠程度的指标,IoU Loss定义为1-IoU,直接优化区域重叠质量。文章推导了IoU的数学表达式和梯度计算,分析了其函数特性:全局耦合梯度、对漏检误检的双重惩罚、适合类别不平衡任务。与Dice Loss相比,IoU更强调覆盖质量而非相似度。实际应用中IoU Loss常与BCE组合使用,前者保证训练稳定性,后者优化整体区域质量。文章还提供了IoU Loss的代码实现,适用于二值分割、小目标提取等场景,特别当任务评

悦学共鸣,温柔以待,汇聚光芒,共同成长 414

查找算法整理(一)---静态查找表:顺序表查找、折半(判定树)查找、静态查找树

查找在实际应用中也是最为常见的。通常我们要在一个集合中查找某一个数或多个数,这个集合称为查找表。查找表分为静态查找表和动态查找表。 静态查找表:在查找表中查询某个“特定的”元素,查找表的大小不会改变,即仅限于查找某个元素,查找表不会被修改。 动态查找表:在查找过程向查找表中删除或插入一个元素,即若在查找过程中同时插入查找表中不存在的元素,或者从查找表中删除已存在的某个元素。 本小节整理的是静

GordonOo的专栏 4332

ICC2: place阶段的clock network delay

设置了set_clock_latency之后,即便没长tree,也会有反标值,显示为clock network delay(ideal)和设置的clock latency值,需要注意的是同时设置set_clock_latency和set_clock_latency -source,clock network delay(ideal)值是二者叠加的。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 314

数据结构:顺序表

顺序表作为一种基础的数据结构,在计算机编程中有着广泛的应用。通过对顺序表的理解和实现,可以更好地掌握数据结构的基本原理,为解决复杂问题打下坚实的基础。希望通过本文的介绍,读者能够对顺序表有更深入的认识和掌握。

2402_82606495的博客 1550

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

查找算法三:顺序查找

1.原理简介 最坏情况须比较n+1次,时间复杂度:O(n) 。平均查找长度为ASL=1/n(1+2+3+…+n)=(n+1)/2 2.C++代码实现 (1)数组法实现 int SequenceSearch(int a[], int value, int n)//数组查找 { int i; for(i=0; i<n; i++) ...

no_heart2019的博客 532

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C数据结构--顺序表

顺序表是一种数据结构,在介绍顺序表之前我们需要知道什么是数据结构,在生活中不借助排队的方式来管理客呼,会导致客户就餐感受差、等餐时间长、餐厅营业混乱等 情况。同理,程序中如果不对数据进行管理,可能会导致数据丢失、操作数据困难、野指针等情况。通过数据结构,能够有效将数据组织和管理在⼀起。按照我们的方式任意对数据进行增删改查等操作。一、什么是数据结构数据结构是由“数据”和“结构”两词组合而来。什么是数据?

Jk_Mr的博客 778

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

顺序表-递增有序表合并

实现一个顺序表的删除操作,删除顺序表中所有值为x的元素。

qq_52291558的博客 614

Linux数据结构——静态顺序表(二)

获取顺序表中任意一个位置的数据SeqListType SeqListGet(SeqList* seqlist,size_t pos,SeqListType default_value){ if(seqlist == NULL){ return; } if(SeqList-&gt;size == 0){ return; ...

晴时有风阴有雨的博客 246

【数据结构】——顺序表

当我们想要使⽤大量使⽤同⼀类型的数据时,通过⼿动定义⼤量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将⼤量的数据组织在⼀起,结构也可以理解为组织数据的方式。在使用完顺序表后,就要销毁顺序表,因为动态顺序表内存是动态开辟的,所以需要对动态内存进行释放,并将有效数据和空间容量个数置为0;到这里,顺序表的知识就完成了,学完这些,我们也要写顺序表的实践,就是通讯录——在下一篇进行实现。求数组的长度,求数组的有效数据个数,向下标为数据有效个数的位置插入数据(注意:这里是。

LH__1314的博客 8995

顺序表讲解

本文大纲1.线性表2.顺序表2.1概念与结构2.2分类2.2.1静态顺序表2.2.2动态顺序表2.3动态顺序表的实现(增删查改)2.4顺序表算法题。

2301_77946061的博客 345

408考研数据结构:顺序查找与折半查找算法详解与可视化

查找算法是数据结构中的基础概念,用于在数据集合中定位特定元素。顺序查找通过线性遍历逐个比较元素,时间复杂度为O(n),适用于无序数据和小规模场景;折半查找基于二分思想,要求数据有序,每次比较可排除一半搜索空间,时间复杂度为O(log₂n)。这两种算法在工程实践中广泛应用于数据库查询、缓存检索等场景,尤其在408计算机考研中属于高频考点。通过可视化图示和代码实现,考生可快速掌握算法核心逻辑,提升对时间复杂度分析和适用场景的理解,为考研实战打下坚实基础。

keke1314520的博客 305

顺序表应用1:多余元素删除之移位算法

Problem Description 一个长度不超过10000数据的顺序表,可能存在着一些值相同的“多余”数据元素(类型为整型),编写一个程序将“多余”的数据元素从顺序表中删除,使该表由一个“非纯表”(值相同的元素在表中可能有多个)变成一个“纯表”(值相同的元素在表中只保留第一个)。 要求:        1、必须先定义线性表的结构与操作函数,在主函数中借助该定义与操作函数调用实现问题功能; ...

王子原的博客 192

【数据结构】编程实现有序顺序表的顺序查找和二分查找算法。C++版

一、实验目的: 熟悉各种查找算法及其复杂性,能够根据实际情况选择合适的存储结构。二、实验要求: 算法完善,考虑时间复杂度。三、实验内容: 编程实现有序顺序表的顺序查找和二分查找算法。 代码段 #include <iostream> using namespace std; #define MAXSIZE 100 typedef int KeyType; //数据元素类型定义 typedef struct{ KeyType key;//数据域 }ElemType; //顺序表的定.

qq_52978240的博客 6337

数据结构顺序表算法题(逆置、查找值、负值在正值前、循环移动)

先声明:本人是个初学者,本博客全为我自己写的,只是作为个人学习记录使用,很有可能不够规范或漏洞百出,请多包涵。 ps:有个小目标,大概就是之后输入数据能通过产生随机数实现,到时候再钻研,本博客还是手动输入的简单样例数据。 首先先简单定义一个用动态存储分配的顺序表以及初始化以及根据长度打印表的函数: #include<stdio.h> #include<malloc.h> #define initSize 100 typedef int ElemType; typedef s

m0_52461904的博客 1902

算法设计题——顺序表

请写一个算法,在顺序表中查找指定的数据,查找成功则将该记录放到顺序表的最前面,而把其他记录后退到有限个位置。

WYMei_529 1853
上一篇: LeetCode 之 Search in Rotated Sorted Array II
下一篇: 多动态图详细讲解二叉搜索树
小菜鸟要高飞
博客等级 码龄12年 14粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值