我所知道的查找算法之二分查找法
作者前言
大家好,我是阿濠,今篇内容跟大家分享的是查找算法之二分查找法
一、介绍二分查找法
是一种在有序数组中
查找
某一特定元素
的搜索算法。
1.搜索过程从数组的
中间元素开始
,如果中间元素
正好
是要查找的元素
,则搜索结束
2.如果某一特定元素大于或者小于中间元素
,则在
数组大于或小于中间元素的那一半中
查找,而且重新开始
从中间元素
进行比较。
3.如果在某一步骤数组为空
,则代表找不到
。这种搜索算法每一次比较都使搜索范围缩小一半
。
二、示例认识线性查找算法
对有序数组进行二分查找{1, 8, 10, 89, 1000, 1234}
输入一个数
,看看该数组是否存在
此数并且求出下标
,如果没有
就提示"没有这个数
"。
步骤思路
1.确定数组中间数
的下标mid
=(left+right)/2
2.将查询
的数
findValue
和
中间数arr[mid]
进行
比较
3.若findVale>arr[mid]
,则说明查找的数findValue在右边
,进行递归向右查询
4.若findVale<arr[mid]
,则说明查找的数findValue在左边
,进行递归向左查询
5.若findVale = =arr[mid]
,则说明查找的
数已找到并返回下标
结束递归思路
1.找到
findValue
值结束
递归
2.数组递归完仍未找到findValue
也结束递归,当left>right
结束递归退出
//二分查找算法
/**
*
* @param arr 数组
* @param left 左边的索引
* @param right 右边的索引
* @param findVal 要查找的值
* @return 如果找到就返回下标,如果没有找到,就返回-1
*/
public static int binarySearch(int[] arr, int left, int right, int findVal) {
//一、没有找到的情况
if(left > right){
return -1;
}
//二、找到的情况
//中间下标
int mid = (left + right) / 2;
int midVal =arr[mid];//中间下标对应的值
if(findVal>midVal) {
//若`findVale>arr[mid]`,则说明查找的数`findValue在右边`,进行递归`向右查询`
return binarySearch(arr, mid + 1, right, findVal);
}else if (findVal<midVal){
//若`findVale<arr[mid]`,则说明查找的数`findValue在左边`,进行递归`向左查询`
return binarySearch(arr,left,mid-1,findVal);
}else{
//若`findVale = =arr[mid]`,则说明`查找的数已找到并返回下标`
return mid;
}
}
public static void main(String[ ] args) {
int arr[]={ 1, 8, 10, 89, 1000, 1234};
int rearchIndex = binarySearch(arr,0,arr.length-1,8);
if(rearchIndex == -1) {
System. out. println("没有找到");
} else {
System .out. println("找到,下标为=" + rearchIndex);
}
}
运行结果如下:
找到,下标为 = 1
三、数组中出现重复数值
有序数组:{1,8, 10, 89, 1000, 1000, 1234}
,有多个相同的数
值
时,如何将
所有的数值
都查找到
,比如这里的1000
.
//二分查找算法
/**
* 课后思考题: {1,8, 10,89,1000, 1000, 1234} 当一个有序数组中,
* 有多个相同的数值时,如何将所有的数值都查找到,比如这里的1000
*
* 思路分析
* 1.在找到mid 索引值,不要马上返回.
* 2.向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
* 3.向mid 索引值的右边扫描,将所有满足1000, 的元素的下标,加入到集合ArrayList
* 4.将Arraylist返 回
*/
public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
//一、没有找到的情况
if(left > right){
return new ArrayList<Integer>();
}
//二、找到的情况
//中间下标
int mid = (left + right) / 2;
int midVal =arr[mid];//中间下标对应的值
if(findVal>midVal) {
//若`findVale>arr[mid]`,则说明查找的数`findValue在右边`,进行递归`向右查询`
return binarySearch2(arr, mid + 1, right, findVal);
}else if (findVal<midVal){
//若`findVale<arr[mid]`,则说明查找的数`findValue在左边`,进行递归`向左查询`
return binarySearch2(arr,left,mid-1,findVal);
}else{
/**思路分析
* 1.在找到mid 索引值,不要马上返回.
* 2.向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
* 3.向mid 索引值的右边扫描,将所有满足1000, 的元素的下标,加入到集合ArrayList
* 4.将Arraylist返回
* */
ArrayList<Integer> rearchIndexlist=new ArrayList<Integer>();
//向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
int temp= mid - 1;
while(true){
//证明向mid 索引值的左边扫描 没有找到相同的findValue值
if(temp < 0 || arr[temp] != findVal ){
break;
}
//证明有相同的findValue值,放入rearchIndexlist里
rearchIndexlist.add(temp);
temp -= 1;//向左移
}
//将找到的mid 索引值 放入rearchIndexlist 中
rearchIndexlist.add(mid);
//向mid 索引值的右边扫描,将所有满足1000, 的元素的下标,加入到集合ArrayList
temp= mid + 1;
while(true){
//证明向mid 索引值的右边扫描 没有找到相同的findValue值
if(temp > arr.length -1 || arr[temp]!= findVal ){
break;
}
//证明有相同的findValue值,放入rearchIndexlist里
rearchIndexlist.add(temp);
temp += 1;//向右移
}
return rearchIndexlist;
}
}
public static void main(String[ ] args) {
int arr[]={ 1, 10, 89, 1000, 1000, 1234};
List integerList= binarySearch2(arr,0,arr.length-1,1000);
System.out.println("找到的所有值:"+ integerList);
}
运行结果如下:
找到的所有值:[3,4]