今天看了一下JDK里面的二分法是实现,觉得有点小问题。二分法的实现有多种今天就给大家分享两种。一种是递归方式的,一种是非递归方式的。先来看看一些基础的东西。

1、算法概念。

二分查找算法也称为折半搜索、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。请注意这种算法是建立在有序数组基础上的。

2、算法思想。

①搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;

②如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。

③如果在某一步骤数组为空,则代表找不到。

这种搜索算法每一次比较都使搜索范围缩小一半。

3、实现思路。

①找出位于数组中间的值,并存放在一个变量中(为了下面的说明,变量暂时命名为temp);

②需要找到的key和temp进行比较;

③如果key值大于temp,则把数组中间位置作为下一次计算的起点;重复① ②。

④如果key值小于temp,则把数组中间位置作为下一次计算的终点;重复① ② ③。

⑤如果key值等于temp,则返回数组下标,完成查找。

4、实现代码。

/**
* description : 二分查找。
* @autor kwzhang
* modify :2012-6-29
*
* @param <E>
* @param array 需要查找的有序数组
* @param from 起始下标
* @param to 终止下标
* @param key 需要查找的关键字
* @return
* @throws Exception
*/
public static <E extends Comparable<E>> int binarySearch(E[] array, int from, int to, E key) throws Exception {
if (from < 0 || to < 0) {
throw new IllegalArgumentException("params from & length must larger than 0 .");
}
if (from <= to) {
int middle = (from >>> 1) + (to >>> 1); // 右移即除2
E temp = array[middle];
if (temp.compareTo(key) > 0) {
to = middle - 1;
} else if (temp.compareTo(key) < 0) {
from = middle + 1;
} else {
return middle;
}
}
return binarySearch(array, from, to, key);
}

5、测试demo很简单,这里就不写了。

 

上面这种实现是通过递归的方式,各人觉得之类的问题用递归比较好理解,而且过程简单。

下面再来看看非递归的方式如何实现。在JDK里面正好有实现,在此就直接贴上Arrays里面的代码。为了简单起见,我们就只看看int参数的方法:

  private static int binarySearch0(int[] a, int fromIndex, int toIndex, int key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
} 

上面这方法是我直接中SDK里面拷的(我可没有改动过)。之所以强调这个方法是因为此方法个人觉得有问题的(相信你也会觉得)。

当key为数组a中的最后一个值时,那么就会找不到(不明白sun公司当初是怎么想的)。个人觉得需要把 int high = toIndex - 1; 改成 int high = toIndex;

这个算法到此为止。欢迎讨论交流。

二分查找算法java实现的更多相关文章

  1. 二分查找算法java

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元 ...

  2. Java实现的二分查找算法

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小 于该中点 ...

  3. Java学习之二分查找算法

    好久没写算法了.只记得递归方法..结果测试下爆栈了. 思路就是取范围的中间点,判断是不是要找的值,是就输出,不是就与范围的两个临界值比较大小,不断更新临界值直到找到为止,给定的集合一定是有序的. 自己 ...

  4. 算法:时间复杂度+二分查找法(Java/Go/Python)实现

    导读 曾几何时学好数据结构与算法是我们从事计算机相关工作的基本前提,然而现在很多程序员从事的工作都是在用高级程序设计语言(如Java)开发业务代码,久而久之,对于数据结构和算法就变得有些陌生了,由于长 ...

  5. 二分查找算法,java实现

    二分查找算法是在有序数组中用到的较为频繁的一种算法. 在未接触二分查找算法时,最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间复杂度为O(n),但二分查找算法则更优,因为其查找时间复杂度 ...

  6. 二分查找算法(JAVA)

    1.二分查找又称折半查找,它是一种效率较高的查找方法. 2.二分查找要求:(1)必须采用顺序存储结构 (2).必须按关键字大小有序排列 3.原理:将数组分为三部分,依次是中值(所谓的中值就是数组中间位 ...

  7. Java之二分查找算法

    算法说明:取中间位置的值与待查字比较.如果比待查字更大,则去列表的前半部分查找,如果比待查字小,则去列表的后半部分查找,直到找到这个待查字,或者返回没有找到这个待查字.其中给定的列表是从大到小排列的有 ...

  8. Java面向对象_常用类库api——二分查找算法

    概念:又称为折半查找,优点是比较次数少,查找速度快,平均性能好:缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表. 例: public class Bi ...

  9. 【algorithm】 二分查找算法

    二分查找算法:<维基百科> 在计算机科学中,二分搜索(英语:binary search),也称折半搜索(英语:half-interval search)[1].对数搜索(英语:logari ...

随机推荐

  1. 如何使用setup.py文件

    setup.py文件的使用:% python setup.py build #编译% python setup.py install    #安装% python setup.py sdist     ...

  2. macbook air 安装win7双系统

    转自: http://jingyan.baidu.com/article/6d704a13f99f1a28da51ca49.html 1)遇到“No bootable device-insert bo ...

  3. 【leetcode】Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...

  4. 【转】javax.net.ssl.SSLHandshakeException(Cas导入证书)

    本文转自:http://my.oschina.net/laiwanshan/blog/159057 一.报错: javax.net.ssl.SSLHandshakeException 二.原因分析:C ...

  5. [Android Memory] android 警告:Exported activity does not require permission

    在一个应用程序中添加了多个antivity后,在manifest.xml文件中会除了主Activity外,其它的Activity属性中都会有个警告: Exported activity does no ...

  6. free(): invalid next size (fast/normal)问题

    本文转自 http://blog.sina.com.cn/s/blog_77f1e27f01019qq9.html  ,在此感谢! c++编译常会出现free(): invalid next size ...

  7. mysql 源码包 有的版本 可能没有 CMakeCache.txt

    如果没有CMakeCache.txt 文件编译的时候会报错!!找不到CMakeCache.txt

  8. android 检测sqlite数据表中字段(列)是否存在 (转)

    原文摘自 http://www.tuicool.com/articles/jmmMnu 一般数据库升级时,需要检测表中是否已存在相应字段(列),因为列名重复会报错.方法有很多,下面列举2种常见的方式: ...

  9. loj 1034(最小点基)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25911 思路:强连通缩点,在新图中找入度为0的点的个数即可. #i ...

  10. 《数据结构与算法分析》学习笔记(五)——队ADT

    一.队的概念 队列也是一种表,但是是一种受限的表,只允许从一端插入,另一端山粗的表. 二.队列的数组实现 #define QMAXSIZE 100 typedef int Position; type ...