DSAA之补充二分查找(一)

1. 为什么要补充?

  在牛客网刷选择题的时候遇到这些概念,奇怪的是在《DSAA》中并没有提及或者详细介绍,今天扩充下,以下引用均来自维基百科,为了节约时间不再详细注明每句话的出处。

2. 二分查找

2.1 定义

Binary search works on sorted arrays. Binary search begins by comparing the middle element of the array with the target value. If the target value matches the middle element, its position in the array is returned. If the target value is less than or greater than the middle element, the search continues in the lower or upper half of the array, respectively, eliminating the other half from consideration.

  二分查找适用于已经排序的序列,在国内的教材有加上顺序存储的条件(逻辑上邻接的元素物理上也邻接,就是数组)。还有其他的叫法:half-interval search, logarithmic search, or binary chop

2.2 步骤

Given an array A of n elements with values or records A0, A1, …, An−1, sorted such that A0 ≤ A1 ≤ … ≤ An−1, and target value T, the following subroutine uses binary search to find the index of T in A.

  • Set L to 0 and R to n − 1. If L > R, the search terminates as unsuccessful.
  • Set m (the position of the middle element) to the floor, or the greatest integer less than (L + R) / 2.
  • If Am < T, set L to m + 1 and go to step 2.
  • If Am > T, set R to m − 1 and go to step 2.
  • Now Am = T, the search is done; return m.

  二分查找的最关键的地方就是medium元素的选择,到底是向下取整还是向上取整,会影响程序其他地方的处理,这个实现是向下取整。

2.2 实现

  维基没有给出直接实现,但是二分查找很简单,可以自己直接实现:

int binary_search( int * nums, int left, int right, int numsSize, int target){
    int medium;
    //基准条件可以注意必须是大于
    if(left > right )
       return 0xffff;
    medium=(left+right)>>2; 
    if(nums[medium] < target)
       return binary_search(nums,medium+1,right,numsSize,target);
    else if(nums[medium > target])
       return binary_search(nums,left,medium-1,numsSize,target);
    else 
       return target;
}   

  该递归为尾递归,可以经过尾递归消除优化提高程序运行效率。将其转换为迭代为:

int binary_search( int * nums, int left, int right, int numsSize, int target){
    int medium;
    //基准条件可以注意必须是大于
    for(;left <= right; ){
       medium=(left+right)>>2; 
       if(nums[medium] < target)
           left=medium+1;
       else if(nums[medium > target])
           right=medium-1;
       else 
           return target;
    }
    return 0xffff;
} 

  无论尾递归优化的如何,迭代的版本都减少了函数调用的开支。

2.3 时间复杂度

  该算法拥有 O ( l o g n ) 的最坏、平均时间复杂度,空间复杂度为 O ( 1 ) 。推导比较简单,笔者以前记录的二叉查找(search)树有过记录。

猜你喜欢

转载自blog.csdn.net/LoveStackover/article/details/80558504