CAUTARE BINARA
CAUTARE BINARA
La ce se refera?
[1]
Avem un tablou de elemente sortate crescator.
5
𝑥1
9
20
24
50
𝑥2
𝑥3
𝑥4
𝑥5
Problema se pune sa cautam o valoare v in sirul dat. Daca se gaseste in sir, afisam pozitia pe care
se gaseste, iar daca nu se gaseste sa precizam acest lucru.
Ex.
v=24 se afla pe pozitia 4.
v=7 nu se gaseste in sir
Care este ideea.
[2] Depistam elementul din mijloc. Daca acesta este egal cu valoarea v, inseamna ca pozitia este la mijloc.
Daca v nu este egal cu elementul din mijloc, daca v este mai mare decat elementul din mijloc, cautam
in dreapta lui, altfel cautam in stanga lui.
[2.1]
ATENTIE! Trebuie tratata situatia cand secventa, in care cautam, are decat un element si acesta
nu este egal cu valoarea v. In acest caz, v nu se gaseste in secventa si intrerupem
cautarea.
CUM PROCEDAM
[3] Sa zicem ca trebuie sa cautam valoarea v in secventa
𝒙𝒔 , … . , 𝒙𝒅
(s=idicele din stanga; d=indicele din dreapta)
Cum procedam?
Aflam indicele din mijloc
𝒙𝒔 , … , 𝒙𝒔+𝒅−𝟏 , 𝒙𝒔+𝒅 , 𝒙𝒔+𝒅+𝟏 , … , 𝒙𝒅
𝟐
𝟐
𝟐
Daca v=𝒙𝒔+𝒅 ,
𝟐
pozitia este
𝒔+𝒅
𝟐
si intrerupem cautarea
altfel
daca secventa are mai multe elemente, s<d
daca v>𝒙𝒔+𝒅 , cautam in
𝟐
𝒙𝒔+𝒅+𝟏 , … , 𝒙𝒅
𝟐
altfel, cautam in
𝒙𝒔 , … , 𝒙𝒔+𝒅−𝟏
𝟐
altfel // daca secventa are decat un element care nu este egal cu v
Nu exista si incetam cautarea
1
CAUTARE BINARA
CUM IMPLEMENTAM?
[4] ATENTIE! Daca v nu este egal cu elementul din mijloc, continuam cautarea in stanga sau in dreapta
lui. Aceasta continuare presupune o repetare. Deci, vom folosii o instructiune repetitiva.
Mai exact, instructiunea while
[4.1] CONCRET! Daca cautam v in secventa 𝒙𝒌 , … . , 𝒙𝒑 , stabilim indicii din stanga si din dreapta, s=k si d=p
si scriem astfel:
s=k;
d=p;
poz=-1;
while (s<=d){
m=(s+d)/2;
if (x[m]==v){
poz=m;
break;
}
else
if (s<d){
if (v>x[m])
s=m+1;
else
d=m-1;
}
else
break;
}
if (poz==-1)
cout<<"nu exista";
else
cout<<poz;
PROBLEME PROPUSE
[1] Consideram sirul 𝒙𝟏 , … . , 𝒙𝒏 cu elementele sortate crescator.
a) Afiseaza pozitia pe care se gaseste v in sirul dat
b) cauta valoarea v in prima jumatate a sirului dat
c) cauta valoarea v in a doua jumatate a sirului dat
d) considerand ca valoarea v se gaseste in sir, sa se precizeze cate elemente sunt mai mici ca v
e) considerand ca valoarea v se gaseste in sir, sa se precizeze cate elemente sunt mai > ca v
f) considerand ca sirul are si elemente egale, sa se precizeze cate elemente sunt egale cu v
g) considerand ca a si b, a<b, se gasesc in sir, sa se precizeze cate elemente sunt in [a,b]
h) considerand ca a si b, a<b, se gasesc in sir, sa se precizeze cate elemente nu sunt in [a,b]
R:
Problemele se rezolva ca la observatia [4], adaptata si putin amplificata in partea de afisare.
2
CAUTARE BINARA
[2] Consideram sirul 𝒙𝟏 , … . , 𝒙𝒏 cu elementele sortate crescator.
a) Afiseaza pozitia pe care s-ar insera v astfel incat sirul sa ramana crescator
b) cauta primul element din sir care ∈ (𝑎, ∞)
c) cauta primul element din sir care ∈ [𝑎, ∞)
d) cauta ultimul element din sir care ∈ (−∞, 𝑎)
e) cauta primul element din sir care ∈ (−∞, 𝑎]
R:
a)
Ideea generala se mentine. Se amplifica cu analiza situatiei in care valaoare v nu se afla in sir, dar se poate
situa intre doua elemente ale sirului. De aceea, daca v nu este egal cu elementul din mijloc, trebuie luata in
calcul varianta de a se afla intre cel din mijloc si cel din dreapta acestuia, sau sau intre cel din mijloc si cel
din stanga acestuia.
ATENTIE! Din start se analizeaza situatia in care v este mai mic decat primul element sau mai mare decat
ultimul element.
cout<<"v="; cin>>v;
if (v<=x[1])
poz=1;
else
if (v>x[n])
poz=n+1;
else{
s=1; d=n;
poz=-1;
while (s<=d){
m=(s+d)/2;
if (x[m]==v){
poz=m; break;
}
else
if (s<d){
if (v>x[m]){
if (v<x[m+1]){
poz=m+1; break;
}
else
s=m+1;
}
else{
if (v>x[m-1]){
poz=m;
}
else
d=m-1;
}
}
else{
poz=s; break;
}
}
}
cout<<poz;
3
break;
CAUTARE BINARA
b)
In fond, cautam pe 𝒂 in sir si pastram pozitia elementului din sir care este mai mare decat 𝒂.
In logica de la a)
cout<<"a="; cin>>a;
if (a<x[1])
poz=1;
else
if (a>=x[n])
poz=-1;
else{
s=1;
d=n;
poz=-1;
while (s<=d){
m=(s+d)/2;
if (x[m]==a){
poz=m+1; break;
}
else
if (s<d){
if (a>x[m]){
if (a<x[m+1]){
poz=m+1;
}
else
s=m+1;
break;
}
else{
if (a>x[m-1]){
poz=m; break;
}
else
d=m-1;
}
}
else{
poz=s;
}
}
}
cout<<poz;
4
break;