二分查找

给出一个有序数组A[0...n-1]和一个值key,返回key在A[]中的位置或者不存在,要求log n复杂度。

C标准库中有一个bsearch(),原型为:

 void * bsearch ( const void * key, const void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );

bsearch()返回第一个找到的位置,而不是首个位置。

通用的方法:给出元素首次出现的位置(最小下标)

int bs(int A[], int low, int high, int key)
{
    int mid;
    while (low < high) {
        mid = (high-low)/2 + low;
        if (A[mid] < key) low = mid+1;
        else high = mid;
    }
    return (A[low]==key) ? low:-1;
}

分析:

1. 循环终止的条件是low>=high, 如果传入的low<high,那么必然不会出现low>high的情况也即循环只在low=high时终止,因为在while循环中mid=(high+low)/2 < high,low<=mid+1<=high;

2. 如果A[low, high]中有值为key的元素,返回的是最小下标:

  (1)可以确定的是A[high]>=key总是成立的,因为初始时A[high]>=key,且只有A[mid]>=key时才更新high;

  (2)更新low的条件是A[mid]<key => A[low]<key,即low只在A[low]<key时更新,更新后A[low=mid+1]<=key && A[mid]<key,所以A[low]=key时,low为最小下标,low最终更新为A[low]=key;

     (3)当low=high即循环终止时,A[high]>=key,A[low]=key,所以A[high]=A[low]=key,且low为最小下标

原文地址:https://www.cnblogs.com/txd0u/p/3390805.html