算法学习——二分法

算法学习————二分法

初学者,如有错误,欢迎指正
二分法又叫折半搜索,是比较简单和基础的算法。主要是将一个有序的数组不断划分为两部分,直到找到需要的值为止,是分治法的一种典型应用。
二分法比较简单但是在使用之前一定要对参数做判断,比如low与high的大小,mid的取值;二分法一般应用与有序数组中,通常不应用与链表中,由于链表查询速度慢,使用二分法查找效率更低。数组的二分法查找实现有两种方法一种使用递归,另外一种不使用递归。下面分别给出递归和非递归的实现:

递归实现
/**
*

二分算法的递归实现


* @param low 起始位置
* @param high 结束位置
* @param a 查询的数组
* @param key 查询关键字
* @return
* int
*
*/
public int binarySerach(int low,int high,int[] a ,int key){
int mid;
if(low>high){
return -1;
}
if(low<0||high>a.length){
return -1;

}
//mid=(high+low)/2; //当数据足够大时可能溢出
mid=low+(high-low)/2;//保证计算出来的mid,一定大于low,小于high,不存在溢出的问题。
if(low<high){
if(a[mid]>key){
return binarySerach(low, mid, a, key);
}else if(a[mid]<key){
return binarySerach(mid+1, high, a, key);
}else if(a[mid]key){
return mid;
}
}else if(low
high){
if(a[mid]==key){
return mid;
}else{
return -1;
}

}else{
return -1;
}
return -1;

}

以上是二分算法的递归实现,在Java的Arrays类有二分的非递归实现这里直接贴代码:

/**
*

比较之前的数据校验


*
* @param length 总长度
* @param fromIndex 开始位置
* @param toIndex 结束位置
* void
*
*/
private static void rangeCheck(int length, int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException(
"fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
}
if (fromIndex < 0) {
throw new ArrayIndexOutOfBoundsException(fromIndex);
}
if (toIndex > length) {
throw new ArrayIndexOutOfBoundsException(toIndex);
}
}

private static int binarySearch0(long[] a, int fromIndex, int toIndex,
long key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
long 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.}
---

额外拓展

二分法主要应用与查找递增或递减序列,但是当序列并非严格单调性的时候就需要使用三分法。三分法主要应用求极值。

设置中点
mid=(l+r)/2
mid2=(mid+r)/2
根据中点的值大小继续缩小范围

public int serach(int left,int right){
int mid=(left+right)/2;
int mid2=(mid+right)/2;
while(high>=low){
if(f(mid)>f(mid2)){
right=mid2;
}else{
left=mid;
}
}
}

posted on 2014-09-25 20:25  好好先生耶  阅读(333)  评论(0)    收藏  举报