一.引子
时光荏苒,已经毕业快一年了。
仍记得计算机导论第一节课,老师曾提出一个问题,一个1~100的有序数列,有一个数就在他们当中,谁能用最少的次数猜到这个数?
你们一定猜我想到了二分查找吧!
很遗憾,当时的我初出茅庐,对此一窍不通,并没有什么好点子。
二.聊聊二分查找
其实二分查找很简单,所谓会者不难,难者不会就是这个道理。就看你能不能坐下来踏踏实实学。
还是上面这个问题,我想一定会有人用一种暴力的方法每一个数都猜一遍,如果这个数是100,岂不是要猜100次才能猜对。
采用二分法会快很多,什么是二分法呢?就是每次都猜中间的那个数,过程是这样的:
- 50 // (1 + 100) / 2 = 50
- 75 // (51 + 100) / 2 = 75
- 88 // (76 + 100) / 2 = 88
- 94 // (89 + 100) / 2 = 94
- 97 // (95 + 100) / 2 = 97
- 99 // (98 + 100) / 2 = 99
- 100 // (100 + 100) / 2 = 100
二分法仅仅用了7次就猜对了,这还是在最坏的情况下。
三.上代码
public int binarySearch(int[] arr, int num){
if(arr == null || arr.length < 1){
return -1;
}
int left = 0;
int right = arr.length - 1;
while(left <= right){
int mid = (left + right) / 2;
if(arr[mid] == num){
return mid;
}
else if(arr[mid] < num){
left = mid + 1;
}
else{
right = mid - 1;
}
}
return -1;
}
四.总结
二分法只适用于有序的序列,对于有序序列的查找是非常高效的。时间复杂度是O(log),n是序列的长度。
完整算法代码我整理在了github上。