二分查找:递归实现

public class BinarySearch {

/**

* @param arr 代查找的数组,需要有序

* @param left 查找区间的左界限

* @param right 查找区间的右界限

* @param target 待查找的值

* @param 泛型

* @return

在arr中[left...right]左闭右闭区间查找target, 找到了就返回该下角标,没找到则返回-1.

*/

public static > int search(T[] arr, int left, int right, T target) {

if (left > right) return -1;//递归结束了都没找到,返回-1.

int mid = left + (right - left) / 2; // 二分,arr[mid]作为比较的基准值。

if (arr[mid].compareTo(target) == 0) {//如果相等,说明找到

return mid;

} else if (arr[mid].compareTo(target) < 0) {//如果中间的比target小,则在右半边找

return search(arr, mid + 1, right, target);

} else {如果中间的比target大,则在左半边找

return search(arr, left, mid - 1, target);

}

}

public static > int search(T[] arr, T target) {

return search(arr, 0, arr.length - 1, target);

}

public static void main(String[] args) {

Integer[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};//二分查找需要是有序的数组

int ret = search(arr, 11);

System.out.printf("下角标是:%d\n", ret);

}

}

二分查找:非递归实现

public class BinarySearch {

public static > int search(T[] arr, T target) {

int left = 0;

int right = arr.length - 1;

while (left <= right) {//从[left ... right] 左闭右闭区间找,当left==right时,就是在判断arr[left]是否等于target

int mid = left + (right - left) / 2;

if (arr[mid].compareTo(target) < 0) {//如果中间的比target还小,那么到右半边去找

left = mid + 1;

} else if (arr[mid].compareTo(target) > 0) {//如果中间的比target大,那么到左半边去找

right = mid - 1;

} else {//如果 arr[mid] == target

return mid;

}

}

//如果没找到

return -1;

}

public static void main(String[] args) {

Integer[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};//二分查找需要是有序的数组

int ret = search(arr, 11);

System.out.printf("下角标是:%d\n", ret);

}

}

二分查找:求mid时除以2的bug问题

比如left = 1256648431, right = 1742321453 那么相加后就会上溢,得到结果 -1295997412, 除以2之后就是 -647998706,显然这个结果是不对的。

下面介绍三种方法,可以计算出正确的结果 1499484942

public class BinarySearch {

public static void main(String[] args) {

int a = 1256648431;

int b = 1742321453;

long c = (long) a + b;

System.out.printf("a + b 应该等于 %d ", c);//a + b 应该等于 2998969884 ,正确

System.out.printf("(a + b)/2 应该等于 %d\n\n", c / 2);//(a + b)/2 应该等于 1499484942 ,正确

System.out.println("整数int型用普通除法");

System.out.printf("a + b 等于 %d ", a + b);// -1295997412 ,溢出

System.out.printf("(a + b)/2 等于 %d\n\n", (a + b) / 2);// -647998706 ,溢出

System.out.println("整数int型用逻辑右移代替除法");

System.out.printf("a + b 等于 %d ", a + b);// -1295997412 ,溢出

System.out.printf("(a + b)>>>1 等于 %d\n\n", (a + b) >>> 1);// 1499484942 ,正确

System.out.println("整数int型用位运算技巧代替除法");

System.out.printf("a + b 等于 %d ", a + b);// -1295997412 ,溢出

System.out.printf("(a & b) + (a ^ b) >> 1 等于 %d\n\n", (a & b) + ((a ^ b) >> 1));// 1499484942 ,正确

}

}

给女朋友讲最后一种情况时的笔记:

目的:两个二进制数,对应位置进行相加,求出每项的项系数,也就是每位结果。

根据规律,分为两种情况。

1.对应位不同,其中一个为1,另一个为0

2.对应位相同,即同为1,或同为0

设a:1100110,b:1010101. 那么a + b = 2110211.(先不考虑进位)

处理情况1:去找规律,发现,情况为1时,相加总为1,相当于异或运算。对于情况2,异或运算总为0,不会被影响到。

处理情况2:再去找规律,发现,情况为2时,两数相加的结果要么是0,要么是2。结果总是‘&运算’结果的2倍。对于情况1,&运算结果总得到0,不会被影响到。

a:1100110

b:1010101

a^b:0110011 0 1 4 5 找到了这些项的系数

a&b:1000100 2 3 6 找到了这些项的系数

但上面这个与运算得出来的并不是真正的项系数,而是对应位置项系数的一般。所以 * 2后得

:2000200(先不考虑进位)

所以sum = (a & b) * 2 + (a ^ b)

sum / 2 = (a & b) + (a ^ b) / 2 (后续再把这个除法改成右移运算)

----------------------------------------------------------

或者换一种说法。

设a:1100110,b:1010101. 那么a + b = 2110211.(先不考虑进位)

对于a + b = 2110211.其中的2都是'&运算' 乘2得来,其中的1都是‘ ^运算 ’得来。

java二分查找范围区间_二分查找(Java实现)相关推荐

  1. java能写驱动吗_使用纯java jdbc驱动程序实现数据库的连接

    1.准备工作: 准备相关的软件(Eclipse除外,开源软件可以从官网下载) <1>.Microsoft SQL server 2005 Express Edition <2> ...

  2. java文件中获取创建日期_如何在Java中获取文件的上次修改日期

    java文件中获取创建日期 Sometimes we need to get the file last modified date in Java, usually for listeners li ...

  3. java 和c 多态比较_多态在 Java 和 C 编程语言中的实现比较

    2011 年 12 月 22 日发布 众所周知,多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定.C++ 和 Java 作为当前最为流行的两种 ...

  4. java 面试题合集_撩课-Java面试题合辑1-50题

    1.简述JDK.JRE.JVM? 一.JDK JDK(Java Development Kit) 是整个JAVA的核心, 包括了Java运行环境(Java Runtime Envirnment), 一 ...

  5. java怎么提升编程能力_怎样提升java编程能力

    1 怎样提升java编程能力 在互联网迅猛发展的时代,而我们如果对互联网一无所知,那就相当于文盲.所以很多人都想去了解它,去学习他.而作为互联网的产物--java,是一门非常不错的技术,学精通之后,你 ...

  6. 有谁转行学java成功了的吗_转行学习java靠谱吗?

    转行学Java靠谱吗?靠不靠谱主要还是看你自己是否想要学好Java技术,是否想要从事这方面的岗位工作,如果你已经有了这个决心,那么自然而然什么都不会问题.无论我们学Java是兴趣还是想要通过学好Jav ...

  7. java正则截取xml节点_实例讲述Java使用正则表达式截取重复出现的XML字符串功能...

    Java使用正则表达式截取重复出现的XML字符串功能示例 本文实例讲述了Java使用正则表达式截取重复出现的XML字符串功能.分享给大家供大家参考,具体如下: public static void m ...

  8. java 获取 反射 方法 名_乐字节Java反射之一:反射概念与获取反射源头Class

    一.Java反射机制概念 "程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言",如Python, Ruby是动态语言:显然C++,Java,C#不是动态语言,但是JAV ...

  9. 深入java虚拟机 第四版_深入理解Java虚拟机-常用vm参数分析

    Java虚拟机深入理解系列全部文章更新中... https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-java-nei-cun-qu-yu- ...

最新文章

  1. React+Redux+中间件
  2. java与fabric区块链--fabric-java-jdk部署搭建--(1)
  3. sql if else语句_一道sql题学习if语句和case when语句
  4. 烽火2640路由器命令行手册-12-IBM网络配置命令
  5. getoutputstream java_已经为此响应调用了getOutputStream()
  6. 大数据可视化的重要性体现在哪里
  7. Elasticsearch从0.90(0.90.x)到1.2(1.x)API的变化-二
  8. Verilog入门教程与实例分享
  9. Windows Phone SDK 7.1 RTM 发布
  10. 第四章选择结构,根据输入的性别和身高判断是否符合招生要求,男生身高大于等于168cm,女生身高大于等于158cm。
  11. SQL语句的五大类:DQL、DML、DDL、DTL、DCL
  12. 贝壳找房的2021,依然充满变数
  13. 【GD32F310开发板试用】编码器接口的使用
  14. openCV minMaxLoc
  15. QCC3040/QCC3046 ANC(主动降噪)调测
  16. 微信小程序点击按钮弹出弹窗_微信小程序自定义弹窗(可通用)
  17. 恢复Excel批注框到默认位置
  18. RBF神经网络——基于近红外光谱的汽油辛烷值预测
  19. android地震监测程序,earthquake(地震监测)
  20. php aes加密中文,PHP AES加密 - 菜鸟要飞啊的IT小窝 - OSCHINA - 中文开源技术交流社区...

热门文章

  1. linux内核zfs,Linus Torvalds 不建议使用 ZFS On Linux
  2. Makefile:跟我一起学makefile
  3. apktool反编译生成java_apktool反编译工具下载|apktool反编译工具 v3.0.1 最新版-520下载站...
  4. android layout_margin的值,Android自定义ViewGroup( 支持layout_margin属性)
  5. server接收dtu透传代码_Gopher2020大会干货总结:代码技巧篇
  6. switch语句(JS)
  7. HoloLens 2开发:三种工程部署方式
  8. 为资产分类定义折旧范围_SAP折旧范围概念
  9. Windows 下的坐标系
  10. Spring定时任务高级使用篇