二分查找就是將查找的鍵和子數組的中間鍵做比較,若是被查找的鍵小於中間鍵,就在左子數組繼續查找;若是大於中間鍵,就在右子數組中查找,不然中間鍵就是要找的元素。html
基礎二分查找:數組
/* * 若是查找到了,就返回所在的下標,若是找不到,就返回-1*/ public static int binarySerach(int []array,int key){ int left=0,right=array.length-1; //這個等於號必不可少 while (left<=right){ int mid=left+(right-left)/2; //防止溢出 if (array[mid]==key) return mid; else { if (key<array[mid]){ //則在左邊 right=mid-1; }else { //則在右邊 left=mid+1; } } } return -1; //若是走到這邊,必定是找不到了。。。 }
二分變種spa
1.求第一個大於等於key的元素code
分析:假設有數組1 3 4 6 8 12 ,這個時候a[mid]是6,而須要找的key是5,因此a[mid]>=key,在原來的基礎二分的時候是:right=mid-1;可是要注意,咱們須要找的是第一個大於等於key的值,因此這個a[mid]頗有多是咱們須要找的數據,於是不能減去,因此這個時候是:right=mid;而若是a[mid]<key的話,原來基礎二分是:left=mid+1;這裏也是同樣的。htm
//找到第一個大於等於key的元素的下標 public static int findFirstLarger(int []array,int key){ int left=0,right=array.length-1; while (left<=right){ int mid=left+(right-left)/2; //防止溢出 if (array[mid]<key){ left=mid+1; }else{ right=mid; /*這裏有個bug,若是left=0 right=1 那麼mid=0,且往右邊查找、 * 那麼left=mid+1=1,那麼就 left==right * 那麼就會陷入死循環*/ if (left==right)break; } } return left; //return right都同樣 }
2.找到第一個小於key的值的元素blog
分析:其實很簡單,能夠變成查找第一個大於等於key的值的元素而後-1便可。博客
代碼就和上面的同樣。只是結果本身-1class
3.找到第一個大於key的值的元素基礎
分析:仍是很簡單的弄到第一種方式的變動,一開始對key加1就行了。而後就變成找到第一個大於等於key的值的元素。循環
題目:對於一個從左往右遞增,從上往下也遞增的二維數組,輸入某個key,判斷該key是否存在於二維數組中。
思路:首先對二維數組的列進行二分查找,找到第一個大於或等於key的值的位置,而後再對那一行進行二分查找便可。時間複雜度:log2n+log2m
public static boolean findNum(int [][]array,int key){ int times=array.length; //對行進行二分,找到第一個大於或等於的key的值 int low=0;int high=times-1; while (low<=high){ int mid=(low+high)/2; if (array[mid][0]>=key){ high=mid-1; } else { low=mid+1; } } if (high<0) return false; //那麼這個時候的low就是所在的 if (low<times&&array[low][0]==key){ return true; }else { //對其上一行進行二分查找 int left=0,right=array[low-1].length-1; while (left<=right){ int mid=(left+right)/2; if (array[low-1][mid]==key){ return true; }else { if (array[low-1][mid]>key){ right=mid-1; }else { left=mid+1; } } } return false; } }
總結:
發現了一篇很好的關於二分的博客:https://www.cnblogs.com/luoxn28/p/5767571.html