誓死搞懂算法之二分查找

286 阅读1分钟

一.引子

时光荏苒,已经毕业快一年了。

仍记得计算机导论第一节课,老师曾提出一个问题,一个1~100的有序数列,有一个数就在他们当中,谁能用最少的次数猜到这个数?

你们一定猜我想到了二分查找吧!

很遗憾,当时的我初出茅庐,对此一窍不通,并没有什么好点子。

二.聊聊二分查找

其实二分查找很简单,所谓会者不难,难者不会就是这个道理。就看你能不能坐下来踏踏实实学。

还是上面这个问题,我想一定会有人用一种暴力的方法每一个数都猜一遍,如果这个数是100,岂不是要猜100次才能猜对。

采用二分法会快很多,什么是二分法呢?就是每次都猜中间的那个数,过程是这样的:

  1. 50 // (1 + 100) / 2 = 50
  2. 75 // (51 + 100) / 2 = 75
  3. 88 // (76 + 100) / 2 = 88
  4. 94 // (89 + 100) / 2 = 94
  5. 97 // (95 + 100) / 2 = 97
  6. 99 // (98 + 100) / 2 = 99
  7. 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(log2^n),n是序列的长度。

完整算法代码我整理在了github上。