fbpx

Algoritm pentru cautarea binara in C++

de Mihai-Alexandru

Ce este cautarea binara?

Algoritmul de cautare binara este un algoritm folosit pentru a gasii un elemnt intr-o lista ordonata (crescatoare sau descrescatoare). Algoritmul foloseste tehnica „divide et impera” (sau „divide si cucereste” pe romana). Deoarece dupa fiecare pas, cardinalul multimii se injumatateste, acest algoritm are o complexitate logaritmica. Citeste mai multe: Cautarea binara – Wikipedia

Algoritmul pentru cautarea binara

Se da un sir de numere ordonat crescator cu N elemente, se cere sa se returneze pozitia in sir a unui numar introdus de la tastatura.

Consideram deja ca avem vectorul V cu cele N elemente ordonate crescator. Ne alegem trei variabile, pe care eu le voi denumii: Left, Right si Mid.

  • Left – inceputul intervalului in care cautam
  • Mid – mijlocul intervalului
  • Right – sfarsitul intervalului in care cautam

Algoritmul verifica de mai multe ori daca Mid este egal cu valoarea elementului cautat de noi. Numai ca intervalul se modifica pe masura ce algoritmul ruleaza.

  • In cazul in care V[Mid] == x (unde x – este elementul cautat de noi) – algoritmul a gasit elementul cautat de noi
  • In caz contrar:
    • daca x este mai mic decat V[Mid], Right va devenii Mid
    • daca x este mai mare decat V[Mid], Left va devenii Mid

Tot ceea ce am descris mai sus se repeta atata timp cat Left <= Right.

Cautarea binara in C++

Varianta 1 (clasica):

#include    <iostream>

using namespace std;

const int N = 10;

int V[N] = {16, 27, 43, 45, 49, 60, 68, 81, 92, 96};

int CautareBinara(int x)
{
    int Sol = -1, Left = 0, Right = N;
    while(Left <= Right)
    {
        int Mid = (Left+Right) / 2;
        if(V[Mid] == x)
        {
            Sol = Mid;
            break;
        }
        if(V[Mid] > x)
            Right = Mid - 1;
        if(V[Mid] < x)
            Left = Mid + 1;
    }
    return Sol;
}

int main()
{
    cout << CautareBinara(43);
    return 0;
}

Varianta 2 (recursiva):

#include    <iostream>

using namespace std;

const int N = 10;

int V[N] = {16, 27, 43, 45, 49, 60, 68, 81, 92, 96};

int CautareBinara(int Left, int Right, int x)
{
    if(Left > Right)
        return -1;
    else
    {
        int Mid =(Left+Right)/2;
        if(x == V[Mid])
            return Mid;
        if(x < V[Mid])
            return CautareBinara(Left, Mid-1, x);
        else
            return CautareBinara(Mid+1, Right, x);
    }
}

int main()
{
    cout << CautareBinara(0, N-1, 43);
    return 0;
}

Varianta 3 (folosind upper_bound()):

#include    <algorithm>
#include    <iostream>

using namespace std;

const int N = 10;

int V[N] = {16, 27, 43, 45, 49, 60, 68, 81, 92, 96};

int main()
{
    int value = 43;
    int result = upper_bound(V, V+N, value) - V - 1;
    if(result >= 1 && result <= N && V[result] == value)
        cout << result;
    else
        cout << -1;
    return 0;
}

Desfasurarea algoritmului de cautare binara pas cu pas:

Pasul initial: Sol: -1 Left: 0 Right: 9
Pasul 1: Sol: -1 Left: 0 Right: 3
Pasul 2: Sol: 2 Left: 2 Right: 3

Cautarea binara in C++

Avem Left = 0, Right = 9, Mid = 4. Daca inlocuim V[Mid] = 49. Deoarece 49 > 43, Right devine 3.

Cautarea binara in C++

Avem Left = 0, Right = 3, Mid = 1. Daca inlocuim V[Mid] = 27. Deoarece 27 < 43, Left devine 2.

Cautarea binara in C++Avem Left = 2, Right = 3, Mid = 2. Daca inlocuim V[Mid] = 43, obtinand numarul cautat de noi.

Complexitatea algoritmului pentru cautarea binara

Pentru a calcula complexitatea acestui algoritm, vom construii un arbore. Radacina arborelui va fi elementul din mijloc. Mai apoi, copilul din stanga va fi mijlocul multimii din stanga, iar copilul din dreapta va fi mijlocul multimii din dreapta. Ca sa intelegeti mai bine, haideti sa desenam copacul multimii noastre:

Complexitatea cautarii binareIn cel mai bun caz, algoritmul nostru gaseste elementul in O(1) – atunci cand elementul cautat se afla exact in mijlocul multimii.

In cel mai rau caz, cautarea binara efectueaza log2(n) comparatii. Cel mai rau caz este obtinut atunci cand algoritmul nostru sapa pana la ultimul nivel al arobrelui. De asemenea, atunci cand elementul cautat nu se afla in multime, se executa tot log2(n) comparatii.

Putem observa faptul ca dupa fiecare comparare, intervalul in care noi cautam se injumatateste. Sa presupunem ca aveam 16 elemente (pentru a simplifica calculele).

Complexitatea cautarii binareDin cate putem observa, exista o legatura stransa intre log2(n) si numarul efectiv de cautari. Asadar, complexitatea acestui algoritm este O(log2n).

Comentarii

S-ar putea sa iti placa