C 二进制搜索给了我一个错误

C 二进制搜索给了我一个错误,c,C,我正在尝试运行这个二进制搜索的实现。我不知道为什么,但它总是给我错误。我想问题可能是我传递数组的方式,或者递归调用有问题 #include <stdio.h> int hasBinarySearch(int *array, int low, int high, int element) { int mid = (low + (high-low)) / 2; if (high>=low) { if (array[mid] == element)

我正在尝试运行这个二进制搜索的实现。我不知道为什么,但它总是给我错误。我想问题可能是我传递数组的方式,或者递归调用有问题

#include <stdio.h>

int hasBinarySearch(int *array, int low, int high, int element)
{

    int mid = (low + (high-low)) / 2;

  if (high>=low)
  {

    if (array[mid] == element)
    {
      return mid;
    }
    else if(array[mid]<element)
    {
        return hasBinarySearch(array, low, mid-1, element);
    }
    else
    {
      return hasBinarySearch(array, mid+1, high, element);
    }
  }

  return 0;
}



int main(void)
{
  int array[10] = {1,2,3,4,5,6,6,6,7,8};
  hasBinarySearch(array, 0, 9, 2);

  return 0;
}
#包括
int hasBinarySearch(int*数组、int低、int高、int元素)
{
int-mid=(低+(高-低))/2;
如果(高>=低)
{
if(数组[mid]==元素)
{
中途返回;
}

否则如果(array[mid]我认为您对二进制搜索有一些误解。请阅读一些关于它的文章或书籍

正如@Claies所评论的,中间索引的计算是错误的。 它应该是low+(high-low)/2。想想数学中两点的内部划分

此外,还必须修复递归调用上的参数,如下面的代码

#include <stdio.h>

int hasBinarySearch(int *array, int low, int high, int element)
{

    int mid = low + (high - low) / 2; // changed
    printf("%d %d\n", high, low);
    if (high >= low)
    {
        if (array[mid] == element)
        {
            return mid;
        }
        else if (array[mid] < element)
        {
            return hasBinarySearch(array, mid + 1, high, element); // changed
        }
        else
        {
            return hasBinarySearch(array, low, mid - 1, element); // changed
        }
    }
    return 0;
}

int main(void)
{
    int array[10] = { 1,2,3,4,5,6,6,6,7,8 };
    hasBinarySearch(array, 0, 9, 2);
    return 0;
}
#包括
int hasBinarySearch(int*数组、int低、int高、int元素)
{
int mid=low+(高-低)/2;//已更改
printf(“%d%d\n”,高,低);
如果(高>=低)
{
if(数组[mid]==元素)
{
中途返回;
}
else if(数组[mid]<元素)
{
return hasBinarySearch(数组,中+1,高,元素);//已更改
}
其他的
{
return hasBinarySearch(数组,低位,中间-1,元素);//已更改
}
}
返回0;
}
内部主(空)
{
int数组[10]={1,2,3,4,5,6,6,6,7,8};
hasBinarySearch(数组,0,9,2);
返回0;
}

我认为您对二进制搜索有一些误解。请阅读一些关于二进制搜索的文章或书籍

正如@Claies所评论的,中间索引的计算是错误的。 它应该是low+(high-low)/2。想想数学中两点的内部划分

此外,还必须修复递归调用上的参数,如下面的代码

#include <stdio.h>

int hasBinarySearch(int *array, int low, int high, int element)
{

    int mid = low + (high - low) / 2; // changed
    printf("%d %d\n", high, low);
    if (high >= low)
    {
        if (array[mid] == element)
        {
            return mid;
        }
        else if (array[mid] < element)
        {
            return hasBinarySearch(array, mid + 1, high, element); // changed
        }
        else
        {
            return hasBinarySearch(array, low, mid - 1, element); // changed
        }
    }
    return 0;
}

int main(void)
{
    int array[10] = { 1,2,3,4,5,6,6,6,7,8 };
    hasBinarySearch(array, 0, 9, 2);
    return 0;
}
#包括
int hasBinarySearch(int*数组、int低、int高、int元素)
{
int mid=low+(高-低)/2;//已更改
printf(“%d%d\n”,高,低);
如果(高>=低)
{
if(数组[mid]==元素)
{
中途返回;
}
else if(数组[mid]<元素)
{
return hasBinarySearch(数组,中+1,高,元素);//已更改
}
其他的
{
return hasBinarySearch(数组,低位,中间-1,元素);//已更改
}
}
返回0;
}
内部主(空)
{
int数组[10]={1,2,3,4,5,6,6,6,7,8};
hasBinarySearch(数组,0,9,2);
返回0;
}

mid
的计算简化为
high/2
,因为您已经添加了下限,然后又减去了下限。看起来您想在下限上添加一半的差异,但是除法发生得太晚了。它应该是
low+(high-low)/2
。(这比
(低+高)/2有点复杂,但避免了其他地方提到的整数数学问题。)

我认为当
high
低于
low
并且变得太小时,就会发生segfault,从而从数组的开头掉下来


而且@Paganist关于上下两个大写字母向后的说法是正确的。

mid
的计算简化为
high/2
,因为您已经添加了下限,然后又减去了下限。看起来您想在下限上添加一半的差异,但是除法发生得太晚了。它应该是
>low+(高-低)/2
(这比
(低+高)/2
复杂一点,但避免了其他地方提到的整数数学问题。)

int mid = (low + (high-low)) / 2; // wrong formula
我认为当
high
低于
low
并且变得太小时,就会发生segfault,从而从数组的开头掉下来

“异教徒”关于大写字母和小写字母的说法是正确的

int mid = (low + (high-low)) / 2; // wrong formula
好答案指出了OP搜索方法中的缺陷,并进行了修复


但仍需深入挖掘

即使某些编译器可能能够“取消递归”代码(),这里也不需要递归。一个简单的循环就足够了

在极端情况下,数组大小可能接近最大值或超过
int
的范围。
对于高
int
范围内的尺寸,以下更好

要容纳所有数组大小,请在
int
上使用
size\u t
。这也处理大小,包括
int\u MAX
附近和以上的大小


候选解决方案,返回匹配元素的地址,如果未找到,则返回
NULL

#include <stdlib.h>
#include <stdio.h>

int *BinarySearch_int(const int *array, size_t count, int key) {
  while (count > 0) {
    size_t mid = count / 2;
    if (key > array[mid]) {
      array += mid + 1;
      count -= mid + 1;
    } else if (key < array[mid]) {
      count = mid;
    } else {
      return (int *) &array[mid];
    }
  }
  return NULL;
}
好答案指出了OP搜索方法中的缺陷,并进行了修复


但仍需深入挖掘

即使某些编译器可能能够“取消递归”代码(),这里也不需要递归。一个简单的循环就足够了

在极端情况下,数组大小可能接近最大值或超过
int
的范围。
对于高
int
范围内的尺寸,以下更好

要容纳所有数组大小,请在
int
上使用
size\u t
。这也处理大小,包括
int\u MAX
附近和以上的大小


候选解决方案,返回匹配元素的地址,如果未找到,则返回
NULL

#include <stdlib.h>
#include <stdio.h>

int *BinarySearch_int(const int *array, size_t count, int key) {
  while (count > 0) {
    size_t mid = count / 2;
    if (key > array[mid]) {
      array += mid + 1;
      count -= mid + 1;
    } else if (key < array[mid]) {
      count = mid;
    } else {
      return (int *) &array[mid];
    }
  }
  return NULL;
}

您的计算
int mid=(低+(高-低))/2;
无法可靠地返回整数值;mid可能最终为
0
,使用
mid-1
0-1
)调用将是意外行为。
(低+(高-低))
只是
high
。因此您的递归调用一遍又一遍地执行相同的操作,直到内存耗尽。
int-mid=(低+(高-低))/2;
-->
int-mid=low+(高-低)/2;
您的计算
int-mid=(低+(高-低))/2;
无法可靠地返回整数值;mid可能会以