C语言中递归二进制搜索问题的解决

C语言中递归二进制搜索问题的解决,c,recursion,C,Recursion,我很难理解为什么我的代码在测试时返回分段错误。我正在努力学习递归,如果有人能告诉我哪里错了,我和C将不胜感激。 这是: // Binary search through numbers using recursion. #include <stdio.h> #include <string.h> #include <stdbool.h> #include <ctype.h> #include <stdlib.h> //prototyp

我很难理解为什么我的代码在测试时返回分段错误。我正在努力学习递归,如果有人能告诉我哪里错了,我和C将不胜感激。 这是:

// Binary search through numbers using recursion.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include <stdlib.h>

//prototype
bool search(int n, int array[], int lower, int upper);

int main(void) {
    int elements;
    //getting a list of numbers from the user
    printf("How many elements are in the array?:");
    scanf("%d", &elements);
    printf("Please type the elements:");
    int array[elements];
    for (int i = 0; i < elements; i++)
        scanf("%d", &array[i]);

    //printing out the array elements typed
    printf("The array is: ");
    for (int k = 0, arraylen = elements; k < arraylen; k++)
        printf("%d ", array[k]);
    printf("\n");
    printf("What number do you wish to search?");
    int item;
    scanf("%d", &item);
    bool result = search(item, array, array[0], array[elements]);
    if (result) {
        printf("Number found.\n");
    } else {
        printf("Number not found.\n");
    }
    return 0;
}

bool search(int n, int array[], int lower, int upper) {
    //base case
    if (upper < lower) {
        return false;
    }

    int midpoint = (upper + lower) / 2;
    if (n == array[midpoint]) {
        return true;
    }
    /** If value searched for is greater than the value at midpoint,  then
        Then discard everything to the left of a sorted list. **/
    else if (n > array[midpoint]) {
        //lower becomes midpoint + 1
        return search(n, array, (midpoint + 1), upper);
    }
    /** If value searched for is less than the value at midpoint, then
        Then discard everything to the right of a sorted list. **/    
    else if (n < array[midpoint]) {
        //upper becomes midpoint - 1
        return search(n, array, lower, (midpoint - 1));
    }
}

您应该传递数组边界索引,而不是元素:

bool result = search(item, array, 0, elements);
当前代码调用未定义的行为:
搜索(项、数组、数组[0],数组[elements])
数组[elements]
作为上边界传递,读取超过
数组
的末尾,可能是一个非常大的数字,导致
搜索
函数引用无效地址,导致
分段故障


此外,在搜索功能中未正确处理这些边界:
upper
被排除在外,因此初始测试应为
if(upper
lower
upper
应为索引,而不是值

// Binary search through numbers using recursion.

#include <stdio.h>
#include <stdbool.h>

//prototype
bool search(int n, int array[], int lower, int upper);

int main(void) {
    int elements;
    //getting a list of numbers from the user
    printf("How many elements are in the array?:");
    scanf("%d", &elements);
    printf("Please type the elements:");
    int array[elements];
    for (int i = 0; i < elements; i++)
        scanf("%d", &array[i]);

    //printing out the array elements typed
    printf("The array is: ");
    for (int k = 0, arraylen = elements; k < arraylen; k++)
        printf("%d ", array[k]);
    printf("\n");
    printf("What number do you wish to search?");
    int item;
    scanf("%d", &item);
    bool result = search(item, array, 0, elements-1);
    if (result) {
        printf("Number found.\n");
    } else {
        printf("Number not found.\n");
    }
    return 0;
}

bool search(int n, int array[], int lower, int upper) {
    if (upper < lower) {
        return false;
    }

    int midpoint = (upper + lower) / 2;

    if (n == array[midpoint]) {
        return true;
    }
    else if (n > array[midpoint]) {
        search(n, array, (midpoint + 1), upper);
    }
    else {
        search(n, array, lower, (midpoint - 1));
    }
}
//使用递归对数字进行二进制搜索。
#包括
#包括
//原型
布尔搜索(整数n,整数数组[],整数下限,整数上限);
内部主(空){
int元素;
//从用户处获取数字列表
printf(“数组中有多少个元素?:”;
scanf(“%d”和元素);
printf(“请键入元素:”);
int数组[元素];
for(int i=0;i数组[中点]){
搜索(n,数组,(中点+1),上);
}
否则{
搜索(n,数组,下,(中点-1));
}
}
您得到segfault的原因是
array[array[5]]
可能超出了
array
的范围,其类型为
int(*)[5]
,导致未定义的行为。(事实上,正如chqrlie所指出的,取消对array[5]的引用本身会导致未定义的行为。)

尝试此代码 我没试过这个 您可以调用以下函数

bool result = search(item, array, 0, lenth_of_array - 1); 
像这样的搜索功能

bool search(int item, int array[], int start, int end){

   if(start>end){
      return false;
   }
   int mid = (start+end)/2;
   if(array[mid]==item){
       return true;
   }

   else if(array[mid]>item){
       return search(item, array, start, mid-1);
   }

   else if(array[mid]<item){
       return search(item, array,mid+1,end);
   }

}
bool搜索(int项,int数组[],int开始,int结束){
如果(开始>结束){
返回false;
}
int mid=(开始+结束)/2;
if(数组[mid]==项){
返回true;
}
else if(数组[mid]>项){
返回搜索(项目、数组、开始、mid-1);
}

else if(数组[mid]
search
不应该返回什么吗?有两个分支没有返回,这将导致未定义的行为。编译器应该警告您。很抱歉,这是一个输入错误。正在更正。另外,如果您有一个
元素数组
元素数,那么您可以使用的最高索引是什么?提示:它不是
elements
。最后,您不应该将索引传递给对
search
的初始调用吗?代码没有完全编译。编译器输出消息:“60:1:警告:控件到达非void函数的末尾[-Wreturn type]”在进行任何其他调试之前,您需要修复该逻辑问题。您如何从
main
函数传递
startingIndex
lastIndex
?您的函数与OPs有何区别?startingIndex=0 lastIndex=lenth_of_array-1检查edit根据编辑调用,您修复了问题,但您的
search
函数与OPs完全相同,参数名称不同。事实上,它应该作为
bool result=search(item,array,0,elements-1)调用
搜索
函数中还有其他问题,可能会导致不正确的结果,在某些情况下会导致未定义的行为。您在中对崩溃的解释并不完全正确:程序没有引用数组[45]
,为上边界传递的值本身就是无效的引用
数组[5]
,刚过定义数组的末尾。@chqrlie是的,你是对的,但我认为只要将
元素
更改为
元素-1
就可以了。是的,它解决了问题,但对于C来说,它不像排除上限那样惯用:它还要求对索引进行签名,以表示空数组有边界
0
-1
,如果将索引的类型更改为
大小
,则会出现问题。
bool result = search(item, array, 0, lenth_of_array - 1); 
bool search(int item, int array[], int start, int end){

   if(start>end){
      return false;
   }
   int mid = (start+end)/2;
   if(array[mid]==item){
       return true;
   }

   else if(array[mid]>item){
       return search(item, array, start, mid-1);
   }

   else if(array[mid]<item){
       return search(item, array,mid+1,end);
   }

}