我在以下两个陈述中有点混淆。
以下程序为finds the index of an element out of a sorted array[no duplicates] using binary search.
int bin(int *arr,int l,int h,int k)
{
int mid;
if(l>h)
return -1;
if(l==h)
{
return arr[l]==k?l:-1;
}
else
{
mid=(l+h)>>1;
if(arr[mid]==k)
return mid;
else if(k>arr[mid])
bin(arr,mid+1,h,k);
else
bin(arr,l,mid-1,k);
}
}
我在程序中没有任何问题[完美地工作]:
我对以下两个陈述感到困惑:
箱(ARR,L,中间-1,K); http://ideone.com/p1o5U
返回bin(arr,l,mid-1,k); http://ideone.com/lMhgB
使用上述任何一个陈述都会给出正确的结果
哪种陈述在时间上更有效?
How the program is working fine even without return statement?
答案 0 :(得分:0)
即使没有return语句,程序如何正常工作?
在这种情况下,我会说在实践中没有区别,因为递归结束于一个return语句,与你给它的参数无关(是的,即使你没有在最后两次调用中指定它) 。但这是一个您不应该依赖的特定于编译器的细节!
哪种陈述在时间上更有效?
您可能会认为带有return语句的那些更有效,因为在这种情况下它不需要读取“else”检查,但是,差异非常小。
请注意,如果没有返回语句,它被认为是“不正确的”,即使它“有效”,并且-Wall会给你关于它的警告。
也请参阅此similar question。复制了答案:
您看到的可能是由实施细节引起的 某些体系结构上的函数通过设置a返回(整数值) 众所周知的注册到该值(i386上的eax)。因此,如果 最底层的递归调用确实返回并设置了这个寄存器,并且 中间的调用不要踩到那个寄存器,你会发现它有点像 作品。但是,你不能依赖它。
编辑:改变措辞,不要将行为暗示为故意优化。不知道是不是。无论如何,这是某些编译器所做的事情,有些则没有。
答案 1 :(得分:0)
使用不同的编译器编译时,该程序会产生不同的结果:
#include <stdio.h>
int bin(int *arr,int l,int h,int k)
{
int mid;
if(l>h)
return -1;
if(l==h)
{
return arr[l]==k?l:-1;
}
else
{
mid=(l+h)>>1;
if(arr[mid]==k)
return mid;
else if(k>arr[mid])
bin(arr,mid+1,h,k);
else
bin(arr,l,mid-1,k);
}
}
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int main(void)
{
int i;
for (i = 0; i <= 11; i++)
printf("bin(%d): %d\n", i, bin(arr, 0, 9, i));
return 0;
}
输出(编译器:打开Watcom C / C ++ 1.9):
>nrv.exe
bin(0): 0
bin(1): 1
bin(2): 2
bin(3): 3
bin(4): 4
bin(5): 4
bin(6): 6
bin(7): 7
bin(8): 8
bin(9): 9
bin(10): 10
bin(11): 11
输出(编译器:MinGW gcc 4.6.2):
$ nrv.exe
bin(0): -1
bin(1): 0
bin(2): 1
bin(3): 2
bin(4): 3
bin(5): 4
bin(6): 5
bin(7): 6
bin(8): 7
bin(9): 8
bin(10): 9
bin(11): -1
我不敢说我在程序中没有任何问题[完美地工作] 。您的bin()
函数调用未定义的行为。
答案 2 :(得分:0)
偏离主题:如果你打算使用递归,你可以通过消除下边界来大大简化程序,而不是碰撞指针。
#include <stdio.h>
int bin(int *arr, int n, int k);
int bin(int *arr, int n, int k)
{
int mid;
if (n <= 0) return -1;
mid = n / 2;
if (arr[mid] == k) return mid;
if (k < arr[mid]) return bin(arr, mid, k);
n = bin(arr+mid+1, n-(mid+1), k);
return (n<0) ? n : mid+1+n;
}
int main(void)
{
int array[] = {0,1,2,3,4,5,6,7,8,9,10,11};
int result, val;
for (val= -2; val < 15; val++) {
result = bin(array, 10, val);
printf("Val=%d -> %d\n", val, result);
}
return 0;
}