【C语言】二分查找(详解)

🎥 岁月失语唯石能言的个人主页        

🔥个人栏专:秒懂C语言

若在许我少年时,一两黄金一两风    


一、二分查找的思路 

       二分查找是一种高效的查找算法,尤其适用于有序数组。它的基本思想是通过将查找区间逐步缩小一半,从而快速定位目标元素。对于大型数据集,二分查找的效率远高于线性查找。然而,它要求数据必须有序,且实现相对复杂一些。总的来说,二分查找是一种非常实用和强大的工具,在许多场景下都能发挥出其独特的优势。

   举个例子:

        朋友让你猜他刚买的一件衣服的价格,告诉你在(0~100)元之间。

        我们一般都是先猜中间价位50元,他说猜低了,你再猜75元,这样一步步的缩减范围。直到锁定86元。你只要用几次二分查找就能找到价格。而你要是从一开始猜你得猜86次,速度和效率提升非常大。


二、思路分析

例子:        int arr[] = {1,2,3,4,5,6,7,8,9,10};

首先题目会给你一个有序数组,让你找出某个数字比如说7的下标.

2.1定义变量

  • 首先我们定义lift,right,key,mid四个变量。left的下标为0;right的下标用sizeof(arr)/sizeof(arr[0])-1   (整个数组的大小)/(一个数组元素的大小)-1   因为数组的下标是从0开始所以要减1。
  • mid = (left + right) / 2;
    如果left和right比较大的时候可能会越界,这时候可以改良一下:
  • mid = left+(right-left)/2;

2.2逻辑分析

  • 然后我们需要拿arr[mid](50元)key去比较大小然后不断缩小范围。
  • 如果arr[mid] == key那就说明找到了,直接打印。
  • 如果arr[mid] > key说明你猜大了那你就要缩小范围1~100就要改成1~49(因为50比价格贵不需要取50元)所以right下标就要改成mid-1
  • 同理,如果arr[mid] < key说明你猜小了那你就要缩小范围1~100就要改成51~100,left的下标改成mid+1
  • 当然有人会担心mid = (left + right) / 2(left + right)是奇数除出来不是整数怎么办。/ 符号位会自动舍掉余数不用当心。
if (arr[mid] == key)
{
	printf("找到了,下标是%d\n", mid);
	break;
}
if (arr[mid] > key)
{
	right = mid - 1;
}
if (arr[mid] < key)
{
	left = mid + 1;
}
  • 然后在使用while循环来实现不断猜数字的过程
  • while的条件就设置成left <= right,只要范围内还有数字就继续排查直到找出,例如3~5,直到找到只剩5~5,找到5。
  • 或者全都找完了还找不到,这时候leftright会继续加减。这时left 就会大于 right,就打印找不到。
while (left <= right)
{
	mid = (left + right) / 2;

	if (arr[mid] == key)
	{
		printf("找到了,下标是%d\n", mid);
		break;
	}
	if (arr[mid] > key)
	{
		right = mid - 1;
	}
	if (arr[mid] < key)
	{
		left = mid + 1;
	}
	
}
if (left > right)
	printf("找不到\n");
return 0;

同理,如果是降序数组的话只需要把 right = mid - 1;和 left = mid + 1;交换位置就行:


三、代码实现

这是升序的代码:

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;
	int right = sizeof(arr) / sizeof(arr[0]) - 1;
	int key = 7;//要找的数字
	int mid = 0;//记录中间元素的下标
	while (left <= right)
	{
		mid = (left + right) / 2;

		if (arr[mid] == key)
		{
			printf("找到了,下标是%d\n", mid);
			break;
		}
		if (arr[mid] > key)
		{
			right = mid - 1;
		}
		if (arr[mid] < key)
		{
			left = mid + 1;
		}
		
	}
	if (left > right)
		printf("找不到\n");
	return 0;
}

这是降序代码:

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;
	int right = sizeof(arr) / sizeof(arr[0]) - 1;
	int key = 7;//要找的数字
	int mid = 0;//记录中间元素的下标
	while (left <= right)
	{
		mid = (left + right) / 2;

		if (arr[mid] == key)
		{
			printf("找到了,下标是%d\n", mid);
			break;
		}
		if (arr[mid] > key)
		{
			left = mid + 1;
		}
		if (arr[mid] < key)
		{
			right = mid - 1;
		}

	}
	if (left > right)
		printf("找不到\n");
	return 0;
}

往期文章推荐:

C语言如何生成随机数以及设置随机数的范围。(超详细):http://t.csdnimg.cn/62LIP

【C语言】函数调用及创建,并将数组传参到函数:http://t.csdnimg.cn/cU9Ku

【C语言】——函数递归,用递归简化并实现复杂问题:http://t.csdnimg.cn/nsS4d


总结

以上就是关于二分查找的相关知识,二分查找虽然性能比较优秀,但应用场景也比较有限,底层必须依赖数组,并且还要求数据是有序的。所以我们在选用算法时需要从多方面考虑。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows更改远程桌面端口并添加防火墙入站规则

1.运行 快捷键winR组合键&#xff0c;win就是键盘上的windows系统图标键。 2.打开注册表 Regedit&#xff0c;在对话框中输入regedit命令&#xff0c;然后回车 3.打开注册表&#xff0c;输入命令后&#xff0c;会打开系统的注册表&#xff0c;左边是目录栏&#xff0c;右边是…

什么是MVCC?看看它的实现原理

大家好&#xff0c;我是归思君~ 之前在讲 MySQL 事务隔离性提到过&#xff0c;对于写操作给读操作的影响这种情形下发生的脏读、不可重复读、虚读问题&#xff0c;是通过MVCC 机制来进行解决的&#xff0c;那么MVCC到底是如何实现的&#xff0c;其内部原理是怎样的呢&#xff1…

Idea执行bat使用maven打包springboot项目成docker镜像并push到Harbor

如果执行以下命令失败&#xff0c;先把mvn的-q参数去掉&#xff0c;让错误输出到控制台。 《idea配置优化、Maven配置镜像、并行构建加速打包、解决maven打包时偶尔几个文件没权限的问题》下面的使用company-repo私有仓库和阿里云镜像仓库同时使用的配置参考。 bat echo off …

四六级高频词组10

目录 词组 其他链接 词组 401. instead of &#xff08;in place of&#xff09; 代替&#xff0c;而不是… 402. instruct…in &#xff08;teach&#xff09; 教。指导。训练某人… 403. insure…for 把…保险&#xff08;多少钱&#xff09;&#xff1b; ensure 使安全…

状态码及常用注解

状态码 1.200 请求成功 2.404 请求资源不存在 检查请求路径 3.400 表示请求参数不合法(页面上参数的key和controller方法参数名字不一致、传的参数数量不对应) 4.405 表示请求方式与接收方式不匹配 5.500 程序报错检查java代码和控制台日志 6.403 表示没有权限访问 MVC常…

web网络安全

web安全 一&#xff0c;xss 跨站脚本攻击(全称Cross Site Scripting,为和CSS&#xff08;层叠样式表&#xff09;区分&#xff0c;简称为XSS)是指恶意攻击者在Web页面中插入恶意javascript代码&#xff08;也可能包含html代码&#xff09;&#xff0c;当用户浏览网页之时&…

国际语音通知系统有哪些应用场景?

国际语音通知系统操作简单、安全性高、实用性强&#xff0c;可广泛应用于国际航空、国际银行、出海游戏、跨国旅游、跨国金融等行业。 1.会议通知 企业人事管理人员使用语音通知的方式&#xff0c;快速通知参会人员。 2.订单通知 企业通过语音通知向客户发送订单确认通知&a…

RCE漏洞基础及CTF绕过

1.漏洞成因 可以对系统命令执行函数和调用代码函数传递的值进行控制。 2.系统执行命令函数 system() exec() exec会执行系统命令&#xff0c;保存回显最后一行而且单exec不输出结果 shell_exec() 不会输出结果&#xff0c;保存所有回显 passthru() 和system一样 popen() …

STM32F407-14.3.2-03 中心对齐模式

中心对齐模式&#xff08;递增/递减计数&#xff09; 在中心对齐模式下&#xff0c;计数器从 0 开始计数到自动重载值&#xff08;TIMx_ARR 寄存器的内容&#xff09;— 1&#xff0c;生成计数器上溢事件&#xff1b;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之…

LLM(七)| Mamba:LLM新架构的浅探

目前大型语言模型&#xff08;LLM&#xff09;领域发展如火如荼&#xff0c;本文将重点探索在单个消费级GPU上可以有效运行的小型模型&#xff08;≤7B个参数&#xff09;。 我们将从以下几个方面重点介绍基于新架构的语言模型&#xff1a;&#x1f40d;Mamba模型&#xff08;h…

HTTP 302错误:临时重定向

在Web开发中&#xff0c;HTTP状态码是用于表示Web服务器响应的各种状态。其中&#xff0c;HTTP 302错误表示临时重定向&#xff0c;这意味着请求的资源已被临时移动到其他位置&#xff0c;并且服务器已经提供了新的URL&#xff0c;以便客户端可以重新发送请求。 了解HTTP 302错…

「Verilog学习笔记」RAM的简单实现

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1ns module ram_mod(input clk,input rst_n,input write_en,input [7:0]write_addr,input [3:0]write_data,input read_en,input [7:0]read_addr,output reg…

2023PCTF Double_SS

记录一下 ssrf配合 ssti的结合 首先开启环境 明显的ssrf 让我们访问 5555端口 使用http协议访问 url127.0.0.1:5555 告诉我们去访问 name 并且给我们key url127.0.0.1:5555/name 出现报错 说我们不是admin 然后我们往下看 我们使用file协议读取app/app.py urlfile:///app…

基于ssm的汽车服务商城系统设计与实现论文

摘 要 本课题是根据用户的需要以及网络的优势建立的一个基于Vue的汽车服务商城系统&#xff0c;来更好的为用户提供服务。 本基于Vue的汽车服务商城系统应用Java技术&#xff0c;MYSQL数据库存储数据&#xff0c;基于SSMVue框架开发。在网站的整个开发过程中&#xff0c;首先对…

Python自动化:selenium常用方法总结

使用的Python版本为3.8&#xff0c;selenium版本为4.15.2 Python自动化:selenium常用方法总结 1. 三种等待方式2. 浏览器操作3. 8种查找元素的方法4. 高级事件 1. 三种等待方式 强制等待 使用模块time下的sleep()实现等待效果隐式等待 使用driver.implicitly_wait()方法&#…

大数据云计算——使用Prometheus-Operator进行K8s集群监控

大数据云计算——使用Prometheus-Operator进行K8s集群监控 一、 背景 在非operator配置的普罗中我们监控k8s集群都是通过配置configmap进行服务发现和指标拉取。切换到prometheus-operator难免会有些使用问题。不少用户已经习惯底层配置自动发现的方式。当过渡到servicemonit…

【docker】常用命令

启动docker服务 systemctl start docker 停止docker服务 systemctl stop docker 重启docker服务 systemctl restart docker 查看docker服务状态 systemctl status docker 设置开机启动docker服务 systemctl enable docker 设置关闭开机启动docker服务 systemctl disable …

Excel实现字母+数字拖拉自动递增,步长可更改

目录 1、带有字母的数字序列自增加&#xff08;步长可变&#xff09; 2、仅字母自增加 3、字母数字同时自增 1、带有字母的数字序列自增加&#xff08;步长可变&#xff09; 使用Excel通常可以直接通过拖拉的方式&#xff0c;实现自增数字&#xf…

02基于matlab的卡尔曼滤波

基于matlab的卡尔曼滤波&#xff0c;可更改状态转移方程&#xff0c;控制输入&#xff0c;观测方程&#xff0c;设置生成的信号的噪声标准差&#xff0c;设置状态转移方差Q和观测方差R等参数&#xff0c;程序已调通&#xff0c;需要直接拍下。

luttuce(RedisTempate)实现hash expire lua脚本

话不多说先放脚本&#xff1a; local argv ARGV local length #argv if length > 0 then local unpackArgs {} for i 1, length - 1 dotable.insert(unpackArgs, argv[i]) end if redis.call(exists, KEYS[1]) 1 thenredis.call(del, KEYS[1])redis.call(hset, KEYS[…