首页 > 其他分享 >二分查找(折半查找)

二分查找(折半查找)

时间:2024-01-31 10:23:02浏览次数:27  
标签:折半 二分 arr target int 位置 查找 数组

二分查找的前提:数组中的数据必须是有序
核心思想:每次排除一半的数据,查询数据的性能明显提高很多

实现步骤
1.定义两个变量,一个代表左边位置,一个代表右边位置
2.定义一个循环控制折半
3.每次折半,都算出中间位置处的索引
4.判断当前要找的元素值,与中间位置处的元素值的大小情况

往左边走,截止位置(右边位置)=中间位置-1
往右边走,起始位置(左边位置)=中间位置+1
中间位置处的元素值,正好等于我们要找的元素值
如果循环结束都没有,ruturn -1 特殊结果,代表没有找到数据,数组中不存在该数据

代码示例

public static int binarySearch(int[] arr,int target){
  //设置左边位置
  int left=0;

  //设置右边位置
  int right = arr.length-1;

  //循环条件:如果左边位置小于等于右边位置
  while(left<=right){
    //中间位置等于(左边加右边)/2
    int mid = (right + left) >>>1

    //如果目标等于中间位置就返回
    if(arr[mid] == target){
      return mid;
    }else if(arr[mid]< target){
      //如果中间位置小于目标位置
      //左边位置等于中间位置+1
      left = mid +1;
    }else if(arr[mid] > target){
      //如果中间位置大于目标位置
      //右边位置等于中间位置-1
      right = mid-1;
    }
  }
  //如果没有找到就返回 -1
  return -1;
}

问题1:为什么判断条件是left<=right,而不是left<right
答案:因为他们所指向的元素也会参与比较,否则会少比较一轮

问题2:(left + right)/2 有没有问题
答案:数值较大时,两数相加会得到一个负数,可以用>>>(无符号运算符)解决

问题3:二分查找的最差情况会执行多少次(时间复杂度)
1.最差的查找情况中右边的比较次数会更多

最差的情况要么是目标元素不在数组中,要么目标元素在数组的最后一个位置

当目标元素不在数组中时,算法会一直缩小搜索范围,直到左边位置大于右边位置,这时算法才会停止。因此右边的比较次数会更多

当目标元素在数组的最后一个位置时,算法会进行一些列的比价操作,直到左边位置等于右边位置。因此,右边的比较次数也会更多

元素个数 循环次数
4-7 3 floor(㏒2(4))=2+1
8-15 4 floor(㏒2(8))=3+1
16-31 5 floor(㏒2(16))=4+1
32-63 6 floor(㏒2(32))=5+1
n floor(㏒2(n))+1
循环次数 L=floor(㏒2(n))+1
left <= right L+1
(right + left)>>>1 L
arr[mid]<target L
arr[mid] > target L
left = mid +! L

二分查找最差的执行情况
(floor(㏒2(n))+1)*5+4

如果有1024个元素
(floor(㏒2(1024))+1)*5+4=59

线性查找(和每一个数据进行比较)

public static int linearSearch(int[] arr, int target) {
    // 遍历数组中的每个元素
    for (int i = 0; i < arr.length; i++) {
        // 如果找到目标值,返回索引
        if (arr[i] == target) {
            return i;
        }
    }
    // 如果没有找到目标值,返回-1
    return -1;
}
数据元素个数n
int i=0 1
i<a.length n+1
i++ n
a[i] == target n
return-1 1

线性查找最差执行情况
3*n+3

如果有1024个元素
3*1024+3=3075

Java中Arrays 类中的 binarySearch 方法是一个用于二分查找的静态方法
查找目标值 target 在数组中的索引。如果找到目标值,返回索引;如果未找到目标值,返回的索引将是一个负数,并且可以通过取负值再减一(-(index)-1)来获取插入点的索引。
示例:在数组中插入一个数据

public class Test{
  public static void main(String[] args){
    //原数组
    int[] a ={2,4,5,8};
    //要插入的目标值
    int target=1;
    //插入点
    int index = Math.abs(Arrays.binarySearch(a,target)+1);
    //新数组
    int[] b = new int[a.length+1];
    //先从原数组的插入位置复制到新数组
    System.arraycopy(a,0,b,0,index);
    //新数组的插入位置赋值为插入的目标值
    b[index]=target;
    //将原数组插入位置开始复制到新数组插入点+1位置,长度为原数组减去插入点
    System.arraycopy(a,index,b,index+1,a.length-index);
    System.out.println(Arrays.toString(b));
  }
}

前面的函数有一点复杂
一般用大O表示法

线性查找示例
f(n)=3*n+3
g(n)=n
取c=4,n=3之后,g(n)可以作为f(n)的渐进上界,因此表示法写作O(n)

二分查找示例
f(n)=5*floor(㏒2(n))+9
g(n)=㏒2(n)
O(㏒2(n))


标签:折半,二分,arr,target,int,位置,查找,数组
From: https://www.cnblogs.com/zhao-zong-yu-hai/p/17998652

相关文章

  • KY27 查找学生信息C++
    用map做查找就行了。#include<iostream>#include<string>#include<map>usingnamespacestd;structnode{stringname;stringx;intage;};typedefstructnodesinfo;intmain(){intn;while(cin>>n){map<......
  • AtCoder Beginner Contest 338 c题二分思路
    观察题目可知,会有一个最大的x(两个菜的最大制作数),大于这个x就不能做任何一盘菜,小于这个x那么一定可以做出来,这样分析就是显而易见的递归。实现递归的check函数,那么我们就可以把两个菜的总制作数传进去。那么什么时候true什么时候false呢,就是判断每种材料的制作量有没有超过原材料......
  • Leetcode刷题第五天-二分法-回溯
    215:第k个最大元素链接:215.数组中的第K个最大元素-力扣(LeetCode)em~~怎么说呢,快速选择,随机定一个目标值,开始找,左边比目标小,右边比目标大,左右同时不满足时,交换左右位置,直到左指针比右指针大,交换目标和右指针位置的值,此时右指针位置即时目标值的在排序好数组中的位置,如果k在右......
  • 二分算法
    二分算法个人感想洛谷二分题单基本完成,发现二分确实是比较模板的方式解答题目,难点往往是寻找出答案的单调性和如何高效验证答案的正确性。二分个人感觉就是枚举的优化,在时间复杂度上的极大优化,有一种暴力的美.目前发现的不足对题目的理解太浅,有时很难看懂题目的意思,理解有问......
  • 【学习笔记】二分图
    1.定义一个二分图满足有一种划分方案使得它节点的被分为两部分,且所有边的端点所在的部分不相同。即每条边都连接两个部分。变量说明:没有特殊说明时,\(n\)表示a部分点数,\(m\)表示b部分点数,\(e\)表示边数。2.判定显然我们给二分图染色,确定一个点所有点都确定。如果在染的......
  • java中二分查找前提必须是升序吗?
    二分查找不必须是升序,降序排列的数组也可以执行二分查找。二分查找算法是一种高效的搜索方法,它要求数据集是有序的,无论是升序还是降序都可以。在升序排列的情况下,算法会将目标值与中间值比较,如果目标值较小,则在左半部分继续查找;如果目标值较大,则在右半部分继续查找。在降序排列的......
  • iOS应用崩溃了,如何通过崩溃手机连接电脑查找日志方法
    ​在iOS应用开发过程中,调试日志和奔溃日志是开发者必不可少的工具。当iOS手机崩溃时,我们可以连接电脑并使用XcodeConsole等工具来查看日志。然而,这种方式可能不够方便,并且处理奔溃日志也相当繁琐。克魔助手的出现为开发者带来了极大的便利,本文将详细介绍其功能和使用方法。克魔......
  • net8字符串匹配查找System.Buffers.SearchValues类
    新增的System.Buffers.SearchValues类,可以用来进行字符串的查找和匹配,相比较 string 类型的操作,性能有大幅提升,下面还是用BenchmarkDotNet进行测试:BenchmarkRunner.Run<SearchValuesTest>();Console.ReadKey();[SimpleJob(RunStrategy.ColdStart,iterationCount:5)]......
  • Java二分查找
    二分查找\789.数的范围给定一个按照升序排列的长度为n的整数数组,以及q个查询。对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。如果数组中不存在该元素,则返回-1-1。输入格式第一行包含整数n和q,表示数组长度和询问个数。第二行包含n个整数(均在1∼1......
  • 通信(二分+SPFA好题)
    第1题    通信查看测评数据信息某城市有N座通信基站,P条双向电缆,第i条电缆连接基站Ai和Bi。特别地,1号基站是通信公司的总站,N号基站位于一座农场中。现在,农场主希望对通信线路进行升级,其中升级第i条电缆需要花费Li。电话公司正在举行优惠活动。农场主可以指定......