二进制搜索中的return语句

时间:2012-06-23 10:09:32

标签: c recursion return-value

我在以下两个陈述中有点混淆。

以下程序为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?

3 个答案:

答案 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;
}