这篇文章讲述的是算法初级部分的折半查找问题的java实现,参考的书籍为清华大学出版社出版,贾蓓等编著的《c语言趣味编程1000例》,如有错误或者不当之处,还望各位大神批评指正。
问题描述
N个有序序列已放在一个一维数组中,利用二分查找法查找整数m在数组中的位置,若找到,返回其下标,若找不到,则输出”没有找到!”
算法分析
折半查找采用的是分而治之的思想,是对一组有序数组进行排序的经典算法,每次查找的时候确定范围的上界和下界high,low,然后计算中间值mid与目标作比较,若匹配则返回,若不匹配则确定范围,如果mid<目标值,则high = mid-1,如果mid>目值,则low = mid+1,若直至high < low时还没找到结果,则查找失败
过程:假设有数组arr[1 3 7 9 10] 查找3
第一趟:low=0,high=4,mid=(low+high)/2=2
判断arr[2]=7 != 3 且arr[2]=7>3缩小范围high=mid-1=1
第二趟:low=0,high=1 mid=mid=(low+high)/2=0
判断arr[0]=1 != 2 且arr[0]=1<3缩小范围low=mid+1=1
第三趟:low=1,high=1,mid=(low+high)/2=1
判断arr[1]=3 == 3 找到
输出mid+1
代码实现
public class Q9_HalfFind {
/**
* 问题描述:N个有序序列已放在一个一维数组中,利用二分查找法查找整数m在数组
* 中的位置,若找到,返回其下标,若找不到,则输出"没有找到!"
*
* 算法分析:折半查找采用的是分而治之的思想,是对一组有序数组进行排序的经典
* 算法,每次查找的时候确定范围的上界和下界high,low,然后计算中间值
* mid与目标作比较,若匹配则返回,若不匹配则确定范围,如果mid<目标
* 值,则high = mid-1,如果mid>目标值,则low = mid+1,若直至high<
* low时还没找到结果,则查找失败
* 过程:假设有数组arr[1 3 7 9 10] 查找3
* 第一趟:low=0,high=4,mid=(low+high)/2=2
* 判断arr[2]=7 != 3 且arr[2]=7>3缩小范围high=mid-1=1
* 第二趟:low=0,high=1 mid=mid=(low+high)/2=0
* 判断arr[0]=1 != 2 且arr[0]=1<3缩小范围low=mid+1=1
* 第三趟:low=1,high=1,mid=(low+high)/2=1
* 判断arr[1]=3 == 3 找到
* 输出mid+1
*
*/
public static void main(String[] args) {
int [] arr = {-3,4,7,9,13,45,67,89,100,180} ; //初始化有序数组
System.out.println("请输入要查询的数:"); //输入要查的数
Scanner scanner = new Scanner(System.in) ;
int find = scanner.nextInt() ;
scanner.close();
boolean flag = true ; //标志位判断是否找到
int low=0 , high=arr.length-1 ,mid ; //初始化low,high,mid
while(low <= high){ //若low<high时进行判断
mid = (high+low)/2 ;
if(arr[mid] == find){
System.out.println("数字: "+find+" 所在位置为:"+(mid+1));
flag = false ;
break ;
}
else if(arr[mid] > find) //如果小于mid缩小范围low~mid-1
high = mid-1;
else if(arr[mid] < find) //如果大于mid缩小范围mid+1~high
low = mid+1;
}
if(flag){
System.out.println("没有找到!");
}
}
}
样例输出
- 输入
4
- 输出
数字: 4 所在位置为:2