经典案例,二分查找的三种实现方式
二分查找是建立在有序序列上的一种查找方式,所以说,前提就是被查找的序列应该是有序的。
1while方式实现的二分查找:
public static boolean binarySearchWithWhile(int[] array , int val)
{
int start = 0 ;
int end = array.length-1;
/**
* 因为二分查找是针对有序序列的
* 所以说,我们假如序列是升序的
* 如果:val<最小的 或者大于最大的
* 我们认为,这个val不存在于我们的array中
*/
if(val<array[start] || val>array[end])
{
searchError(val);
return false;
}
boolean flag = true;
while(flag)
{
/**
* 当我们要查找的val根本确实不存在于我们的array中的时候
* 退出二分查找的条件:start>end
*/
if(start > end)
{
searchError(val);
return false;
}
int middle = (start+end)/2;
if(val == array[middle])
{
searchOk(val, middle);
return true;
}
// 查找的元素在右侧部分
else if(val > array[middle])
{
start=middle+1;
}
// 查找的元素在左侧部分
else
{
end=middle-1;
}
}
return false;
}
2for方式实现的二分查找:
public static boolean binatySearchWithFor(int[] array , int val)
{
int start = 0;
int end = array.length-1;
if(val<array[start] || val>array[end])
{
searchError(val);
return false;
}
// 其实,这种虽然使用的是for循环,但是实际上,和while的机制一样
for(;start<=end ;)
{
int middle = (start+end)/2;
// 如果查找到
if(val == array[middle])
{
searchOk(val, middle);
return true;
}
// 代表我们要查找的数字可能在左侧部分
else if(val < array[middle])
{
end = middle -1;
}
else
{
start = middle+1;
}
}
// 走到这一步代表我们没有找到我们要找的数字
searchError(val);
return false;
}
3递归方式实现的二分查找
// 递归的方式实现二分查找 , 递归需要重新构建数组,或者在参数上确定数组下标范围,所以我们使用下标来确定
public static boolean binarySearchWithRecursion(int[] array ,int start,int end ,int val)
{
// 每次递归,都把start赋值为0 这样不合理
// start = 0;
// end = array.length-1;
int middle = (start+end)/2;
if(val > array[end] || val < array[start])
{
searchError(val);
return false;
}
if(val == array[middle])
{
searchOk(val, middle);
return true;
}
// val 在右侧
else if(val> array[middle])
{
return binarySearchWithRecursion(array, middle+1,end, val);
}
// val 在左侧
else
{
return binarySearchWithRecursion(array, start, middle-1, val);
}
}
测试以及解析:
public static void main(String[] args) {
int[] array = new int[]{1,3,4,5,7,10,11,12};
System.out.println("使用while的方法解析 查找存在的数字======【开始】=======");
BinarySearch.binarySearchWithWhile(array, 7);
/**
* (1)start=0,end=7,middle=(start+end)/2=3
* array[3]=5,7>5
* 所以数据在右侧,start=middle+1=3+1=4
*
* (2)start=4,end=7,middle=(start+end)/2=5
* array[5]=10,7<10,
* 所以数据在左侧,start=4,end=middle-1=5-1=4
*
* (3)start=4,end=4,middle=(start+end)/2=4
* array[4]=7,7=7
* 所以此刻我们查找到了我们的数据7,下标是middle,下标是4
*/
System.out.println("使用while的方法解析 查找不存在的数字=============");
/**
* (1)start=0,end=7,middle=(start+end)/2=3
* array[3]=5,6>5
* 所以数据在右侧,start=middle+1=3+1=4
* (2)start=4,end=7,middle=(start+end)/2=5
* array[5]=10,6<10
* 所以数据在左侧,end=middle-1=5-1=4
* (3)start=4,end=4,middle=(start+end)/2=4
* array[4]=7,6<7
* 所以数据在左侧,end=middle-1=4-1=3
* 此刻:start>end
* 所以我们判断6不存在与我们的数组中
*/
BinarySearch.binarySearchWithWhile(array, 6);
System.out.println("使用while的方法解析======【结束】=======");
/**
* for循环和while循环的机制一样
*/
BinarySearch.binatySearchWithFor(array, 6);
System.out.println("=================================");
System.out.println("=============递归=================");
System.out.println("==========查找存在的数字==============");
BinarySearch.binarySearchWithRecursion(array,0,array.length-1 ,7);
/**
* 递归方式查找解析:
*A:(1)start=0,end=7,middle=(start+end)/2=3
*array[3]=5,7>5
*E:接收到D,D来自C所以打印:恭喜 ,您要查找的数字:7已经找到,其下标为:4
* B:数据在右侧
* 递归-start=middle+1=3+1=4
* binarySearchWithRecursion(array,middle+1,end,val)
* 也就是:
* binarySearchWithRecursion(array,4,7,7)
* (1)start=4,end=7,middle=(start+end)/2=(4+7)/2=11/2=5
* array[5]=10,val<10(7<10)
* D:
* C:数据在左侧
* 递归-end=middle-1=5-1=4
* binarySearchWithRecursion(array,start,middle-1,val)
* 也就是:
* binarySearchWithRecursion(array,4,5-1,7)
* (1)start=4,end=(5-1)=4,middle=(start+end)/2=(4+4)/2=4
* array[4]=7,7=val(7=7)
* 所以此刻我们找到数据,返回所以true,索引为middle(middle此刻为4)
* 将数据返回到D处
*
*/
System.out.println("=================================");
System.out.println("=============递归=================");
System.out.println("==========查找不存在的数字==============");
BinarySearch.binarySearchWithRecursion(array,0,array.length-1 ,6);
/**
* A:(1)start=0,end=7,middle=(start+middle)/2=(0+7)/2=3
* array[3]=5,6>5
* 数据在右侧
* D:
* 打印出-对不起 ,您要查找的数字:6不存在
* B:(1)递归-start=middle+1=(3+1)=4
* binarySearchWithRecursion(array,start,end,val)
* 也就是
* binarySearchWithRecursion(array,3+1,7,6)
* (2)start=4,end=7,middle=(start+end)/2=(4+7)/2=5
* array[5]=10,【array[start]=7 val<array[start]】
* 所以,retur false
* 返回到D:
*
*/
}
首先,二分查找很重要,其次如果大家能够明白这三种凡是实现的二分查找,那么说明大家对于递归以及二分查找的原理也就认识的比较透彻了。
下面给出全部的代码,方便大家调试:
package com.luzhiming.binarysearch;
/**
* @author fighter24h E-mail: 645707787@QQ.com
* @version 创建时间:2013-7-15 下午2:53:12
*
*/
public class BinarySearch {
private static void searchOk(int val , int index)
{
System.out.println("恭喜 ,您要查找的数字:"+val+"已经找到,其下标为:"+index);
}
private static void searchError(int val)
{
System.out.println("对不起 ,您要查找的数字:"+val+"不存在");
}
// while方式的二分查找
public static boolean binarySearchWithWhile(int[] array , int val)
{
int start = 0 ;
int end = array.length-1;
/**
* 因为二分查找是针对有序序列的
* 所以说,我们假如序列是升序的
* 如果:val<最小的 或者大于最大的
* 我们认为,这个val不存在于我们的array中
*/
if(val<array[start] || val>array[end])
{
searchError(val);
return false;
}
boolean flag = true;
while(flag)
{
/**
* 当我们要查找的val根本确实不存在于我们的array中的时候
* 退出二分查找的条件:start>end
*/
if(start > end)
{
searchError(val);
return false;
}
int middle = (start+end)/2;
if(val == array[middle])
{
searchOk(val, middle);
return true;
}
// 查找的元素在右侧部分
else if(val > array[middle])
{
start=middle+1;
}
// 查找的元素在左侧部分
else
{
end=middle-1;
}
}
return false;
}
// for方式的二分查找
public static boolean binatySearchWithFor(int[] array , int val)
{
int start = 0;
int end = array.length-1;
if(val<array[start] || val>array[end])
{
searchError(val);
return false;
}
// 其实,这种虽然使用的是for循环,但是实际上,和while的机制一样
for(;start<=end ;)
{
int middle = (start+end)/2;
// 如果查找到
if(val == array[middle])
{
searchOk(val, middle);
return true;
}
// 代表我们要查找的数字可能在左侧部分
else if(val < array[middle])
{
end = middle -1;
}
else
{
start = middle+1;
}
}
// 走到这一步代表我们没有找到我们要找的数字
searchError(val);
return false;
}
// 递归的方式实现二分查找 , 递归需要重新构建数组,或者在参数上确定数组下标范围,所以我们使用下标来确定
public static boolean binarySearchWithRecursion(int[] array ,int start,int end ,int val)
{
// 每次递归,都把start赋值为0 这样不合理
// start = 0;
// end = array.length-1;
int middle = (start+end)/2;
if(val > array[end] || val < array[start])
{
searchError(val);
return false;
}
if(val == array[middle])
{
searchOk(val, middle);
return true;
}
// val 在右侧
else if(val> array[middle])
{
return binarySearchWithRecursion(array, middle+1,end, val);
}
// val 在左侧
else
{
return binarySearchWithRecursion(array, start, middle-1, val);
}
}
public static void main(String[] args) {
int[] array = new int[]{1,3,4,5,7,10,11,12};
System.out.println("使用while的方法解析 查找存在的数字======【开始】=======");
BinarySearch.binarySearchWithWhile(array, 7);
/**
* (1)start=0,end=7,middle=(start+end)/2=3
* array[3]=5,7>5
* 所以数据在右侧,start=middle+1=3+1=4
*
* (2)start=4,end=7,middle=(start+end)/2=5
* array[5]=10,7<10,
* 所以数据在左侧,start=4,end=middle-1=5-1=4
*
* (3)start=4,end=4,middle=(start+end)/2=4
* array[4]=7,7=7
* 所以此刻我们查找到了我们的数据7,下标是middle,下标是4
*/
System.out.println("使用while的方法解析 查找不存在的数字=============");
/**
* (1)start=0,end=7,middle=(start+end)/2=3
* array[3]=5,6>5
* 所以数据在右侧,start=middle+1=3+1=4
* (2)start=4,end=7,middle=(start+end)/2=5
* array[5]=10,6<10
* 所以数据在左侧,end=middle-1=5-1=4
* (3)start=4,end=4,middle=(start+end)/2=4
* array[4]=7,6<7
* 所以数据在左侧,end=middle-1=4-1=3
* 此刻:start>end
* 所以我们判断6不存在与我们的数组中
*/
BinarySearch.binarySearchWithWhile(array, 6);
System.out.println("使用while的方法解析======【结束】=======");
/**
* for循环和while循环的机制一样
*/
BinarySearch.binatySearchWithFor(array, 6);
System.out.println("=================================");
System.out.println("=============递归=================");
System.out.println("==========查找存在的数字==============");
BinarySearch.binarySearchWithRecursion(array,0,array.length-1 ,7);
/**
* 递归方式查找解析:
*A:(1)start=0,end=7,middle=(start+end)/2=3
*array[3]=5,7>5
*E:接收到D,D来自C所以打印:恭喜 ,您要查找的数字:7已经找到,其下标为:4
* B:数据在右侧
* 递归-start=middle+1=3+1=4
* binarySearchWithRecursion(array,middle+1,end,val)
* 也就是:
* binarySearchWithRecursion(array,4,7,7)
* (1)start=4,end=7,middle=(start+end)/2=(4+7)/2=11/2=5
* array[5]=10,val<10(7<10)
* D:
* C:数据在左侧
* 递归-end=middle-1=5-1=4
* binarySearchWithRecursion(array,start,middle-1,val)
* 也就是:
* binarySearchWithRecursion(array,4,5-1,7)
* (1)start=4,end=(5-1)=4,middle=(start+end)/2=(4+4)/2=4
* array[4]=7,7=val(7=7)
* 所以此刻我们找到数据,返回所以true,索引为middle(middle此刻为4)
* 将数据返回到D处
*
*/
System.out.println("=================================");
System.out.println("=============递归=================");
System.out.println("==========查找不存在的数字==============");
BinarySearch.binarySearchWithRecursion(array,0,array.length-1 ,6);
/**
* A:(1)start=0,end=7,middle=(start+middle)/2=(0+7)/2=3
* array[3]=5,6>5
* 数据在右侧
* D:
* 打印出-对不起 ,您要查找的数字:6不存在
* B:(1)递归-start=middle+1=(3+1)=4
* binarySearchWithRecursion(array,start,end,val)
* 也就是
* binarySearchWithRecursion(array,3+1,7,6)
* (2)start=4,end=7,middle=(start+end)/2=(4+7)/2=5
* array[5]=10,【array[start]=7 val<array[start]】
* 所以,retur false
* 返回到D:
*
*/
}
}
如果大家觉得复制粘贴不方便,可以下载源文件进行测试调试。

浙公网安备 33010602011771号