二分查找及详细注意事项

news2024/10/5 22:21:19

二分查找是很基础的一种算法

例题:

在一个有序数组中查找具体的某个数,如果找到了返回,这个数的下标。找不到的返回-1

其原理图如图所示

 因为是有序的数列,所以可以将要查找的数与中间的数进行比较,如果要查找的数比中间的数大,那么他就在中间数的右边,反之,就在中间数的左边

例如上图,设上图序列为数组a

中间的数为a[0]+a[9]/2,即5

如果要查找的数比5大,那么缩小范围,对5右边的数在进行二分,此时的范围是

a[6]~a[9]之间,右边的数(a[9])不变,左边的数变为a[5+1]

如果要查找的数比5小,那么就缩小范围,对5左边的数进行二分,此时的范围是a[0]~a[4]

左边的数a[0]不变,右边的数变为a[5-1],将这个思路广泛化,得到关键代码如下:

//根据索引确定中间的数,在让中间的数arr[mid],与left或者right进行比较
//left,right,mid计算的都是下标,因为返回的值需要为下标
//而进行比较的值是arr[mid],即中间下标对应的值
int binary_search(int arr[],int k,int sz)//sz表示这个数组的长度
{
	int left,right;
	left=0;
	right=sz-1;//最右边的数的下标是数组长度-1,例如数组长度是10,那么最右边数的下标就是a[9]
	while(left<=right)//如果left大于right,表示找不到该数
	{
		int mid=(left+right)/2;//中间的数的下标
		if(k<arr[mid])
			right=mid-1; 
		else if(k>arr[mid])
			left=mid+1;
		else 
			return mid;
	} 
	return -1;
}

那么最终代码如下:

#include<stdio.h>
int binary_search(int arr[],int k,int sz)
{
	int left,right;
	left=0;
	right=sz-1;
	while(left<=right)
	{
		int mid=(left+right)/2;
		if(k<arr[mid])
			right=mid-1; 
		else if(k>arr[mid])
			left=mid+1;
		else 
			return mid;
	} 
	return -1;
}

int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9,10};
	int k=7;
	int sz=sizeof(arr)/sizeof(arr[0]);
	int ret=binary_search(arr,k,sz);
	if(ret==-1)
		printf("找不到指定的数字\n");
	else
		printf("%d",ret);
	return 0;
}

注意事项:非常关键

1.mid不能写在while循环的外面

int binary_search(int arr[],int k,int sz)
{
	int left,right;
	left=0;
	right=sz-1;
    int mid=(left+right)/2;
	while(left<=right)
	{		
		if(k<arr[mid])
			right=mid-1; 
		else if(k>arr[mid])
			left=mid+1;
		else 
			return mid;
	} 
	return -1;
}

因为mid的值会根据left和right值的改变而改变了,如果mid值不变,就不能进行范围的缩小,只能进行一次二分查找,得不到最终结果 

2.left<=right不能少了=

int binary_search(int arr[],int k,int sz)
{
	int left,right;
	left=0;
	right=sz-1;
	while(left<right)
	{
		int mid=(left+right)/2;
		if(k<arr[mid])
			right=mid-1; 
		else if(k>arr[mid])
			left=mid+1;
		else 
			return mid;
	} 
	return -1;
}

如果left和right同时指向这一元素,而这一元素正好是我们需要查找的元素,写为left<right的话,那么就会跳过我们需要查找的元素,返回-1 

3.binary_search函数不能写为如下形式

int binary_search(int arr[],int k)
{
	int left,right;
	left=0;
    sz=sizeof(arr)/sizeof(arr[0]);
	right=sz-1;
	while(left<=right)
	{
		int mid=(left+right)/2;
		if(k<arr[mid])
			right=mid-1; 
		else if(k>arr[mid])
			left=mid+1;
		else 
			return mid;
	} 
	return -1;
}

即,在该函数内计算数组的大小

因为数组在传参的时候,只会传递数组的第一个元素的地址,int arr[]是指针类型的参数,即int *arr,所以对于sizeof(arr)是一个地址的大小,即4,而arr[0]是int类型元素,其大小也为4

所以这里的sz=1/1=1,得不到最终的结果,这一点千万注意。

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

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

相关文章

【论文】【生成对抗网络五】Wasserstein GAN (WGAN)

【题目、作者】&#xff1a; 紫色&#xff1a;要解决的问题或发现的问题 红色&#xff1a;重点内容 棕色&#xff1a;关联知识&#xff0c;名称 绿色&#xff1a;了解内容&#xff0c;说明内容 论文地址&#xff1a; 论文下载 本篇文章仅为原文翻译&#xff0c;仅作参考。…

C# 根据图片的EXIF自动调整图片方向

PropertyItems 代码 /// <summary>/// 根据图片exif调整方向/// </summary>/// <param name"img"></param>public void RotateImage(Bitmap img){var exif img.PropertyItems;byte orien 0;var item exif.Where(m > m.Id 274).ToArra…

从单平台运营到多平台服务,Live Market打造跨境产业集合平台

随着全球贸易和数字化的不断发展&#xff0c;跨境电商市场已经成为全球贸易的重要组成部分。在这个竞争激烈的市场中&#xff0c;品牌需要寻找更好的出海跨境运营孵化服务&#xff0c;而多平台服务已经成为了品牌出海的必选之路。Live Market是一家跨境电商产业集合平台&#x…

leetcode 135. 分发糖果

2023.8.1 这道题只从前向后遍历会出各种问题&#xff0c;所以最后决定向前向后各遍历一次。 先定义一个饼干数组biscuits&#xff0c;记录每个孩子的饼干数量&#xff0c;初始化每个孩子饼干数量为1。 然后从前向后遍历、从后向前遍历&#xff0c;使其满足“相邻两孩子评分更高…

day17 | 654.最大的二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

文章目录 一、最大的二叉树二、合并二叉树三、二叉搜索树中的搜索四、验证二叉搜索树 一、最大的二叉树 654.最大的二叉树 构建二叉树的题目&#xff0c;都用前序遍历。 因为我们一定要先构建根节点&#xff0c;才能继续向后构建。 递归函数的参数和返回值&#xff1a; Tree…

问道管理:总资产大于总市值好吗?

在财政领域&#xff0c;总财物和总市值是两个非常重要的指标。总财物是指公司所有的财物&#xff0c;包括固定财物、流动财物、无形财物等&#xff0c;而总市值则是指公司股票在商场上的总价值。当总财物大于总市值时&#xff0c;这是否是一个好的信号呢&#xff1f;咱们将从多…

【万字长文】SpringBoot整合MyBatis搭建MySQL多数据源完整教程(提供Gitee源码)

前言&#xff1a;在我往期的博客介绍了2种关于如何使用SpringBoot搭建多数据源操作&#xff0c;本期博客我参考的是目前主流的框架&#xff0c;把最后一种整合多数据源的方式以博客的形式讲解完&#xff0c;整合的过程比较传统和复杂&#xff0c;不过我依旧会把每个实体类的思路…

【C++初阶】C++基础(下)——引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr

目录 1. 引用 1.1 引用概念 1.2 引用特性 1.3 常引用 1.4 使用场景 1.5 传值、传引用效率比较 1.6 引用和指针的区别 2. 内联函数 2.1 概念 2.2 特性 3.auto关键字&#xff08;C11&#xff09; 3.1 类型别名思考 3.2 auto简介 3.3 auto的使用细则 3.4 auto不能推…

企业级IT应用运维监控层次架构设计

企业基本都有自己的IT系统&#xff0c;而每个IT系统都有自己的监控系统。 企业级的IT应用监控架构是一种综合性的解决方案&#xff0c;涉及到很多层级和相应的工具。随着企业IT系统的规模和复杂程度的不断增加&#xff0c;监控和管理系统也面临着越来越大的挑战。 大家有时在…

【算法心得】善用js可以把函数写在函数里的特性;善用spread表达式生成新数组

https://leetcode.cn/problems/combinations/ 善用js可以把函数写在函数里的特性 这样维护全局变量很烦 把子函数直接写在combine()内部&#xff0c;n和k可以直接用&#xff0c;也不用因为ans是全局的&#xff0c;每次来一个新的case要专门将ans清空了 善用spread表达式生成新…

2023年推荐的四款出色财务管理软件,助力您高效管理财务

在当今数字化时代&#xff0c;各类数字化工具逐渐普及&#xff0c;其中财务管理软件成为各个企业的标配工具。财务管理软件市场也逐渐百花齐放&#xff0c;那么2023年有什么好用的财务管理软件吗&#xff1f;本文就为大家推荐2023好用的四款财务管理软件&#xff01; 一. Zoho …

Vue 常用指令 v-model 双向数据绑定

之前的指令&#xff0c;无论使用哪一种&#xff0c;都是在代码当中定义的内容。在web开发当中经常要去获取用户的输入&#xff0c;v-model可以十分方便的将表单的值和实例当中的数据关联起来。 这样就可以十分便捷的获取和设置表单元素的值了。&#xff08;注意是表单元素&…

基于Spirngboot运动会管理系统

一&#xff1a;技术栈 SpringbootVueElement-UIMavenMysqlredis 二&#xff1a;角色 1.管理员&#xff08;创建运动会项目&#xff0c;视频&#xff0c;运动会开幕式等&#xff09; 2.裁判&#xff08;打分&#xff09; 3.运动员&#xff08;报名参赛&#xff09; 二&#…

每天一个电商API分享:获取淘宝商品描述详情 接口

电商商品描述在电商平台中扮演着重要的角色&#xff0c;对于商品销售和用户购物体验起到关键作用。以下是电商商品描述的重要性&#xff1a; 吸引用户&#xff1a;商品描述是吸引用户的第一步。通过生动、详细、精准的商品描述&#xff0c;可以吸引用户的注意力&#xff0c;引起…

Posix API原理返回值说明

文章目录 1、概述2、connect函数3、listen函数4、accept返回值处理5、recv返回值处理5.1、LT\ET模式读取数据 6、send返回值处理 1、概述 主要介绍网络编程中&#xff0c;使用到的一些系统调用解释&#xff0c;以及返回值的说明 2、connect函数 connect函数功能为&#xff0c;客…

牛客网Verilog刷题——VL51

牛客网Verilog刷题——VL51 题目答案 题目 请编写一个十六进制计数器模块&#xff0c;计数器输出信号递增每次到达0&#xff0c;给出指示信号zero&#xff0c;当置位信号set 有效时&#xff0c;将当前输出置为输入的数值set_num。模块的接口信号图如下&#xff1a; 模块的时序图…

CS人的痛

FDU原题详情请见&#xff1a;机试合集&#xff0c;选取一些学习的&#xff0c;求上岸 2022.3---CP1514 概率最大路径 题目描述&#xff1a; 2021.3---CP494 目标和 题目描述&#xff1a;

【雕爷学编程】Arduino动手做(177)---ESP-32 掌控板4

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

M5ATOMS3基础04给ROS2发一个问候(micro-ROS)

参考以往部分历程&#xff1a; 1. esp32与ros2的欢乐启程 2021 2. micro-ROS之esp32与ros2资料&#xff08;freertos&#xff09; 2021 3. esp32发布机器人电池电压到ros2&#xff08;micro-rosCoCube&#xff09; 2022 4. CoCube和Micro-ROS简单案例演示 2022 不需要僵化的…

面试总结(三)

1.进程和线程的区别 根本区别&#xff1a;进程是操作系统分配资源的最小单位&#xff1b;线程是CPU调度的最小单位所属关系&#xff1a;一个进程包含了多个线程&#xff0c;至少拥有一个主线程&#xff1b;线程所属于进程开销不同&#xff1a;进程的创建&#xff0c;销毁&…