概述:
举个例子,好比KTV上来一批美女(100个),按身高从矮到高排序,每人将身高写在脑门上,现在要从这些人中找出张馨予,用肉眼一个个看肯定太慢了,用2分法如何找?
首先我知道张馨予身高169cm,美女集群中最高的是2米,最矮的是1.6米,取2米和1.6的中间身高是1.8,1.69小于1.8,说明张馨予肯定是在前半截,然后将最高值设为1.8,再在1.6和1.8之间再取平均数,不断进行轮回,直到start身高大于end身高时终止。
注意:二分法必然是排序好的数据,否则不准
用Java举例如下
package com.maizijf.test.test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Created by Germmy on 2018/5/19.
*/
public class TestBinarySearch {
// private int array[]={1,3,4,6,8,9};
private int array[] = {1, 3, 4};
@Before
public void init() {
}
@Test
public void testBinarySearch() {
int rst;
rst = binarySearch(array, 6);
Assert.assertEquals(-1, rst);
rst = binarySearch(array, 1);
Assert.assertEquals(1, rst);
rst = binarySearch(array, 3);
Assert.assertEquals(3, rst);
rst = binarySearch(array, 4);
Assert.assertEquals(4, rst);
}
/**
* 解决了长度为2的问题,当发现长度为2或者currIndex在尾指针还差1时,强行比较这2个元素
*
* @param array
* @param num
*/
private int binarySearch(int array[], int num) {
int startIndex = 0;
int endIndex = array.length - 1;
int currIndex = 0;
while (true) {
currIndex = (startIndex + endIndex) / 2;
if (num < array[currIndex]) {
endIndex = currIndex - 1;//一定要让指针强行移动
} else if (num > array[currIndex]) {
startIndex = currIndex + 1;//一定要让指针强行移动
} else if (num == array[currIndex]) {
System.out.println("找到了");
return num;
}
if (startIndex > endIndex) {
System.out.println("絮贫僧无能,找不到");
return -1;
}
}
}
}
注意到:当发现目标值大于或者小于一半的值后,startIndex或者endIndex的索引一定要+1,不能在原地,否则当startIndex和endIndex只差1个时,指针将永远停止,会导致一些数永远查不到
运行结果如下