理解折半查找法

理解折半查找法:高效的查找算法

在这里插入图片描述

折半查找法(又称二分查找法)是一种高效的查找算法,用于查找一个已排序数组中的目标元素。与线性查找方法不同,折半查找每次都将搜索范围减半,从而大幅提升查找效率。本文将详细分析折半查找的工作原理,并以查找目标值 13 为例进行内存分析。

折半查找法的基本原理

折半查找法基于这样一个假设:目标数据已经排好序。该算法通过不断地将查找范围一分为二,逐步缩小查找范围,从而在较短的时间内找到目标元素。具体步骤如下:

  1. 初始化:设定一个查找范围,包括 leftright,分别代表数组的起始索引和结束索引。
  2. 计算中间元素:每次计算中间元素的位置,mid = left + (right - left) / 2,并与目标值进行比较。
  3. 缩小查找范围
    • 如果目标值等于中间元素,返回该元素的索引。
    • 如果目标值小于中间元素,说明目标值在左半部分,将 right 设置为 mid - 1
    • 如果目标值大于中间元素,说明目标值在右半部分,将 left 设置为 mid + 1
  4. 循环:重复上述步骤,直到找到目标元素或查找范围为空(left > right)。

折半查找法的时间复杂度

折半查找的时间复杂度是 (O(\log n)),其中 n 是数组的大小。每次比较都会将查找范围减半,因此不需要遍历整个数组。相比于线性查找的 (O(n)),折半查找法的效率要高得多,尤其是在数据量较大的情况下。

源代码实现

下面是实现折半查找的 C++ 代码:

#include <iostream>
using namespace std;// 折半查找函数,返回目标值的索引,找不到返回 -1
int binarySearch(int arr[], int size, int target) {int left = 0;int right = size - 1;while (left <= right) {int mid = left + (right - left) / 2; // 防止溢出// 检查中间元素是否是目标值if (arr[mid] == target) {return mid; // 找到目标,返回索引}// 如果目标值小于中间元素,缩小右边界else if (arr[mid] > target) {right = mid - 1;}// 如果目标值大于中间元素,缩小左边界else {left = mid + 1;}}return -1; // 目标值不在数组中
}int main() {int arr[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; // 必须是有序数组int size = sizeof(arr) / sizeof(arr[0]);int target;cout << "Enter the number to search: ";cin >> target;int result = binarySearch(arr, size, target);if (result != -1) {cout << "Found " << target << " at index " << result << endl;} else {cout << target << " is not in the array." << endl;}return 0;
}

以查找目标值 13 为例

假设我们有一个有序数组 arr[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19},并且我们的目标值是 13,我们将在数组中查找目标值。

初始设置:

  • 数组 arr[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
  • 目标值 target = 13
  • 数组大小 size = 10,即 arr 的长度。
  • 初始值:left = 0right = 9

1. 第一次迭代

  • left = 0, right = 9
  • 计算中间索引 mid = 0 + (9 - 0) / 2 = 4,即 mid = 4
  • 访问 arr[mid],即 arr[4] = 9

比较 arr[mid] 与目标值 target

  • arr[mid] = 9,目标值 13 大于 9,因此目标值在右侧。

更新 left = mid + 1 = 4 + 1 = 5,新的查找区间是 [5, 9]

2. 第二次迭代

  • left = 5, right = 9
  • 计算中间索引 mid = 5 + (9 - 5) / 2 = 7,即 mid = 7
  • 访问 arr[mid],即 arr[7] = 15

比较 arr[mid] 与目标值 target

  • arr[mid] = 15,目标值 13 小于 15,因此目标值在左侧。

更新 right = mid - 1 = 7 - 1 = 6,新的查找区间是 [5, 6]

3. 第三次迭代

  • left = 5, right = 6
  • 计算中间索引 mid = 5 + (6 - 5) / 2 = 5,即 mid = 5
  • 访问 arr[mid],即 arr[5] = 11

比较 arr[mid] 与目标值 target

  • arr[mid] = 11,目标值 13 大于 11,因此目标值在右侧。

更新 left = mid + 1 = 5 + 1 = 6,新的查找区间是 [6, 6]

4. 第四次迭代

  • left = 6, right = 6
  • 计算中间索引 mid = 6 + (6 - 6) / 2 = 6,即 mid = 6
  • 访问 arr[mid],即 arr[6] = 13

比较 arr[mid] 与目标值 target

  • arr[mid] = 13,目标值 13 相等,查找成功。

返回索引 6,即目标值 13 的位置。

内存分析

每次迭代,程序都会读取 arr[mid] 并进行比较。内存访问是按需进行的,程序仅读取当前中间位置的值,而不是遍历整个数组。每次查找范围缩小后,leftright 指针更新,从而减少了对内存的访问。通过每次将查找范围缩小一半,折半查找能够快速找到目标值,避免了不必要的内存读取。

总结

折半查找法通过每次将查找范围缩小一半,显著提高了查找效率。在有序数组中,我们能够在 (O(\log n)) 的时间复杂度内查找到目标元素。每次对数组元素的访问都是必要的,避免了线性查找中的不必要访问,使得内存访问更加高效。对于大规模数据集,折半查找法是一种理想的查找方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/61634.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决前端页面报错:Not allowed to load local resource

在前后端分离项目中&#xff0c;在前端页面里使用file://的绝对路径访问本地图片&#xff0c;在加载图片的 时候会报出Not allowed to load local resource 的错误。 这是因为浏览器出于安全因素&#xff0c;禁止通过绝对路径访问图片&#xff0c;需要通过虚拟路径进行访问。 …

VM虚拟机装MAC后无法联网,如何解决?

✨在vm虚拟机上&#xff0c;给虚拟机MacOS设置网络适配器。选择NAT模式用于共享主机的IP地址 ✨在MacOS设置中设置网络 以太网 使用DHCP ✨回到本地电脑上&#xff0c;打开 服务&#xff0c;找到VMware DHCP和VMware NAT&#xff0c;把这两个服务打开&#xff0c;专一般问题就…

力扣 LeetCode 236. 二叉树的最近公共祖先(Day10:二叉树)

解题思路&#xff1a; 后序遍历 注意&#xff1a; p和q其中一个就是它们的公共祖先的情况也考虑到了&#xff0c;假设q是公共祖先&#xff0c;遇到q就直接返回&#xff0c;相当于是下面一边为空&#xff0c;一边不为空的情况&#xff0c;返回不为空就一边即可 class Solutio…

前端速通(HTML)

1. HTML HTML基础&#xff1a; 什么是HTML&#xff1f; 超文本&#xff1a; "超文本"是指通过链接连接不同网页或资源的能力。HTML支持通过<a>标签创建超链接&#xff0c;方便用户从一个页面跳转到另一个页面。 标记语言&#xff1a; HTML使用一组预定义的标签…

python语言基础-5 进阶语法-5.4 正则表达式

声明&#xff1a;本内容非盈利性质&#xff0c;也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站&#xff0c;会尽量附上原文链接&#xff0c;并鼓励大家看原文。侵删。 5.4 正则表达式 5.4.1 正则表达式 正则表达式的概念&#xff1a; 正则表达式是用来…

论文阅读——Performance Evaluation of Passive Tag to Tag Communications(一)

文章目录 摘要一、互耦对监听器标签输入阻抗的影响A. 无限细偶极子互阻抗的理论研究B. 电细偶极子的情况&#xff1a;理论与模拟C. 印刷偶极子的情况&#xff1a;电磁模拟与测量 二、T2T 通信系统的性能评估总结 论文来源&#xff1a;https://ieeexplore.ieee.org/document/970…

Palo Alto Networks PAN-OS身份认证绕过漏洞复现(CVE-2024-0012)

0x01 产品描述: PAN-OS 是运行 Palo Alto Networks 下一代防火墙的软件。通过利用 PAN-OS 本机内置的关键技术(App-ID、Content-ID、设备 ID 和用户 ID),可以在任何时间、任何地点完全了解和控制所有用户和设备中正在使用的应用程序。0x02 漏洞描述: PAN-OS 设备管理 Web …

使用ENSP实现静态路由

一、双路由器静态路由 1.项目拓扑 2.项目实现 (1)路由器AR1配置 进入系统试图 sys将路由器命名为R1 sysname R1进入g0/0/0接口 int g0/0/0将g0/0/0接口IP地址配置为1.1.1.1/24 ip address 1.1.1.1 24进入g0/0/1接口 int g0/0/1将g0/0/1接口IP地址配置为192.168.1.1/24 ip ad…

版本控制和idea简体中文教程

版本控制是一种管理软件开发过程中代码变更的技术。它允许多个开发者协作编辑同一个项目&#xff0c;同时跟踪每个变更的历史记录&#xff0c;以便在需要时恢复到之前的版本。版本控制系统&#xff08;Version Control System, VCS&#xff09;是实现版本控制的具体工具。 16.…

自制游戏:监狱逃亡

第一个游戏&#xff0c;不喜勿喷&#xff1a; #include<bits/stdc.h> #include<windows.h> using namespace std; int xz; int ruond_1(int n){if(xz1){printf("撬开了&#xff0c;但站在你面前的是俄罗斯内务部特种部队的奥摩大帝&#xff0c;你被九把加特…

Claude3.5-Sonnet和GPT-4o怎么选(附使用链接)

随着人工智能模型的不断进化&#xff0c;传统的评估标准已经逐渐变得陈旧和不再适用。以经典的“喝水测试”为例&#xff0c;过去广泛应用于检测模型能力&#xff0c;但现如今即便是国内的一些先进模型&#xff0c;也能够轻松答对这些简单的问题。因此&#xff0c;我们亟需引入…

uniapp+vue3+ts H5端使用Quill富文本插件以及解决上传图片反显的问题

uniappvue3ts H5端使用Quill富文本插件以及解决上传图片反显的问题 1.在项目中安装Quill npm i quill1.3.72.需要显示富文本的页面完整代码 <template><view><div ref"quillEditor" style"height: 65vh"></div></view> &…

QML —— 3种等待指示控件(附源码)

效果如下 说明 BusyIndicator应用于指示在加载内容或UI被阻止等待资源可用时的活动。BusyIndicator类似于一个不确定的ProgressBar。两者都可以用来指示背景活动。主要区别在于视觉效果,ProgressBar还可以显示具体的进度(当可以确定时)。由于视觉差异,繁忙指示器和不确定的…

数字后端零基础入门系列 | Innovus零基础LAB学习Day11(Function ECO流程)

###LAB 20 Engineering Change Orders (ECO) 这个章节的学习目标是学习数字IC后端实现innovus中的一种做function eco的flow。对于初学者&#xff0c;如果前面的lab还没掌握好的&#xff0c;可以直接跳过这节内容。有时间的同学&#xff0c;可以熟悉掌握下这个flow。 数字后端…

Swift从0开始学习 协议和扩展 day5

协议:定义行为的契约 协议类似于其他语言中的接口。它们定义了一组方法、属性或其他需求,供结构体、类、枚举等类型去遵循和实现。协议并不实现这些需求,而是作为一种约定或合同,确保实现协议的类型会遵循特定的行为。 协议的定义和遵循 在 Swift 中,使用 protocol 关键…

R语言绘图过程中遇到图例的图块中出现字符“a“的解决方法

R语言绘图过程中遇到图例的图块中出现字符的解决方法 因为我遇到这个问题的时候没在网上找到合适的方法&#xff0c;找到个需要付费的&#xff0c;算了。也许是因为问的方式不同&#xff0c;问了半天AI也回答出来&#xff0c;莫名有些烦躁&#xff0c;打算对代码做个分析&…

云服务器部署WebSocket项目

WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;其设计的目的是在Web浏览器和Web服务器之间进行实时通信&#xff08;实时Web&#xff09; WebSocket协议的优点包括&#xff1a; 1. 更高效的网络利用率&#xff1a;与HTTP相比&#xff0c;WebSocket的握手只…

二十:HTML Form表单提交时的协议格式

在Web开发中,HTML表单(form)是与用户交互的一个重要组件,常用于收集用户输入并将数据发送到服务器进行处理。HTML表单的提交是通过HTTP协议进行的,而表单的提交格式是由表单的method、action、enctype等属性决定的。在本文中,我们将详细探讨HTML表单在提交数据时的协议格…

数字反向输出

数字反向输出 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 小明听到广播里的数字后&#xff0c;总喜欢反着念给妈妈听。请聪明的你将小明听到的数字反向输出。 输入 输入为一个整型的四位数n 输出 …

libigl 邻接矩阵

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 libigl使用一种邻接矩阵来描述各个点之间的关系,这样做非常的直观,方便使用。 二、实现代码 #include <Eigen/Core> #include <Eigen/Geometry> #include <igl/read_triangle_mesh.h>