二分法是静态查找法的一种,又称折半查找法,在某些情况下相比于顺序查找,使用折半查找算法的效率更高。(要求其静态查找表必须是有序的)
在折半查找之前对查找表按照所查的关键字进行排序的意思是:若查找表中存储的数据元素含有多个关键字时,使用哪种关键字做折半查找,就需要提前以该关键字对所有数据进行排序。
对静态查找表{2,4,6,8,10,12,14,15,16,19,20}
采用折半查找算法查找关键字为 4 的过程为
- 先把查找表从中间一分为二,(查找表长度的一半11/2=5),试比较中间索引位置的值和查找关键字值的大小(12>4)。
- 如果查找表中间索引位置的值大于查找关键值,那么取查找表中间索引位置前一部分的数据为新的查找表。(否则取查找表中间索引位置后一部分的数据为新的查找表)。这个查找表的数据即
{2,4,6,8,10,12
} - 把新的查找表再从中间一分为二,((查找表长度的一半6/2=3),试比较中间索引位置的值和查找关键字值的大小(8>4)。依旧取查找表中间索引位置前一部分的数据为新的查找表。以次类推直到找到目标关键字。(找到最后一个也没有即未找到)
算法实现
/**
* 使用循环实现(二分法)
* @param arr 查找数组 [1 2 3 4 5 6]
* @param key 查找值 3
*/
public static int findTwoPoint(int[] arr,int key) {
int start = 0;
int last = arr.length-1;
while (start <= last){
int temp = (last-start)/2+start;
if (key == arr[temp]){
return temp;
}else if (arr[temp] > key){
last = temp ;
}else {
start = temp;
}
}
return -1;
}
/**
* 递归实现(二分法)
* @param arr 查找数组
* @param key 查找值
* @param start 上限
* @param last 下限
*/
public static int search(int[] arr,int key,int start,int last) {
int temp = (last-start) / 2 + start;
// 边界条件
if (arr[temp] == key){
return temp;
}else if(last < start) {
return -1;
}else {
if (arr[temp] > key){
return search(arr,key,start,temp);
}else {
return search(arr,key,temp,last);
}
}
}