算法学习(二)——二分查找

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

递归实现

int bsearch(int array[], int low, int high, int target)
{
    if (low > high) return -1;
    
    int mid = (low + high)/2;
    if (array[mid]> target)
        return    bsearch(array, low, mid -1, target);
    if (array[mid]< target)
        return    bsearch(array, mid+1, high, target);
    
    //if (midValue == target)
        return mid;
}

非递归 

int binary_search(int *a, int low, int high, int target)
{
    int mid;

    while (low < high) {
        mid = low + (high - low) / 2;
        if (a[mid] > target) 
            high = mid - 1;
        else if (a[mid] < target)
            low = mid + 1;
        else 
            return mid;

    }
    return -1;
}

查找边界

当查找目标在数组中有多个时,下面的程序可以返回出现的第一个位置的下标,和最后一个位置的下标的下一个位置。

// 下界
// 以下程序当key存在时返回它出现的第一个位置,若不存在,返回这样一个下标 i,在此处插入key(原来的a[i],a[i+1],...全部往后移动一个位置)后任然有序
int
lower_bound(int *a, int low, int high, int target) { int mid; while (low < high) { mid = low + (high - low) / 2; if ( a[mid] >= target) high = mid; else low = mid + 1; } return low; }
// 上界
// 当target存在,返回它出现的最后一个位置的后一个位置
int
higher_bound(int *a, int low, int high, int target) { int mid; while (low < high) { mid = low + (high - low) / 2; if (a[mid] <= target) low = mid + 1; else high = mid; } return high; }
原文地址:https://www.cnblogs.com/ezhengnan/p/3667767.html