C 为什么';我的二进制搜索实现找不到最后一个元素?

C 为什么';我的二进制搜索实现找不到最后一个元素?,c,arrays,binary-search,C,Arrays,Binary Search,我已经在C中实现了二进制搜索的初学者递归版本。但是,当要查找的元素位于数组的最后一个位置时,它似乎不起作用。有没有办法在不改变函数原型的情况下解决这个问题 #include <stdio.h> int search(int value, int values[], int n); int main() { int a[] = { 26, 27, 28 }; if (search(28, a, 3) == 0) printf("Found.\n")

我已经在C中实现了二进制搜索的初学者递归版本。但是,当要查找的元素位于数组的最后一个位置时,它似乎不起作用。有没有办法在不改变函数原型的情况下解决这个问题

#include <stdio.h>

int search(int value, int values[], int n);

int main() {
    int a[] = { 26, 27, 28 };

    if (search(28, a, 3) == 0)
        printf("Found.\n");
    else
        printf("Not found.\n");
}

int search(int value, int values[], int n)
{
    if (n <= 0) 
        return 1;

    if (value < values[n/2])
        // Search the left half
        return search(value, values, n/2);
    else if (value > values[n/2])
        // Search the right half, excluding the middle term
        return search(value, values + n/2 + 1, n/2 - 1);
    else 
        return 0;

    return 1;
}
#包括
int搜索(int值,int值[],int n);
int main(){
int a[]={26,27,28};
如果(搜索(28,a,3)==0)
printf(“找到了。\n”);
其他的
printf(“未找到。\n”);
}
int搜索(int值,int值[],int n)
{
如果(n个值[n/2])
//搜索右半部分,不包括中间项
返回搜索(值,值+n/2+1,n/2-1);
其他的
返回0;
返回1;
}

它似乎是else-if子句中的返回语句。数组
n
的长度应该是
n-n/2-1
而不是
n/2-1
,否则最后一个元素将被剪掉。随着数组长度的增加以及搜索来自右侧的元素,您可以看到这种情况更加普遍

return search(value, values + n/2 + 1, n - n/2 - 1);
注意:
正如chqrlie指出的,您的
搜索功能不正确:

  • 在右侧部分递归时传递的切片大小计算不正确:它应该是
    n-n/2-1
    ,而不是
    n/2-1
以下是更正的版本:

#include <stdio.h>

int search(int value, int values[], int n);

int main(void) {
    int a[] = { 26, 27, 28 };

    if (search(28, a, 3) == 0)
        printf("Found.\n");
    else
        printf("Not found.\n");

    return 0;
}

int search(int value, int values[], int n) {
    if (n > 0) {
        int mid = n / 2;
        if (value < values[mid]) {
            // Search the left half
            return search(value, values, mid);
        } else
        if (value > values[mid]) {
            // Search the right half, excluding the middle term
            return search(value, values + mid + 1, n - mid - 1);
        } else {
            // Found the value
            return 0;
        }
    }
    return 1;
}
#包括
int搜索(int值,int值[],int n);
内部主(空){
int a[]={26,27,28};
如果(搜索(28,a,3)==0)
printf(“找到了。\n”);
其他的
printf(“未找到。\n”);
返回0;
}
int搜索(int值,int值[],int n){
如果(n>0){
int-mid=n/2;
如果(值<值[mid]){
//搜索左半部分
返回搜索(值、值、中间);
}否则
如果(值>值[mid]){
//搜索右半部分,不包括中间项
返回搜索(value,value+mid+1,n-mid-1);
}否则{
//找到了价值
返回0;
}
}
返回1;
}
下面是一个更简单的迭代版本:

int search(int value, int values[], int n) {
    while (n > 0) {
        int mid = n / 2;
        if (value < values[mid]) {
            // Search the left half
            n = mid;
        } else
        if (value > values[mid]) {
            // Search the right half, excluding the middle term
            values += mid + 1;
            n -= mid + 1;
        } else {
            // Found the value
            return 0;
        }
    }
    return 1;
}
int搜索(int值,int值[],int n){
而(n>0){
int-mid=n/2;
如果(值<值[mid]){
//搜索左半部分
n=中等;
}否则
如果(值>值[mid]){
//搜索右半部分,不包括中间项
数值+=中间值+1;
n-=mid+1;
}否则{
//找到了价值
返回0;
}
}
返回1;
}

我刚刚运行了你的代码;好用吗?你能澄清你的错误,你的重复步骤吗?如果
值==值[n/2]
,为什么你要返回
0
?您不应该返回
n/2
?如果n是3,你认为
n/2-1
会是什么?可能重复
n/2-1
-->
n-n/2-1
@chqrlie这是一个好的观点,也是一个重要的观点。虽然我会让OP自行决定,因为主要关注的似乎是数学逻辑。@chqrlie实际上,这将解决越界问题,接球不错。