HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Binary search as a generic algorithm

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericbinarysearchalgorithm

Problem

I am upgrading my C++11 knowledge and repeating some essential algorithm. Here is binary search only in terms of iterators.

#include 

#include 
#include 

using namespace std;

template
t_iter binarySearch(t_iter begin, t_iter end, typename iterator_traits::value_type q)
{
    typedef iterator_traits::value_type t_elem;
    size_t len = end - begin;

    if (len  a(tmp, tmp + len);

    int q = 35;

    auto it = binarySearch(a.begin(), a.end(), q);

    cout << distance(a.begin(), it) << endl;
}

Solution

Iterators may not be random access iterators which means the length calculation and the advance by half won't compile.

For this there is the distance and advance functions available which use the random access if it is available but fall back to counting and repeated incrementing when it isn't.

You never use the t_elem type def.

In the recursion step both branches are equally likely and equally important, that is best signified and made more readable by using an else branch rather than letting it fall through.

you can also implement as a loop to minimize recursion overhead (micro-optimization admittedly because automatic tail-call optimization would do the same).

template
t_iter binarySearch(t_iter begin, t_iter end, typename iterator_traits::value_type q)
{
    auto len = std::distance(begin, end);

    while(len>1)
    {
        t_iter middleElem = begin;
        std::advance(middleElem, len / 2);

        if (*middleElem < q)
        {
            begin = middleElem;
        }
        else
        {
            end = middleElem;
        }
        len = std::distance(begin, end);
    }

    if (*begin == q)
    {
        return begin;
    }
    return end;

}

Code Snippets

template<typename t_iter>
t_iter binarySearch(t_iter begin, t_iter end, typename iterator_traits<t_iter>::value_type q)
{
    auto len = std::distance(begin, end);

    while(len>1)
    {
        t_iter middleElem = begin;
        std::advance(middleElem, len / 2);

        if (*middleElem < q)
        {
            begin = middleElem;
        }
        else
        {
            end = middleElem;
        }
        len = std::distance(begin, end);
    }

    if (*begin == q)
    {
        return begin;
    }
    return end;

}

Context

StackExchange Code Review Q#60566, answer score: 6

Revisions (0)

No revisions yet.