什么是折半查找?
折半查找其实通过字面上的意思就是大致就可以理解为每次查找的时候
选取中间下标的值进行查找.
如果找不到,就判断这个要查找的数大于还是小于这个这个中间下标的值.
如果大于,就把这个中间值的下标+1给到左边的下标
中间下标 就等于 左下标 加 右边下标 除以2
如果小于,就把这个中间值的下标-1给到右边的下标
中间下标 就等于 左下标 加 右边下标 除以2
以此类推直到找到为止...
当左边的下标大于右边的下标时,说明这个要找的值不存在.
这里还有个最重要的,那就是折半查找,只能查找已经排好序的(不管升序还是降序)
假定定义一个数组int arr = {2, 7, 15, 21, 34, 45, 57, 61, 102, 120}
我们要查找的是 7是否在这个数组上
画个图是这样的:
现在假设要查找的值,不在数组的情况下
假设我们要找的是3
图片链接:百度网盘
下面是java源代码
public class day05_13 { //类名
public static void main(String[] args){ //主函数
int[] arr = {2, 7, 15, 21, 34, 45, 57, 61, 102, 120};
int fis, in, tail; //fise不能定义变量所以用 fis 首, in 中, tail 尾
int key; //用于输入用户要查找的数
int num; //接受数组的下标
key = 7; //假设用户要找的是7
fis = 0;
tail = arr.length-1;
in = (fis+tail)/2;
while(true)
{
if(arr[in] > key) //中间数值大于要找的值
{
tail = in - 1; //把中间的下标-1给到右值
}
else if(arr[in] < key) //中间数值小于要找的值
{
fis = in + 1; //把中间的下标+1给到右值
}
else //这种是等于的情况
{
num = in;
break;
}
if(fis>tail) //当左边的大于右边的时候,说明没有数组内没有要找的值
{
num = -1;
break;
}
in = (fis+tail)/2;
}
System.out.println("查找的数组下标为:"+num);
}
}
代码执行之后的结果
下面这个是利用自定义函数写的源代码:
public class day05_14 { //类名
public static void main(String[] args)
{
int[] arr = {2, 7, 15, 21, 34, 45, 57, 61, 102, 120};
int num; //接受数组的下标
num = find(arr, 7);
System.out.println("查找的数组下标为:"+num);
}
//折半查找
public static int find(int[] arr, int key){
int fis, tail, in; //fise不能定义变量所以用 fis 首, in 中, tail 尾
fis = 0;
tail = arr.length-1;
in = (fis+tail)/2;
while(arr[in] != key)
{
if(arr[in] > key) //中间数值大于要找的值
{
tail = in - 1; //把中间的下标-1给到右值
}
else if(arr[in] < key) //中间数值小于要找的值
{
fis = in + 1; //把中间的下标+1给到右值
}
if(fis > tail) //当左边的大于右边的时候,说明没有数组内没有要找的值
{
return -1; //返回-1
}
in = (fis + tail)/2;
}
return in;
}
}
.
.
.
更简洁的代码:
public class day05_15 { //类名
public static void main(String[] args){ //主函数
int[] arr = {3, 4, 7, 9, 12, 18, 21, 41, 56, 71, 87, 90};
int index = halfSearch(arr, 9); //index 获取要找数值的数组的下标
System.out.println("index="+index); //输出找到的下标
}
//函数功能:折半查找
public static int halfSearch(int[] arr, int key){
int min = 0;
int max = arr.length-1;
while( min <= max)
{
int mid = (min+max)>>1; //向左移动一位,相当于除以2
if(key> arr[mid]) //要找的值大于中间值的时候
{
min = mid-1;
}
else if (key < arr[mid]) //要找的值小于中间值的时候
{
max = mid +1;
}
else
{
return mid; //相等的时候
}
}
return -1; //min>max说明要找的树没有在数组中,返回-1
}
}