麻烦在C中找出递归二进制搜索的问题

时间:2016-01-03 13:52:32

标签: c recursion

我无法理解为什么我的代码在测试时会返回分段错误。我正在努力学习递归,如果有人能告诉我错在哪里,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));
    }
}

当我运行它时,会发生这种情况:

./bin_search 
How many elements are in the array?:5
Please type the elements:1 2 3 45 46
The array is: 1 2 3 45 46 
What number do you wish to search?45
Segmentation fault (core dumped)

3 个答案:

答案 0 :(得分:1)

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

bool result = search(item, array, 0, elements);

您当前的代码调用未定义的行为:search(item, array, array[0], array[elements])传递array[elements]作为上边界,读取超过array的末尾,可能是导致search的非常大的数字}函数引用无效地址,导致Segmentation fault

此外,搜索功能无法正确处理这些边界:upper 已排除,因此初始测试应为if (upper <= lower) return false;,当您在左半部分进行递归时,您应该使用midpoint作为上限,而不是midpoint-1

以下是更正后的版本:

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. **/
    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. **/    
    //upper becomes midpoint - 1
    return search(n, array, lower, midpoint);
}

请注意,您需要一种方法来了解匹配的索引,解决方案是返回此索引并返回-1以进行匹配。

答案 1 :(得分:0)

F5LTM.GetActiveLB();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)); } } 可能超出array[array[5]]的范围,其类型为array,导致未定义的行为。(实际上,取消引用数组[正如chqrlie所指出的,5]本身会导致未定义的行为。)

答案 2 :(得分:0)

试试这段代码 我没试过这个 你可以调用以下函数

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);
   }

}