二进制搜索递归的麻烦

时间:2016-12-18 12:17:27

标签: c algorithm

我是C语言和算法的初级。

我尝试使用递归进行二进制搜索,我无法理解如何检查数组中是否存在数字。

这是我的代码:

install()

如果数组中不存在数字,我想返回(-1)。

2 个答案:

答案 0 :(得分:1)

我已经编写了一个BinarySearch C代码供您检查并查看问题所在。     这部分:int BinarySearch通过循环进行BinarySearch,     这部分:int BinarySearchRec通过递归进行BinarySearch。

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

int BinarySearch(int*,int,int);
int BinarySearchRec(int*,int,int,int);
int main(void){
    int length;
    int searchElement;
    int* list;
    printf("Enter the length of the list\n");
    scanf("%d",&length);
    list = malloc(length*sizeof(int));
    printf("Enter the search element for this list");
    scanf("%d",&searchElement);
    printf("Enter the elements for this list\n");
    for(int i=0;i<length;i++){
        scanf("%d",list+i);
    }
    int result1 = BinarySearch(list,length,searchElement);
    int result2 = BinarySearchRec(list,0,length-1,searchElement);
    printf("Result from loopy BinarySearch : %d\n",result1);
    printf("Result from recursive BinarySearch: %d\n",result2);
    return 0;
}

int BinarySearch(int* list, int length, int searchElement){
    int found=0;
    int min = 0;
    int max = length-1;
    int mid=0;
    while(found != 1 && max > min){
        mid = (max+min)/2;
        if(searchElement == list[mid]){
            found = 1;
        }else if(searchElement > list[mid]){
            min = mid+1;
        }else if(searchElement < list[mid]){
            max = mid;
        }

    }
    if(max > min){
        return mid;
    } else{
        return -1;
    }
}

int BinarySearchRec(int* list,int min,int max,int searchElement){
    int mid = (min+max)/2;
    if(max > min){
        if(searchElement == list[mid]){
                    return mid;
            }else{
                    if(searchElement < list[mid]){
                             return BinarySearchRec(list,min,mid,searchElement);
                    }else if(searchElement > list[mid]){
                            min = mid+1;
                            return BinarySearchRec(list,mid+1,max,searchElement);
                    }
            }
    }else{
        return -1;
    }
}

答案 1 :(得分:1)

您的代码中存在多个问题:

  • midpoint()定义为宏容易出错。您的定义没有正确括号,应该是:

    #define midpoint(start, end) (((start) + (end)) / 2)
    

    写为总和的一半,它实际上会调用startend的大值的未定义行为,更安全的版本是start + (end - start) / 2,但不应该用于宏,因为它评估start两次。只需直接在函数中编写代码即可。

  • 你的初始化函数迭代了一步太远,循环应该是:

    for (int i = 0, number = 0; i < SIZE; i++) {
        array[i] = number;
        number += 2;
    }
    
  • find()确实应该返回找到的值的索引,如果找不到则返回-1。你没有退货。使它在失败时返回-1,并在递归时返回递归调用的值。

  • find的参数是start,搜索中包含的范围的起始索引,以及从搜索中排除的end上限。在左侧部分递归时,不应传递mid - 1

以下是更正后的版本:

#include <stdio.h>

#define SIZE 15

void fill_array(int array[], int size) {
    // here I just fill array with even numbers
    for (int i = 0, number = 0; i < SIZE; i++) {
        array[i] = number;
        number += 2;
    }
}

int find(int target, const int array[], int start, int end) {
    if (start >= end) {
        // empty range: not found
        return -1;
    }

    int mid = start + (end - start) / 2;

    if (target == array[mid]) {
        return mid;
    }
    if (target > array[mid]) {  
        return find(target, array, mid + 1, end);
    } else {
        return find(target, array, start, mid);
    }
}

void locate(int value, const int array[], int size) {
    int res = find(value, array, 0, size);
    if (res < 0) {
        printf("%d was not found in the array\n", value);
    } else {
        printf("%d was found at offset %d\n", value, res);
    }
}

int main(void) {
    int array[SIZE];

    fill_array(array, SIZE);
    locate(1, array, SIZE);
    locate(2, array, SIZE);
    return 0;
}

输出:

1 was not found in the array
2 was found at offset 1

请注意,find()可以实现为代码较少的循环:

int find(int target, const int array[], int start, int end) {
    while (start < end) {
        int mid = start + (end - start) / 2;

        if (target == array[mid]) {
            return mid;
        }
        if (target > array[mid]) {  
            start = mid + 1;
        } else {
            end = mid;
        }
    }
    return -1;
}
相关问题