查找算法之二分查找

参考

1. 二分查找法 | 博客园

二分查找

在有序的顺序表中查找元素,可以通过二分查找算法进行查找。

基本思想:

假设是递增序列(或者不减序列),

先通过待查找顺序表的最左端元素索引left 和最右端元素索引right求得中间元素索引middle( middle=(left+right)/2 ),然后将待查元素与中间元素比较。若待查元素>中间元素,则右移left至middle+1在较大的子序列中继续查找;若待查元素<中间元素,则左移right至middle-1在较小的子序列中继续查找;如果待查元素=中间元素,则查找成功,返回当前位置索引middle即可;如果left==midle或者right==middle还未能查找到,则查找失败。

 即:

0) 结束条件:left > right,或者已查找到目标

1) 令mid = (left+right)/2

2) 如果value == a[mid], mid即为查找到的位置,返回mid

3) 如果 value < a[mid],说明value只可能在位置[left, mid)。

那么,令right=mid-1,重新开始步骤1)进行查找。

4) 如果value > a[mid],说明value只可能在位置(mid, right]。

那么,令left=mid+1,重新开始步骤1)进行查找。

先决条件:

1. 待查存储在顺序表中(数组,而非链表);

2. 待查顺序表有序(递增,递减都可以,相邻元素相等也可以)

先看一组示例,待查找有序顺序表:array[8]={4,6,7,22,23,23,45,56}, 待查找元素t=45

步骤:

那么初始状态,left=0, right=7, => middle=(left+right)/2=3. 由array[middle]=22 < t, 右移left=middle+1=4.

Step1, 重新求得middle=(left+right)/2=5,  由array[middle]=23 < t, 右移left=middle+1=6.

Step2, 重新求得middle=(left+right)/2=6,  由array[middle]=45== t. 查找成功,返回当前位置middle=6

示例代码,为了便于快速验证、演示,用python进行编写

data = [4, 6, 7, 22, 23, 23, 45, 56] #all data to search


"""
bisearch(list, integer) -> integer
binary search for searching
@param arrary list to search
@param target element to search in the arrary
@return >=0 sucess
<0 failure
"""
def bisearch(array, target):
    left = 0
    right = len(array) - 1

    while left <= right:
        middle = (left + right) / 2
        if target > array[middle]:
            left = middle + 1
        elif target < array[middle]:
            right = middle - 1
        else:
            print 'find out %d in the arrays, index = %d.' %(target, middle)
            return middle
    print 'can not find out %d from the arrays.'%target
    return -1


print bisearch(data, 45) #sucess
print bisearch(data, 44) #failure

运行结果

find out 45 in the arrays, index = 6.
6
can not find out 44 from the arrays.
-1

二分查找变形

上述二分查找,是以查找待查值在递增(或递减)数组中的位置为目的,分为查找成功和不成功两种状态。有时候,即使查找不带待查值,也需要找到待查值在数组范围。

例子,某门课分x依据分数0,10,20,30,40,50,60,70,80,90,100分为A, B, C, D, E, F, G, H, I, J这10档,即

1)x=0 <=> A;

2)0<x<=10 <=>B;

3)10<x<=20 <=> C;

4)20<x<=30 <=> D;

5)30<x<=40 <=> E;

6)50<x<=60 <=> F;

3)60<x<=70<=> G;

3)70<x<=80<=> H;

3)80<x<=90<=> I;

3)90<x<=100<=> J;

现在要根据分数x,查找x所属成绩档。如何设计算法进行处理?

原文地址:https://www.cnblogs.com/fortunely/p/9551861.html