vlambda博客
学习文章列表

细说算法之二分查找算法

    

细说算法之二分查找算法

二分查找是一种常见的查找算法,但是你真的理解么?本文将介绍二分查找及其变型,保证有收获。  

  

    二分查找算法因为其高效的查找效率不仅在计算机领域广泛应用,在日常生活中也会用到,例如当你要在一本很厚的书本中找到第200页时,你一定不会从第1页开始,一页一页地往后翻,我们通常的做法是凭感觉打开一页,假如发现是第350页,我们就知道要在前半部分查找目标,通过几次翻页,很快就会定位到第200页。这就是二分查找算法的一个简单应用,听起来似乎二分查找算法很简单,但是其具体实现起来并不十分简单。

        下面是维基百科对二分查找算法的定义:

    在计算机科学中,二分查找算法(binary search algorithm),也称折半搜索算法(half-interval search algorithm)、对数搜索算法(logarithmic search algorithm),是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

    以下以升序排列的有序数组为例对二分查找算法进行说明。

1. 常规二分查找算法


    常规二分查找,从不重复的排序数组中查找指定数字,如果存在则返回下标,不存在返回-1。举个栗子。。。

    问题描述:从有序数组{0,1,2,3,4,5,6,7,8,9}中查找数字8.


细说算法之二分查找算法

算法描述:

    令mid = (left + right)/2,

        当num[mid] > target, right = mid -1;

        当num[mid] < target, left = mid + 1;

        当num[mid] == target,则mid就是所求结果;

代码:

细说算法之二分查找算法


2. 二分查找算法变型


 查找数字出现次数

    查找某个数字出现的次数:从包含重复数字的排序数组中查找指定数字出现次数。

细说算法之二分查找算法


    问题描述:从有序数组{0,0,2,3,4,4,4,4,5,6,7}中查找数字4出现的次数。

细说算法之二分查找算法


算法描述:

    将问题拆分为求目标数字在有序数组中的最小下标和最大下标两个问题,出现的次数即为最大和最小下标之差加一,两个问题求解思路类似,以求最小下标为例说明算法过程,令mid = (left + right)/2,

    当num[mid] > target, right = mid - 1;

    当num[mid] < target, left = mid + 1;

    当num[mid] == target时,需要判断mid是不是最小下标:

如果mid - 1 >= 0,且num[mid - 1] == target, 说明mid不是最小小标,令right = mid - 1;

否则mid是最小下标,即为所求结果;


代码如下:

细说算法之二分查找算法

细说算法之二分查找算法

细说算法之二分查找算法


 翻转数组中查找数字

      从翻转数组中查找数字:将一个有序数组以中间的某个元素为中心旋转后,在其中查找某个指定元素的出现位置。

            问题描述:从翻转数组{4,5,6,7,9,10,11,0,1,2}中查找数字1。


细说算法之二分查找算法


算法描述:

    翻转数组的特点是前半部分有序,后半部分也有序,利用这个特点可将问题转换为二分查找来处理,若target落在有序的部分,即可利用二分查找来提高查找效率。

    令mid = (left + right)/2,

    当num[mid] == target, target即为所求结果;

    否则

若后半部分有序(num[mid] < num[right]),

如果target位于后半部分,则left = mid + 1;

否则right = mid - 1;

若前半部分有序(num[mid] < num[left]),

如果target位于前半部分,则right = mid - 1;

否则left = mid + 1;

代码如下:



结尾

    

        二分查找算法重点,除了折半查找思想以外,还有很重要的一点是边界条件的处理。

        二分查找,你掌握了吗?希望有所收获!