查找-之有序表查找

简介: 待查找的表是有序排列的

待查找的表是有序排列

解决的方法1:

折半查找/二分法查找

其中线性表采用的是顺序存储

//C
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(key<a[mid])//待查的数小于中间的值,说明数据在待查表的左边
     high=mid-1;
  else if(key>a[mid])//待查的数大于中间的值,说明数据在待查表的右边
     low=mid+1;
  else
     return mid
 }
return 0;
}

算法复杂度分析

时间复杂度:O(log(n))  每次划分为一半 故 2^x=n  则x=log2(n)

空间复杂度:O(1)

解决的方法2:

插值查找

二分法查找mid=(low+high)/2=low+1/2(high-low)

其中的1/2修改为(key-a[low])/(a[high]-a[low])

mid=low+(key-a[low])/(a[high]-a[low])(high-low)

依据查找的关键字key和查找表中最大最小关键字比较后的查找方法

表长较大,关键字分布比较均匀的查找表,效果比二分法好

解决方法3:

斐波那契查找

斐波那契数列

e606f6fc3a4a7445ab08210b2cc64465_20200201133313267.png

采用了黄金分割点而不是一分为二

斐波那契数列 F={0,1,1,2,3,5,8,13,21,...........}

578eac1a10c8e5a7b50ad71149086ef3_20200201133416515.png

a为待查找的数组,例如:a={0,1,16,24,35,47,59,62,73,88,99}

                                     n=10为数组的长度

假设查找的key=59

ee33f0caa00d2902694c6249e6586bd3_20200201133407203.png

步骤:

1)边界确定

2)待查数组按照斐波那契数列扩充

3)循环的判断为low<=high

其中的high为原来的待查数组长度,为什么不是扩充后的长度,原因是扩充后的值都是重复原来待查数组的末尾值,在low>n之前已经找到查找的值,否则找不到

那么扩充待查数组长度的目的是:防止查找后半部分的数时没有值

4)查找过程

待查数组:元素F(k)-1个,因为已经从原来的n个扩充为F(k)-1个

分割点划分:

由斐波那契数列的特性:F[k]=F[k-1]+F[k-2],构建如下的划分

4e6f1d695ce3af09283b8312011fbc05_20200201133416609.png

这张图里的high是扩充的F(k)-1而不是n

//C
/*构造一个斐波那契数组*/
void Fibonacci(int * F)
{
F[0]=0;
F[1]=1;
for(int i=2;i<max_size;++i)
F[i]=F[i-1]+F[i-2];
}
int Fibonacci_Search(int *a, int n, int key)
 {
int low, high,mid,i,k;
low=1;//左边界
high=n;//右边界
int F[n];
Fibonacci(F);//构造一个斐波那契数组F
k=0;
while(n>F[k]-1)//计算n位于斐波那契数列的位置 
    k++;
for(i=n;i<F[k]-1;i++)//将待查数组长度不满(斐波那契数列中对应值--长度)的数值部分补全  ,也即是在a数组的尾部拷贝补充到指定F[k]-1长度
    a[i]=a[n];
while(low<=high)
{
  mid=low+F[k-1]-1;//计算当前分隔的下标
  if(key<a[mid])//若查找记录小于当前分隔记录,说明key在待查数组的前半部分
    {
     high=mid-1;//最高下标调整到分隔下标mid-1处
     k=k-1;//斐波那契数列的下标减1位
    }
  else if(key>a[mid])//若查找记录大于当前分隔记录,说明key在待查数组的后半部分
   {
    low=mid+1;
    k=k-2;
   }
 else
   {
      if(mid<=n)//若相等且小于长度n则说明mid为查找到的位置
         return mid;
     else//若mid>n说明是补全数值,返回待查数组的末尾的第一个数字索引n
       return n ;
   }
 }
return -1;
}

时间复杂度: O(logn)

空间复杂度: O(n)  斐波那契数列的创建

可参考:

斐波那契查找原理详解与实现https://www.cnblogs.com/bethunebtj/p/4839576.html

《大话数据结构》

目录
相关文章
|
安全 API
sip账号如何对接手机使用?
这里所说的线路对接,指的是电销线路对接 就是用户方如果有自己的系统,想要在外面找线路商对接一个电销线路到自己的系统里。只使用线路商的线路,系统还是自己的。这种一般就是线路对接。
|
存储 缓存 编解码
阿里云服务器2核8G、4核16G、8核32G选择经济型、通用算力型和计算型实例参考
如果我们计划购买的云服务器配置是2核8G、4核16G、8核32G配置,在阿里云目前的活动中,可选的实例规格有经济型e、通用算力型u1、通用型g7、通用型g8y等几个实例规格可选,由于不同实例规格的性能和价格及适用场景不同,因此,有的新手用户可能不知道如何选择,本文为大家介绍在2核8G、4核16G、8核32G这三种配置下,经济型、通用算力型和通用型实例的选择问题,以供参考。
|
Linux C# 开发者
用Visual Basic打造桌面与移动应用:跨平台开发的探讨
【4月更文挑战第27天】本文探讨了Visual Basic在跨平台应用开发中的运用,从桌面应用到移动应用,包括使用.NET框架、Xamarin及Mono等工具。Visual Basic结合这些技术,能在Windows、Linux、macOS及移动操作系统上创建应用。开发者需考虑平台兼容性、性能优化和持续维护,通过案例研究和最佳实践,展现VB在多平台开发的潜力。随着工具的改进,Visual Basic在跨平台开发领域将持续发挥作用。
474 3
|
人工智能 自然语言处理 API
构建ChatPDF AI助手
本项目利用通义千问Qwen技术构建了一个ChatPDF AI助手,用户可上传PDF文件并基于文件内容进行对话。项目采用Python及多个库实现,包括Streamlit、OpenAI API、Transformers、Tiktoken等,支持高效、可定制的多语言对话,具备上下文理解能力和成本效益。示例代码展示了从环境配置到功能实现的完整流程,适合开发者快速上手。
|
XML 算法 数据可视化
我的Neo4j探索之旅 - 安装Apoc插件以及JAVA集成(二)
我的Neo4j探索之旅 - 安装Apoc插件以及JAVA集成(二)
1342 0
|
人工智能 监控 自动驾驶
物联网对 5G 的指标要求 | 带你读《5G时代的承载网》之九
未来移动互联网主要面向以人为主体的通信,注重提供更好的用户体验,进一步改变人类社会信息交互方式,为用户提供增强现实、虚拟现实、超高清视频、云端办公、休闲 娱乐等更加身临其境的极致业务体验。
物联网对 5G 的指标要求  | 带你读《5G时代的承载网》之九
|
NoSQL 应用服务中间件 nginx
Docker容器化技术实战操作汇总(附开发环境搭建)
docker是什么: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
964 0
Docker容器化技术实战操作汇总(附开发环境搭建)
|
传感器 移动开发 前端开发
从《淘特斗地主》说起,前端如何做 h5 游戏的游戏体验
从《淘特斗地主》说起,前端如何做 h5 游戏的游戏体验
1309 1
从《淘特斗地主》说起,前端如何做 h5 游戏的游戏体验
|
前端开发 JavaScript 网络协议
Vue中 使用 WebSocket
Vue中 使用 WebSocket
672 0
Vue中 使用 WebSocket
|
网络架构
【eNSP 华为模拟器】静态路由小实验
【eNSP 华为模拟器】静态路由小实验
591 0
【eNSP 华为模拟器】静态路由小实验