经典案例,二分查找的三种实现方式

二分查找是建立在有序序列上的一种查找方式,所以说,前提就是被查找的序列应该是有序的。

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:
		 *
		 */
	}
}


如果大家觉得复制粘贴不方便,可以下载源文件进行测试调试。

 

下载

 

posted @ 2013-07-16 20:06  javawebsoa  Views(624)  Comments(0)    收藏  举报