[英]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.