订购二进制搜索w / Assembly |递归与迭代与图书馆

时间:2012-02-25 15:23:37

标签: c++

哪个更好?

根据Savitch的说法,每个递归都以激活帧的形式保存在堆栈中。这有开销。但是,编写递归版本需要少量代码。对于一个最好上交的面试。两者的代码都在下面。

#include <iostream>

using namespace std;
const int SIZE = 10;
int array[ SIZE ] = { 0,1,2,3,4,5,6,7,8,9 };
int answer = NULL;

void binary_search_recursive( int array[], int start, int end, int value, int& answer )
{
    int mid = (start + end ) / 2;

    if ( array[ mid ] == value )
    {
        answer = mid;
    }
    else if ( array[ mid ] < value )
    {
        binary_search_recursive( array, mid + 1, end, value, answer );
    }
    else
    {
        binary_search_recursive( array, start, mid - 1, value, answer );
    }
}

void binary_search_iterative( int array[], int start, int end, int value, int& answer )
{
    int mid = ( (start + end ) / 2 );

    while( array[ mid ] != value  )
    {
        if ( array[ mid ] < value )
        {
            start = mid; 
            mid = ( ( ( mid + 1 ) + end ) / 2 );
        }
        else
        {
            end = mid;
            mid = ( ( start + ( mid - 1 ) ) / 2 );
        } 
    }
    answer = mid;
}

int main()
{
    binary_search_iterative( array, 0, SIZE - 1, 4, answer);
    cout << answer;
    return 0;
}

4 个答案:

答案 0 :(得分:4)

算法的递归版本通常在代码行中更短,但由于递归版本的函数调用开销,相同算法的迭代版本通常通常更快。 / p>

关于二进制搜索算法,更快的实现被编写为迭代。例如,Jon Bentley发布的二进制搜索版本是迭代的。

答案 1 :(得分:2)

在二进制搜索的情况下,递归并不能比迭代更好地表达你的意图,所以迭代方法更好。

我认为面试的最佳方法是提交一个调用lower_bound的解决方案:它向采访者显示您不仅知道一些基本语法以及如何编写一年级算法,而且你不要浪费时间重写样板代码。

答案 2 :(得分:1)

如果速度是一个问题或者堆栈大小有限制,则使用迭代,因为正如您所说,它涉及重复调用该函数,这会导致它占用堆栈上更多的空间。至于在面试中回答我会选择当时最简单的做法,原因显而易见:))

答案 3 :(得分:1)

对于一次采访,我首先要提到递归和迭代解决方案都是可能的,同样也很容易写。递归版本存在嵌套堆栈帧的潜在问题,使用甚至耗尽堆栈内存(并将不同页面错误地放入缓存中),但编译器倾向于提供尾递归优化,从而有效地创建迭代实现。递归函数往往更加明显无误,但是在日常的C ++编程中并没有那么广泛适用,所以对维护程序员来说可能不那么熟悉和舒适。

除非有理由不在实际项目中使用std::binary_search中的<algorithm>(http://www.sgi.com/tech/stl/binary_search.html)。< / p>

为了说明尾递归,您的binary_search_recursive算法已由g++ -O4 -S更改为下面的程序集。注意:

  • 要获得代码的印象,您不需要了解每一行,但以下有助于:
    • movl是寄存器和存储器之间的移动语句(赋值)(“long”的尾随“l”反映寄存器/存储器位置中的位数)
    • sublshrlsarlcmpl是减法,右移,右移算术和比较指令,重要的是要注意的是副作用他们设置了一些标志,如“等于”,如果他们产生0结果,由je(如果等于跳跃)和jge(如果大于或等于跳跃),{{{ 1}}如果不相等就跳。
  • {L}处理jne终止条件,而L14和L4处的代码处理递归步骤,可以跳回L12。

这是你的binary_search_recursive函数的反汇编(名称以C ++风格破坏)......

answer = mid