为什么我的二进制搜索实现没有找到最后一个元素?
Why doesn't my binary search implementation find the last element?
我已经用C语言实现了二分查找的初学者递归版本。但是,当要查找的元素位于数组的最后一个位置时,它似乎不起作用。有没有办法在不改变函数原型的情况下解决这个问题?
#include <stdio.h>
int search(int value, int values[], int n);
int main() {
int a[] = { 26, 27, 28 };
if (search(28, a, 3) == 0)
printf("Found.\n");
else
printf("Not found.\n");
}
int search(int value, int values[], int n)
{
if (n <= 0)
return 1;
if (value < values[n/2])
// Search the left half
return search(value, values, n/2);
else if (value > values[n/2])
// Search the right half, excluding the middle term
return search(value, values + n/2 + 1, n/2 - 1);
else
return 0;
return 1;
}
这似乎是您在 else if 子句中的 return 语句。数组的长度 n
应该是 n-n/2-1
而不是 n/2-1
否则最后一个元素将被剪掉。随着数组长度的增加以及您正在搜索来自右侧的元素,您可以看到这种情况更加普遍。
return search(value, values + n/2 + 1, n - n/2 - 1);
注:
正如 chqrlie 指出的
您的 search
函数不正确:
- 递归右侧部分时传递的切片大小计算不正确:它应该是
n - n/2 - 1
而不是 n/2 - 1
。
这是更正后的版本:
#include <stdio.h>
int search(int value, int values[], int n);
int main(void) {
int a[] = { 26, 27, 28 };
if (search(28, a, 3) == 0)
printf("Found.\n");
else
printf("Not found.\n");
return 0;
}
int search(int value, int values[], int n) {
if (n > 0) {
int mid = n / 2;
if (value < values[mid]) {
// Search the left half
return search(value, values, mid);
} else
if (value > values[mid]) {
// Search the right half, excluding the middle term
return search(value, values + mid + 1, n - mid - 1);
} else {
// Found the value
return 0;
}
}
return 1;
}
这是一个更简单的迭代版本:
int search(int value, int values[], int n) {
while (n > 0) {
int mid = n / 2;
if (value < values[mid]) {
// Search the left half
n = mid;
} else
if (value > values[mid]) {
// Search the right half, excluding the middle term
values += mid + 1;
n -= mid + 1;
} else {
// Found the value
return 0;
}
}
return 1;
}
我已经用C语言实现了二分查找的初学者递归版本。但是,当要查找的元素位于数组的最后一个位置时,它似乎不起作用。有没有办法在不改变函数原型的情况下解决这个问题?
#include <stdio.h>
int search(int value, int values[], int n);
int main() {
int a[] = { 26, 27, 28 };
if (search(28, a, 3) == 0)
printf("Found.\n");
else
printf("Not found.\n");
}
int search(int value, int values[], int n)
{
if (n <= 0)
return 1;
if (value < values[n/2])
// Search the left half
return search(value, values, n/2);
else if (value > values[n/2])
// Search the right half, excluding the middle term
return search(value, values + n/2 + 1, n/2 - 1);
else
return 0;
return 1;
}
这似乎是您在 else if 子句中的 return 语句。数组的长度 n
应该是 n-n/2-1
而不是 n/2-1
否则最后一个元素将被剪掉。随着数组长度的增加以及您正在搜索来自右侧的元素,您可以看到这种情况更加普遍。
return search(value, values + n/2 + 1, n - n/2 - 1);
注: 正如 chqrlie 指出的
您的 search
函数不正确:
- 递归右侧部分时传递的切片大小计算不正确:它应该是
n - n/2 - 1
而不是n/2 - 1
。
这是更正后的版本:
#include <stdio.h>
int search(int value, int values[], int n);
int main(void) {
int a[] = { 26, 27, 28 };
if (search(28, a, 3) == 0)
printf("Found.\n");
else
printf("Not found.\n");
return 0;
}
int search(int value, int values[], int n) {
if (n > 0) {
int mid = n / 2;
if (value < values[mid]) {
// Search the left half
return search(value, values, mid);
} else
if (value > values[mid]) {
// Search the right half, excluding the middle term
return search(value, values + mid + 1, n - mid - 1);
} else {
// Found the value
return 0;
}
}
return 1;
}
这是一个更简单的迭代版本:
int search(int value, int values[], int n) {
while (n > 0) {
int mid = n / 2;
if (value < values[mid]) {
// Search the left half
n = mid;
} else
if (value > values[mid]) {
// Search the right half, excluding the middle term
values += mid + 1;
n -= mid + 1;
} else {
// Found the value
return 0;
}
}
return 1;
}