我正在尝试构建一个递归函数,它通过与中间值进行比较并根据相对大小继续返回已排序数组中的地址。如果值不在数组中,则应该只打印NULL。现在函数的第一部分工作,但是每当发生null时我都会遇到分段错误。代码如下:
#include <stdio.h>
int *BinSearchRec(int arr[], int size, int n){
if(n==arr[size/2]){
return &arr[size/2];
}
else if(n>arr[size/2]) {
return(BinSearchRec(arr, size+size/2, n));
}
else if(n<arr[size/2]) {
return(BinSearchRec(arr, size-size/2, n));
}
else{
return NULL;
}
}
main(){
int numb[]={2,7,8,9};
if((int)(BinSearchRec(numb, 4, 22)-numb)>=0) {
printf("Position: %d \n", (int)(BinSearchRec(numb, 4, 22)-numb)+1);
}
else{
printf("NULL \n");
}
}
答案 0 :(得分:6)
你的递归调用是错误的。在第一种情况下,您声称数组的大小比原来大<50> 大,并且您错误地传递了指针(您应该传递第二个&#34;一半&#34;数组)。
在这两种情况下,&#34;数组的大小&#34;总是功能的一半。在第二种情况下,您需要将指针传递给数组的后半部分。
像
这样的东西else if(n>arr[size/2]) {
return(BinSearchRec(arr + sizeof/2, size/2, n));
}
else if(n<arr[size/2]) {
return(BinSearchRec(arr, size/2, n));
}
您还要将函数的返回值视为错误。它不是一个值,它是值的指针,您需要将其视为这样。从另一个(相关的)指针中减去一个指针是可以的,它被称为指针算术。
答案 1 :(得分:1)
除了其他人所说的没有正确划分数组而没有正确使用返回值之外,你的函数还缺少终止条件。
在您的代码中,永远不会达到[{1}},因为上述三个条件涵盖了所有可能性:else
小于,等于或大于n
。< / p>
在访问和比较它们之前,您应该测试您的子数组是否实际上有元素。这是您的代码的修订版:
arr[size/2]
这是一个示例int *BinSearchRec(int arr[], int size, int n)
{
int m = size/2;
if (size == 0) return NULL;
if (n > arr[m]) return BinSearchRec(arr + m + 1, size - m - 1, n);
if (n < arr[m]) return BinSearchRec(arr, m, n);
return &arr[m];
}
,它显示了如何使用返回的指针。如果指针是main
,则该数字不在数组中,并且您不能取消引用指针。
NULL
答案 2 :(得分:0)
使用2个索引(size
和left
)来分隔您正在探索的子数组,而不是使用单个right
。
根据这种方法修改代码可以得到:
#include <stdio.h>
#include <stdlib.h>
int *BinSearchRec(int arr[], int left, int right, int n){
if (left > right)
return NULL;
int mid = (left + right) / 2;
if(n == arr[mid])
return &arr[mid];
if(n > arr[mid])
return BinSearchRec(arr, mid + 1, right, n);
else
return BinSearchRec(arr, left, mid - 1, n);
}
int main(int argc, char *argv[]){
int numb[] = {2,7,8,9};
int *p = BinSearchRec(numb, 0, 3, 22);
if (p) {
printf("Position: %d \n", (int) (p - numb + 1));
} else {
printf("NULL \n");
}
return 0;
}