上一篇用递归实现二分法,十分丑陋,当时的想法焦点集中在去寻找二分的中心移动上,
这回把焦点放在两边的边界上,判断中心值与待查找目标的大小,调整两边的边界,继续判断,不断压缩搜索的空间,这样,不用构造新的数组,算法实现更加优雅
代码如下:
package org.test.algorithm;
/**
* 二分法搜索
* 《离散数学及其应用》P100
* @author ytdaguang_shan@126.com
* @since 2012-5-18
*
*/
public class BinarySearch {
/**
* 二分搜索
* 把关注点放在两端的边界上
* 根据中间元素检测的结果不断修改两边的边界位置,而不是修改中间指针的位置(这种方式的算法依赖于递归)
* 得到了更优雅简洁的非递归方案
* @param numAimed 待搜索数字
* @param arrSrc 源数组
* @return 找到则返回索引,否则-1
*/
public static int binarySearch(int numAimed,int[] arrSrc){
int startIndex = 0;
int endIndex = arrSrc.length-1;
while(startIndex<endIndex){
int middleIndex = startIndex+(endIndex-startIndex)/2;
if(numAimed>arrSrc[middleIndex]){
startIndex = middleIndex+1;//+1 不断压缩搜索空间,直至首尾变成一个
}else{
endIndex = middleIndex;
}
}
if(arrSrc[startIndex]==numAimed){
return startIndex;
}
return -1;
}
}
package org.test.algorithm;
import junit.framework.TestCase;
public class BinarySearchTest extends TestCase {
private static int[] srcArr;
public void testBinarySearch() {
init();
assertEquals(3,BinarySearch.binarySearch(78, srcArr));
assertEquals(4,BinarySearch.binarySearch(900, srcArr));
assertEquals(0,BinarySearch.binarySearch(2, srcArr));
}
private static void init(){
//===============准备待搜索源数组======================
srcArr = new int[]{2,34,56,78,900};
/**
* random 1~10
*/
int randomStep = (int)Math.random()*10;
/**
* 填充数组 元素整数递增,递增间隔10以内随机数
*/
// for(int i=0;i<srcArr.length;i++){
// if(i==0){
// srcArr[i] = i+randomStep;
// }else{
// srcArr[i] = srcArr[i-1]+randomStep;
// }
// }
//=====================================
}
}