查找算法(2022年第一篇博客)

简介: 查找算法(2022年第一篇博客)

顺序查找算法

顺序查找又叫线性查找,是最基本的查找技术,它的查找过程是:从表中的第一个(或最后一个)记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录;如果直到最后一个(或第一个)记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找不成功。
在这里插入图片描述
代码:

int Sequential_Search(int*a,int n,int key)
{
    
    int i;
    for(i=1;i<=n;i++)
    {
    
        if(a[i]==key)
        return i;
    }
    return 0;
}

代码优化:

int Sequential_Searchval(int*a,int n,int key)
{
    
    int i;
    a[0]=key;
    i=n;
    while(a[i]!=key)
    {
    
        i--;
    }
    return i;
}

复杂度分析:

查找成功时的平均查找长度为:(假设每个数据元素的概率相等)
   ASL = (1+2+3+…+n)/n = (n+1)/2 ;
  当查找不成功时,需要n+1次比较,时间复杂度为O(n);
  所以,顺序查找的时间复杂度为O(n)

折半查找算法

折半查找,又称二分查找,核心是,通过不断缩小筛选的范围,来实现对key的查找。
以升序数列为例,比较一个元素与数列中的中间位置的元素的大小,如果比中间位置的元素大,则继续在后半部分的数列中进行查找;如果比中间位置的元素小,则在数列的前半部分进行比较;如果相等,则找到了元素的位置。每次比较的数列长度都会是之前数列的一半,直到找到相等元素的位置或者最终没有找到要找的元素。
这就是简单的二分查找思想
在这里插入图片描述
时间复杂度:
O(logn)
代码实现

int Binary_Search(int*a,int n,int key)
{
    
    int low,high,mid;
    low=1;
    high=n;
    while(low<=high)
    {
    
        mid=(low+high)/2;
        if(a[mid]>key)
        {
    
            high=mid-1;
        }
        else if(a[mid]<key)
        {
    
            low=mid+1;
        }
        else
        return mid;
    }
    return 0;
}

插值查找算法

在前面的二分查找中,mid=(1/2)*(low+high)

这个式子可以化为 mid=(low+high)/2=low+(1/2)*(high-low)

现在,我们对(high-low)前面的系数进行改进

改为 (key-a[low])/(a[high]-a[low]),为什么呢,认真思考你会发现,这样计算会使mid的值更接近目标值key的下标,这样就可在二分查找算法的基础上进一步优化查找过程

插值查找是根据要查找的关键字Key与查找表中最大最小记录的关键字比较后的查找方法,其核心是差值计算公式(key-a[low])/(a[high]-a[low])

代码实现:

int Interpolation_Search(int*a,int n,int key)
{
    
    int low,high,mid;
    low=1;
    high=n;
    while(low<=high)
    {
    
        mid=low+(key-a[low])/(a[high]-a[low])*(high-low);
        if(key>a[mid])
        {
    
            low=mid+1;
        }
        else if(key<a[mid])
        {
    
            high=mid-1;
        }
        else
        return mid;
    }
    return 0;
}

时间复杂度:
O(logn)

斐波那契查找

实现前提:有一组斐波那契数组
斐波那契查找原理:与前两种相似,仅仅改变了中间节点(mid)的位置,mid不再是中间或插值得到的
而是位于黄金分割点附近,即mid=low+F(k-1)-1
推导:
由斐波那契数列的性质得 F[k]=F[k-1]+F[k-2],然后进一步推到可以得到,
(F[k]-1)=(F[k-1]-1)+(F[k-2]-1)+1;
上面式子很好推导
再结合下面的图,可以推出 mid=low+F(k-1)-1时,mid就处于黄金分割点

在这里插入图片描述
但顺序表长度n不一定刚好等于F[k]-1,所以需要将原来的顺序表长度n增加至F[k]-1,这里的k只要能使
F[k]-1恰好大于或等于n即可。
即:

 while(n>F[k]-1)
        k++;

代码实现:

int Fib_Search(int*a,int n,int key)
{
    
    int low,high,mid,i,k;
    low=1;
    high=n;
    k=0;
    while(n>F[k]-1)
        k++;
    for(i=n;i<F[k]-1;i++)
        a[i]=a[n];      //将不满的数值补全,按数组最后元素去补
    while(low<=high)
    {
    
        mid=low+F[k-1]-1;
        if(key<a[mid]) //在数组前面找
        {
    
            high=mid-1;
            k=k-1;
                     //1.全部元素 = 前面元素 + 后面元素
                  //2.前面元素有F[k-1]个,F[k] = F[k-1] + F[k-2]
                  //3.F[k-1] = F[k-2] + F[k-3]
                  //即在F[k-1]前面继续查找
                  //所以k=k-1
        }
        else if(key>a[mid])  //在数组后面找
        {
    
            low=mid+1;
            k=k-2;
                  //1.全部元素 = 前面元素 + 后面元素
                  //2.F[k] = F[k-1] + F[k-2]
                  //3.后面元素有F[k-2]个,F[k-2]=F[k-3] + F[k-4]
                  //即在F[k-2]后面继续查找
                  //所以k=k-2
        }
        else
        {
    
            if(mid<=n)
                 return mid;
            else
                return n;
        }
    }
    return 0;

}

时间复杂度:
O(logn)

相关文章
|
3月前
|
Java 关系型数据库 MySQL
Docker技术解析
本文详细介绍了Docker的安装配置、常用命令、数据卷管理、自定义镜像制作以及多容器项目部署方法。主要内容包括:1. Docker安装步骤,包括卸载旧版本、配置镜像源、安装最新版本;2. 常用Docker命令解析,如镜像操作、容器管理等;3. 数据卷的概念和使用方法,实现宿主机与容器目录的映射;4. 自定义镜像制作流程,通过Dockerfile文件定义镜像结构;5. 容器网络配置,实现容器间的互联互通;6. 使用Docker Compose编排多容器项目,简化部署流程。文章通过Nginx和MySQL等实例演
|
弹性计算 安全
停止使用云服务通常需要遵循以下步骤
停止使用云服务通常需要遵循以下步骤
1114 2
|
移动开发 前端开发 JavaScript
2024年前端框架趋势概览
【10月更文挑战第2天】本文综合了多个来源的信息,以提供一个全面的2024年前端框架趋势概览。希望通过本文,读者能够把握前端开发的最新动态,并在自己的项目中应用这些趋势。
|
关系型数据库 数据库 PostgreSQL
【一文搞懂PGSQL】1.简述和安装
PostgreSQL(简称PG或PGSQL)是一款使用C和C++语言开发的开源关系型数据库管理系统。其官网为 [www.postgresql.org](https://www.postgresql.org/),中文社区为 [www.postgres.cn](http://www.postgres.cn)。PG采用了多层逻辑结构:第一层为实例,第二层为数据库(每个实例下可有多个相互独立的数据库),第三层为Schema(每个数据库下包含多个Schema)。每个Schema下可以创建表、视图、索引、函数等数据库对象。
|
前端开发 JavaScript 数据库
Web的B/S架构
Web的B/S架构
2348 1
|
小程序 算法 API
小程序微信支付API?小程序获取手机号?
小程序微信支付API?小程序获取手机号?
341 0
|
Ubuntu Shell 应用服务中间件
Docker之 - 使用镜像和仓库(二)
上一篇文章中,我们学习了包括 docker run 在内的许多对容器进行操作的基本指令,那么在本节中,我们主要探讨 Docker 镜像的一些概念,比如什么是镜像,如何对镜像进行管理,如何修改镜像,如何创建、存储、共享自己创建的镜像等,那么就开始我们的学习
179 0
Docker之 - 使用镜像和仓库(二)
|
存储 负载均衡 数据安全/隐私保护
zookeeper工作原理以及基础概念
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它是一个为分布式应用提供一致性服务的软件,提供的功能包括:数据发布/发布、负载均衡、配置维护、域名服务、分布式同步、组服务等。而我们为何选择zookeeper,因为Zookeeper具有以下特性:
359 0
zookeeper工作原理以及基础概念
|
算法 数据可视化 数据挖掘
数据分析入门系列教程-决策树原理
今天我们一起来学习决策树,那么什么是决策树呢,其实在生活中,我们无时无刻不在使用它。
数据分析入门系列教程-决策树原理

热门文章

最新文章