【问题标题】:binary search only using length?二进制搜索只使用长度?
【发布时间】:2015-07-23 07:16:24
【问题描述】:

所以我写了一个二分查找函数,它接受一个整数数组、一个低索引搜索值、一个高索引搜索值和一个校验值:

int binarySearch(int d[], int low, int high, int check)  
{
int mid = (high-low)/2 + low;

if(low > high)
    return -1;

if(d[mid] == check)
    return mid;
else if(check > d[mid])
    return binarySearch(d, mid+1, high, check);
else
    return binarySearch(d, low, mid-1, check);
}

但是,我被要求编写一个只接受数据数组、数组长度和搜索值的二分搜索函数?如果没有低变量和高变量,我怎么能做到这一点?如何根据大小声明低变量和高变量?

int binSearch(int d[], int size, int check)

【问题讨论】:

  • 将(尾)递归函数转换为非递归循环。然后low可以是一个初始值为0的局部变量。或者写一个包装函数到binarySearch

标签: arrays algorithm search binary


【解决方案1】:

这取决于语言。

在 C 中,可以通过更改指向数组头部的指针,而不是考虑整个数组,只考虑它的第二半。

if in 1st half:
    arr = arr // unchanged
    size = size/2 //only the size and thus end point change
if in 2nd half:
    arr = arr + size/2  //only the 2nd half is considered
    size = size/2 //and size is also changing

当从递归调用返回时,你当然需要将你在第二种情况下添加的间隙添加到答案中。

在 java 中,你不能真正有效地做到这一点(假设你仍然想要递归二进制搜索),因为数组是一个你不能(很好地)改变起点的对象。您当然可以创建相关子数组的副本 - 但这会失去二分搜索的效率。

【讨论】:

    【解决方案2】:

    您可以将函数重写为循环,其中递归被替换为另一个通过具有其他变量值的循环的传递。循环变量可以是局部变量,不必在接口中公开。在对二分查找函数的递归调用中,您只需调整一个参数,lowhigh,这使得重写函数变得容易:

    int binarySearch(int d[], int length, int check)  
    {
        int low = 0;
        int high = length;
    
        while (low < high) {
            int mid = (high - low) / 2 + low;
    
            if (d[mid] == check) return mid;
    
            if (check > d[mid]) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
    
        return -1;
    }
    

    请注意,我使用了一种稍微不同的方式来描述当前搜索的子数组:low 是包含的下限,但上限 high 是独占的。这是使用从零开始的数组索引的语言中范围的自然表示。然后由low == high 表示一个空子数组。

    【讨论】:

      【解决方案3】:

      这很简单 - 事实上,您几乎完成了:您所需要的只是一个围绕递归函数的单行包装器,它将四参数函数转换为三参数函数。

      编写匹配所需签名的函数:

      int binSearch(int d[], int size, int check) {
          return binarySearch(d, 0, size-1, check);
      }
      

      当然,您也可以使用指针:不要将low 作为单独的参数传递,您可以将&amp;d[low] 作为新的d 传递,并将high-low 作为长度传递。

      【讨论】:

      • 我不认为这是面试官要求不同签名时的意思,但可能是错误的。函数签名中缺少可见性修饰符表明 c.
      • @amit 他写的是int d[] 而不是int[] d 这表明它可能不是Java :-) 我也不确定这是一个面试问题——它很可能是一所学校任务。
      • 和 OP 中 foo() &lt;newline&gt; { 的约定(恶心,我知道!)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-10
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多