当前位置: 首页 > news >正文

折半查找算法[二分查找法]算法的实现和解决整数溢出问题~

算法实现的要求:

折半查找法又称为二分查找法,这种方法对待查找的列表有两个要求:

1:必须采用顺序存储结构
2:必须按关键字大小有序排列

算法思想:

将表中间位置记录的关键字与查找关键字进行比较如果两者相等,则查找成功,否则利用中间位置记录将表分成前后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表

重复上述查找过程,直到找到满足条件的记录,则查找成功,或直到子表不存在为止,则查找不成功

使用java实现该算法:

算法实现方法:

1:前提要求:有已排序数组A[因为在查找的过程中是根据下标进行的]

2:定义左边界L,右边R,确定搜索范围,循环执行二分查找

3:获取中间索引M=(L+R)/2,如果是小数,一般默认向下取整

4:中间索引的值A[M]与带搜索的值T进行比较
A[M]==T,返回中间索引
A[M]>T,中间值右侧的其他元素都大于T,无需比较,中间索引左边去找,M-1,设置为右边界,重新查找
A[M]<T,中间值左侧的其他元素都小于T,无需比较,中间索引右边去找,M+1设置为左边界,重新查找

5:当L>R时,表示没有找到,应结束循环

代码如下所示:

package bin_find;

import java.util.Scanner;

public class bin_find {
    public static void main(String[] args) {
        int arr[] = {4, 10, 18, 23, 45, 68, 199};
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要查找的数:");
        int x = scanner.nextInt();
        int result= bin_research(arr,x);
        if(result!=-1){
            System.out.println("你要查找的数已找到,它是数组的第"+(result+1)+"个元素");
        }
        else{
            System.out.println("你要查找的数不存在");
        }
    }

    public static int bin_research(int arr[], int x) {
        int L = 0;
        int R = arr.length - 1;
        while(L<=R) {
        //不要写到循环外面了,因为每查找一次,中间索引的位置也需要变化
            int M = (L + R) / 2;
            if (x > arr[M]) {
                L = M+1;
            } else if (x < arr[M]) {
                R = M - 1;
            } else if (x == arr[M]) {
                return M;
            }
        }
        return -1;
    }
}

输出:

请输入你要查找的数:
23
你要查找的数已找到,它是数组的第4个元素

整数溢出现象:

package bin_find;

public class bin_find2 {
    public static void main(String[] args) {
        int l=0;
        int r=Integer.MAX_VALUE-1;
        int m=(l+r)/2;
        //当要查找的数在左子表时:
        System.out.println(m);
        //当要查找的数在右子表时:发生整数溢出现象
        l=m+1;
        m=(l+r)/2;
        System.out.println(m);
    }
}

输出:

1073741823
-536870913

之所以会出现负数的原因:是因为在计算机中,是根据二进制进行运算的,逢二进一,由于最高位表示符号位,当它为1时,该数即为负数!

对该过程不熟悉的小伙伴,可以去看我写的这篇文章

解决整数溢出问题:

上述代码中产生溢出的原因是由于:当要查找的数在右子表时,此时:r最初为整数的最大值-1不变,而l的值增大到了r/2的大小,因此即使他两相加除2,在计算机中,是根据二进制进行运算的,逢二进一,由于最高位表示符号位,当它为1时,该数即为负数,那么解决溢出的核心就是改变m的值,但所谓的改变,并不是将m的值真正的改变,而是通过变换表达式等等,去调整m的大小

方法1:通过调整数学表达式

方法如下:

在这里插入图片描述

代码如下:

package bin_find;

public class bin_find2 {
    public static void main(String[] args) {
        int l=0;
        int r=Integer.MAX_VALUE-1;
        int m=l+(r-l)/2;
        //当要查找的数在左子表时:
        System.out.println(m);
        //当要查找的数在右子表时:
        l=m+1;
        m=l+(r-l)/2;
        System.out.println(m);
    }
}

输出:

1073741823
1610612735

方法2:通过>>>运算符

>>>表示无符号右移运算符也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0,移动的是二进制位,但他们的操作数必须是整数,[当被操作的数是整数时]右移一位有除二的效果,因此对于上述溢出现象,右移一位既能够避免最高位[符号位]为1,导致该数为负数的现象,而且正好借用它右移一位有除二的效果,还简化了数学表达式;

修改如下:

package bin_find;

public class bin_find2 {
    public static void main(String[] args) {
        int l=0;
        int r=Integer.MAX_VALUE-1;
        int m=(r+l)>>>1;
        //当要查找的数在左子表时:
        System.out.println(m);
        //当要查找的数在右子表时:
        l=m+1;
        m=l+(r-l)>>>1;
        System.out.println(m);
    }
}

输出:

1073741823
1073741823

对于上述两种做法均可以解决整数溢出问题,不过我们更加推荐第二种,因为它的效率比较高!

练习题:

有一个有序表为 1,5,8,11,19,22,31,35,4045,89,50 当分查找值为48的结点时,查找成功需要比较的次数
[来源于:京东实习生招聘]

答案为:4次

这里需要强调的点就是:当子表的元素个数为偶数时,如果题目没有强调,那么我们默认选择靠左边的元素为中间数

使用二分法在序列 1,4,6,7,15,33,39,50,64,78,75,81,89,96 中查找元素81 时,需要经过()比较
[来源于:美团点评校招]

答案为:4次

在拥有128个元素的数组中二分查找一个数,需要比较的次数最多不超过多少次 [来源于:北京易道博识社招]

答案为:7次

方法1:
上述题目相当于为2^n=128,n的值为多少?

方法2:
使用128一直不断的除2,直到变为1,只需要计算除2的次数即可

方法3:
使用计算器,问题转变为log2^128,不过需要知道该计算机是以多少为底,下图为Windows10操作系统的计算器,以10为底

在这里插入图片描述

运算结果是整数,则该整数即为最终结果

运算结果是小数,则舍去小数部分,整数加一为最终结果

相关文章:

  • 做的网站怎么把技术支持去掉/如何申请网站域名流程
  • 要建一个网站该怎么做/亚洲长尾关键词挖掘
  • 学校班级网站建设主页源代码PHP/网络推广外包哪家好
  • wordpress 菜单加图标/威海百度seo
  • 做网站销售那里找客户/百度seo一本通
  • 石碣镇仿做网站/北京seo邢云涛
  • InfluxDB的查询优化
  • 1-货物摆放
  • 2023.1.16 (一) 上午 关于人口老龄化的研究——老龄化的式子表示及建国以来的老龄化情况
  • 5. 统计学基础2:协方差、相关系数、协方差矩阵
  • 【C++】二叉树进阶OJ题
  • 人工智能入门基础概念—教你正确打开人工智能世界的大门
  • 【自学Python】Python查找字符串
  • mybatis-plus分布式id重复问题
  • 译文 | Kubernetes 1.26:PodDisruptionBudget 守护不健康 Pod 时所用的驱逐策略
  • 数据库概述
  • 01.【Vue】Vue2基础操作
  • JAVA校园闲置物品交易系统源码+数据库,为在校师生提供闲置物品发布、物品查询、物品交易等功能