二分查找 vs. N分查找

简介: 二分查找三分查找算法分析

二分查找


     二分查找(Binary Search)又称折半查找,是一种高效率的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。


二分查找原理


      满足表中元素有序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成两个子表,根据中间关键字和查找关键字的关系在子表中查找,重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。


二分查找分析


优点: 比较次数少,查找速度快,平均性能好。

缺点: 要求待查表为有序表,且插入删除困难。

 适用范围: 不经常变动而查找频繁的有序列表。

 时间复杂度: O( log ⁡ 2 N )



代码实现


/ C++
int binarySearch(vector<int>& nums, int target) {
  int mid;  // 中间位置 
  int left = 0;  // 左边界 
  int right = nums.size() - 1;  // 右边界 
  while (left <= right) { // 折半查找 
  mid = left + (right - left) / 2;  // 计算中间位置 
  if (nums[mid] == target) {  // 与中间位置元素比较 
    return mid;  // 查找成功,返回位置信息 
  } else if (target < nums[mid]) {  // 小于中间位置元素 
    right = mid - 1;  // 改变右边界  
  } else {  // 大于中间位置元素 
    left = mid + 1;  // 改变左边界 
  }
  }
  return -1;  // 查找失败返回-1 
}


三分查找

三分查找原理


 三分查找,类似于二分查找,区别在于利用两个中间位置记录,将表分为三个子表。


三分查找分析


 时间复杂度: O( log ⁡ 3 N )


代码实现

// C++
int trisectionSearch(vector<int>& nums, int target) {
    int midl;  // 靠左中间位置 
    int midr;  // 靠右中间位置
    int left = 0;  // 左边界
  int right = nums.size() - 1;  // 右边界 
    while (left <= right) {  // 三分查找 
      midl = left + (right - left) / 3;  // 计算靠左中间位置
      midr = right - (right - left) / 3;  // 计算靠右中间位置
      if (target < nums[midl]) {  // 小于靠左中间位置
    right = midl - 1;  // 改变右边界 
  } else if (target > nums[midr]) {  // 大于靠右中间位置  
    left = midr + 1;  // 改变左边界
  } else if (target != nums[midl] && target != nums[midr]) {  // 不等于左右中间位置
    left = midl + 1;  // 改变左边界
    right = midr - 1;  // 改变右边界 
  } else {  // 等于左或右中间位置 
    return nums[midl] == target ? midl : midr;  // 查找成功,返回位置信息 
  }
  }
    return -1;  // 查找失败返回-1
}


算法分析


由时间复杂度看,三分查找是不是优于二分查找呢?

     二分查找每次查询范围减少一半,需要查询的次数是 log ⁡ 2 N )。三分查找每次查询两个数字与目标数字比较,可以把查询范围缩小成原先的 1 / 3。查询次数就只有 log ⁡ 3 N )

N,一下子就优化了这么多,那如果是四分,五分,六分,七分,N分岂不是能无限优化。

     答案并非如此,因为二分法和三分法的渐进复杂度是一样的。



 

     log ⁡2 3 是个常数,因此对数函数的底对于算法的复杂度分析是没有意义的。

     因此,无论是二分法,三分法,四分法,N分法······复杂度都是一样的,分的越多,代码反而越复杂,得不偿失。

————————————————

版权声明:本文为CSDN博主「Acx7」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Acx77/article/details/117090545

相关文章
|
8月前
|
数据采集 自然语言处理 NoSQL
利用中间件实现任务去重与分发精细化:股吧舆情数据采集与分析实战
本项目针对东方财富股吧设计精细化采集方案,解决重复采集、调度混乱与反爬等问题,构建舆情分析数据模型。通过采集帖子内容、用户行为与情绪信号,实现情绪趋势可视化、热点识别与个股预警,助力把握市场风向。
381 0
利用中间件实现任务去重与分发精细化:股吧舆情数据采集与分析实战
|
11月前
联通骨干网如何从内循环走向全球化?
中国联通骨干网的发展历程堪称中国互联网基础设施建设的缩影。从承载2G/3G业务的B网起步,经由169网的国内“内循环”先锋阶段,到A网(CUII)的企业级服务高速公路,再到国际化的AS10099骨干网,形成当前“China169+CUII”的双网格局。这一布局实现了普通用户与企业需求的分离,确保服务质量的同时提升资源调配效率,为数字中国建设提供了坚实支撑。
410 0
联通骨干网如何从内循环走向全球化?
|
12月前
|
监控 算法 安全
公司电脑网络监控场景下 Python 广度优先搜索算法的深度剖析
在数字化办公时代,公司电脑网络监控至关重要。广度优先搜索(BFS)算法在构建网络拓扑、检测安全威胁和优化资源分配方面发挥重要作用。通过Python代码示例展示其应用流程,助力企业提升网络安全与效率。未来,更多创新算法将融入该领域,保障企业数字化发展。
261 10
|
机器学习/深度学习 人工智能 自然语言处理
AI如何预测体育比赛结果
AI预测体育比赛结果依赖于历史数据、球员表现、球队状态等多因素。通过数据收集与处理、机器学习模型(如回归分析、神经网络)、模拟与蒙特卡洛方法、实时数据分析及自然语言处理等技术,AI能识别影响比赛的关键模式,评估胜负概率,并结合统计学与优化算法不断调整预测,提升准确性。
|
前端开发 JavaScript API
前端Get请求能在body上传参吗
【10月更文挑战第11天】 在浏览器环境中,GET请求的body参数会被忽略,这是因为浏览器中的XHR和fetch实现限制了这一行为。而在Node.js服务端环境中,GET请求可以在body中传递参数,因为服务端请求库没有这样的限制。实际上,GET请求不带body是HTTP标准的一部分,但在某些场景下,为了遵循RESTful规范,可以考虑通过服务端转发或BFF模式来实现复杂的参数传递。
|
算法
递归算法实现二分查找
本文简要介绍了递归实现的二分查找算法,这是一种在有序列表中快速查找的策略。递归方法虽在实际应用中较少,但有助于理解递归思想,为学习数据结构中的树内容打下基础。文中提供了原版和递归版本的二分查找代码,并强调了递归算法中处理未找到情况的注意事项。此外,还提到了递归在解决复杂问题时的优势,并通过链接分享了一个关于递归实现素数判断的例子。
414 2
|
Java 编译器 测试技术
安谋科技(Arm China)刘庆川:借助Arm SIMD指令提升Java应用性能
2023年9月22日,系列课程收官的最后一节《借助Arm SIMD指令提升Java应用性能》正式上线,由安谋科技(Arm China)高级工程师刘庆川主讲,内容涵盖:SIMD 指令及 Java VM介绍、如何在 Java 应用中使用 SIMD 指令、Java Vector API在 倚天上的案例分析。本期节目在阿里云官网、阿里云微信视频号、阿里云钉钉视频号、InfoQ 官网、阿里云开发者微信视频号、阿里云创新中心直播平台 & 微信视频号同步播出,同时可以点击【https://developer.aliyun.com/topic/ecs-yitian】进入【倚天实例迁移课程官网】了解更多内容。
安谋科技(Arm China)刘庆川:借助Arm SIMD指令提升Java应用性能
|
编译器 C++
struct 和 typedef struct 区别和用法总结
struct 和 typedef struct 区别和用法总结
469 0
|
机器学习/深度学习 自然语言处理
自注意力机制(Self-Attention Mechanism)
自注意力机制(Self-Attention Mechanism)
1742 6
|
缓存 前端开发 搜索推荐
服务端渲染(SSR)与静态网站生成(SSG):Next.js入门
服务端渲染(SSR)与静态网站生成(SSG):Next.js入门
912 0