繁体   English   中英

递归二进制搜索功能不会为数组中不存在的值返回-1

[英]Recursive binary searching function doesn't return -1 for value that's not existant in the array

我正在尝试使用递归进行二进制排序。 它与list[]结构数组中存在的值很好地配合。 但是,当我打入一个我不知道在数组内部的值时,而不是返回-1,而是返回垃圾值。 我在MVS中使用调试器跟踪了代码,但是可能确实存在(实际上确实是)看不到的东西。

有人可以告诉我为什么它不返回-1吗?

#include<stdio.h>
#include<string.h>

#define MAX 20

typedef struct
{
    char name[MAX] = "";
    char surname[MAX] = "";
    int id;
}patient;

int binarySearch(patient list[], char *target, int top, int bottom, int *comparisons)
{
    int center;
    center = (top + bottom) / 2;
    if (strcmp(list[center].surname, target) == 0)
        return center;
    (*comparisons)++;

    if (top == center || bottom == center)
        return -1;
    if (strcmp(list[center].surname, target) == 1)
        return binarySearch(list, target, center - 1, bottom, comparisons);
    if (strcmp(list[center].surname, target) == -1)
        return binarySearch(list, target, top, center + 1, comparisons);
}

int main(void)
{
    FILE *fi = fopen("patients.txt", "r");

    if (fi == NULL)
        printf("Problem opening file!");
    else
    {
        patient list[MAX];
        int i = 0, comparisons = 0, index;
        char target[MAX] = "";

        while (fscanf(fi, "%s %s %d", &list[i].name, &list[i].surname, &list[i].id) != EOF)
            i++;

        printf("Enter the surname of the patient (END to exit): ");
        scanf("%s", target);

        index = binarySearch(list, target, i, 0, &comparisons);

        printf("%-15s %-15s %-15d\n", list[index].name, list[index].surname, list[index].id);
        printf("%d comparisons\n", comparisons);

    }
}

您得到一个垃圾值,因为最后的条件并不详尽。

strcmp指示第一个值在第二个值之后时,不需要返回1 唯一的要求是它返回一个正数。 少则为负, -1为负。 因此,您的函数可能最终会到达终点而不会遇到return ,这是未定义的行为。

您需要更改if的链,以将返回值与零进行比较。 作为优化,您应该存储一次比较结果,并在整个条件中重复使用它:

int binarySearch(patient list[], char *target, int top, int bottom, int *comparisons)
{
    int center = (top + bottom) / 2;
    (*comparisons)++;
    int cmp = strcmp(list[center].surname, target);
    if (cmp == 0)
        return center;
    if (top == center || bottom == center)
        return -1;
    if (cmp > 0)
        return binarySearch(list, target, center - 1, bottom, comparisons);
    else // cmp < 0 here
        return binarySearch(list, target, top, center + 1, comparisons);
}

还要注意,为了以正确的方式考虑比较次数,应在strcmp调用之前(*comparisons)++

如何节省时间:1)确保完全启用编译器警告。 2)使用一个好的编译器。

我希望以下内容会生成类似“警告:控制到达非void函数的末尾”之类的警告,为您提供比堆栈溢出更好且更快的反馈。

  if (strcmp(list[center].surname, target) == -1)
    return binarySearch(list, target, top, center + 1, comparisons);
}

其他良好的编译器反馈"error: expected ':', ',', ';', '}' or '__attribute__' before '='"

typedef struct {
  char name[MAX] = "";  // not valid to initialize.

“使用MVS中的调试器跟踪代码”->使我想知道您是否将C代码编译为C ++代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM