当前位置: 首页 > 科技观察

怎么写一个没有bug的二分查找

时间:2023-03-16 12:51:33 科技观察

在计算机领域,二分查找也叫binarysearch。有些地方根据其时间复杂度将其称为对数搜索。它可以在对数时间内找到指定的元素。本文介绍二分查找的基础知识和原理。原理二分查找算法是一种在有序数组中查找特定元素的查找算法,查找过程从数组的中间元素开始。如果中间的元素恰好是要查找的元素,则查找结束。如果小于中间元素的值,则在数组开头和小于中间元素的一半之间查找,从这一半的中间开始比较。如果大于中间元素的值,则在大于中间元素的数组的一半到末尾元素之间查找,从这一半的中间开始比较。这里是一个有序数组,元素的索引从0到6,我们以它为例来说明二分查找的过程:找到值为15的元素;15正好在数组的中间,所以比较一下就找到了;search值为8的元素;数组中间的元素为15,目标值8小于15,所以搜索范围缩小到15左边的一半,即[3,9],中间的元素这一半的是8,正好是要查找的值;查找值为34的元素;数组中间的元素是15,目标值34大于15,所以搜索范围缩小到15右边的一半,即[19,34],他们的中间元素是20、目标值34大于20,所以搜索范围继续减半为[34,34],他们的中间元素为34,正好是要搜索的值。基本框架根据上述二分查找的过程,可以总结出二分查找的基本框架。以下是伪代码:intbinary_search(vector&vec,inttarget){intleft=0;//搜索范围左侧的索引intright=0;//搜索范围的右边索引while(...)//找到结束条件{//数组中间元素的索引intmid=left+(right-left)/2;//等于目标值if(target==vec[mid]){//处理逻辑...}//目标值小于中间元素elseif(target>1,避免溢出风险。有许多方法可以实现二分查找。这里,我们只选取前面基本框架中的方法进行介绍。常见的二分查找场景包括:查找指定数,找到数组中第一个等于目标值的元素,找到数组中最后一个元素等于目标值。下面的算法实现代码是用C++语言实现的,vectorvec代表一个整型数组,数组名为vec,类似于Java中的int[]nums,如果是C语言,可以使用int*nums和intlento表示是一样的,你可以自己用熟悉的编程语言来实现。1.找到等于目标值的元素这是最基本的二分查找,只要找到等于目标值的元素,就返回它的索引,否则返回-1,表示元素的索引等于未找到目标值:intbinary_search(vector&vec,inttarget){intilen=(int)vec.size();如果(ilen<=0)返回-1;int左=0;intright=ilen-1;while(left<=right){intmid=left+(right-left)/2;//找到,直接返回if(target==vec[mid])returnmid;if(targetright,然后退出while循环。为什么左=中+1或右=中-1;根据前面的介绍,二分查找的范围是[left,right],当我们发现查找的目标值不等于mid索引元素的值时,下一次查找的范围是[left,mid-1]或[mid+1,right],因为mid处的元素已被比较,需要排除在搜索范围之外。2.第一个等于target值的元素上面的二分查找有一个限制,比如一个有序数组{-1,-1,-1,-1,2,3},target的值为-1,在这次算法返回的index是2,结果是正确的,但是如果我想得到第一个等于target的元素的index,即0或者最后一个等于target的元素的index,也就是3,这个算法没用为了应对,下面介绍两种二分查找算法。intbinary_search_firstequal(vector&vec,inttarget){intilen=(int)vec.size();如果(ilen<=0)返回-1;int左=0;intright=ilen-1;while(left<=right){intmid=left+(right-left)/2;//找到目标,继续向左找目标if(target==vec[mid])right=mid-1;elseif(target&vec,inttarget){intilen=(int)vec.size();如果(ilen<=0)返回-1;int左=0;intright=ilen-1;while(left<=right){intmid=left+(right-left)/2;//找到目标,继续向右找目标if(target==vec[mid])left=mid+1;elseif(target