今天看了一下JDK裏面的二分法是實現,以爲有點小問題。二分法的實現有多種今天就給你們分享兩種。一種是遞歸方式的,一種是非遞歸方式的。先來看看一些基礎的東西。php
一、算法概念。算法
二、算法思想。數組
①搜素過程從數組的中間元素開始,若是中間元素正好是要查找的元素,則搜素過程結束;post
②若是某一特定元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半中查找,並且跟開始同樣從中間元素開始比較。測試
③若是在某一步驟數組爲空,則表明找不到。spa
這種搜索算法每一次比較都使搜索範圍縮小一半。code
三、實現思路。blog
①找出位於數組中間的值,並存放在一個變量中(爲了下面的說明,變量暫時命名爲temp);遞歸
②須要找到的key和temp進行比較;ip
③若是key值大於temp,則把數組中間位置做爲下一次計算的起點;重複① ②。
④若是key值小於temp,則把數組中間位置做爲下一次計算的終點;重複① ② ③。
⑤若是key值等於temp,則返回數組下標,完成查找。
四、實現代碼。
/** * 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); }
五、測試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;
這個算法到此爲止。歡迎討論交流。