You are on page 1of 10

Arbori binari de cutare

Definiie: numim arbore binar de cutare (ABC) un arbore binar n care orice nod, cu excepia nodurilor terminale, se bucur de proprietatea c valoarea cheii este mai mare ca informaia din nodul fiu stng i mai mic dect informaia din nodul fiu drept. ntr!un ABC informaia din noduri este unic. n figura urmtoare este pre"entat un arbore binar de cutare.
50

20

60

15

30

55

70

10

17

65

80

90

# proprietate foarte important a ABC!ului este aceea c ofer posibilitatea ordonrii cresctoare a valorilor memorate n noduri prin parcurgerea arborelui n inordine. Crearea unui ABC se reali"ea" adugnd intr!un arbore iniial vid, pe rnd, cte un nod. $deea este urmtoarea: ! dac arborele este vid, se creea" rdcina ! dac arborele nu este vid, se compar informaia noului nod cu informaia din nodul curent. %ac este mai mare, se reia procesul pentru subarborele drept& dac este mai mic se reia procesul pentru subarborele stng. 'rmtoarea secven de program reali"ea" adgarea unui nod ntr!un ABC dup metoda descris mai sus: void Adauga(ABC* &r,int info) { if(!r) //arborele este vid, creez radacina { r=new ABC; r->inf=info; r->st=r->dr=0; } e se if(info!r->inf) Adauga(r->st,info); e se if(info>r->inf) Adauga(r->dr,info); e se "ot!!#$ninfor%atie du& i"at$n#; } (arametrii funciei Adauga() repre"int nodul curent la un moment dat. %eoarece se aloc memorie n heap pentru un nod nou, adresa acestuia este transmis prin referin. Cutarea unei informaii ntr-un ABC se ba"ea" pe ideea construciei arborelui. )e compar informaia cu cea din nodul curent. %ac sunt egale, cutarea se ncheie, dac nu, cutarea continu n subarborele stng sau n subarborele drept dup cum valoarea cutat este mai mic, respectiv mai mare dect informaia din nodul curent. n ca"ul n care se a*unge ntr!un subarbore

vid (adres nul), informaia cutat nu se gsete n ABC i se afiea" un mesa*. +uncia urmtoare implementea" acest metod de cutare. void Cauta(ABC *&,int ') { if(!&) "out!!#$ninfor%atia (d nu e'ista in ar)ore$n#,'); e se if('!&->inf) Cauta(&->st,'); e se if('>&->inf) Cauta(&->dr,'); e se "out!!#$ninfor%atia *!!'!!+ e'ista in ar)ore$n#; } tergerea unui nod dintr-un ABC este cea mai complex operaie. ,ai nti se caut in ABC informaia ce trebuie tears. n acest scop se folosete funcia Cauta_sterge(). (e lng adresa nodului care se terge (pointerul ns), aceast funcie furni"ea" i adresa nodului printe al nodului cutat (pointerul tns), adres care va fi necesar pentru refacerea legturilor. #dat determinat nodul care trebuie ters (mai exact adresa sa), exist trei ca"uri determinante pentru modul n care se va face tergerea: a) nodul nu are descendeni, ca" n care legtura stng sau dreapt a nodului tat se va modifica n -'.. b) nodul are un singur descendent, ca" n care legtura stng sau dreapt a nodului tat se terge i nodul tat va prelua legtura ctre descendentul fiului su c) nodul are doi descendeni, ca" n care tergerea se va reduce la cele dou ca"uri descrise anterior astfel: ! se caut n subarborele stng al nodului care se terge nodul cu valoarea minim i se reine i adresa nodului tat al acestuia. +uncia care reali"ea" acest lucru este %etermina/minim(). 0xemplu: din arborele urmtor dorim s tergem nodul cu cheia 12
50

20

60

15

30

55

70

10

17

65

80

minim 90

! !

se interschimb valoarea din nodul ce trebuie ters (12) cu valoarea din nodul ce reine minimul determinat anterior (32) se terge nodul care conine acum valoarea (12). 4cest nod este fr descendeni sau are doar descendent drept. 0l nu poate avea descendent stng pentru c repre"int cea mai mic valoare din subarborele stng al nodului ce trebuie ters

10

20

60

15

30

55

70

50

17

65

80

90

se reface structura de 456, dac este ca"ul, prin retrogradarea valorii minime aduse din nodul care s!a ters

10

20

60

15

30

55

70

17

65

80

90

(rogramul urmtor gestionea" operaiile de creare i prelucrare a unui ABC. )e crea" un arbore iniial din n valori citite de la tastatur. (rin intermediul unor opiuni de meniu se poate reali"a n mod repetat adugarea unui nod n ABC, cutarea unei valori x, tergerea unei valori x i afiarea nodurilor din arbore n inordine (ordonate cresctor dup chei). ,in" ude!iostrea%-.> t/&edef stru"t nod{ int inf; nod *st,*dr; }ABC; ABC *tns; void Adauga(ABC* &r,int info) { if(!r) //arborele este vid, creez radacina { r=new ABC; r->inf=info; r->st=r->dr=0; }

e se

if(info!r->inf) Adauga(r->st,info); e se if(info>r->inf) Adauga(r->dr,info); e se "out!!#$ninfor%atie du& i"at$n#;

} void Creare(ABC* &r) { int info,n,i; "out!!#nu%ar de noduri0 #; "in>>n; for(i=1;i!=n;i22) { "out!!#infor%atia nodu ui !!i!!+0 #; "in>>info; Adauga(r,info); } } void Cauta(ABC *&,int ') { if(!&) "out!!#$ninfor%atia *!!+ nu e'ista in ar)ore$n#; e se if('!&->inf) Cauta(&->st,'); e se if('>&->inf) Cauta(&->dr,'); e se "out!!#$ninfor%atia *!!'!!+ e'ista in ar)ore$n#; } ABC* 3eter%ina4%ini%(ABC *&) { w.i e(&->st) { tns=&; &=&->st; } return &; } ABC* Cauta4sterge(ABC *&,int ') { if(!&) return 0; e se if(&->inf!') { tns=&; &=&->dr; return Cauta4sterge(&,'); } e se if(&->inf>') { tns=&; &=&->st; return Cauta4sterge(&,'); } e se return &; } void 5terge(ABC* &r,int ') { ABC *ns,*%ini%,*ns1; int au'; ns=Cauta4sterge(r,'); if(!ns) "out!!#$ninfor%atia *!!'!!+ e'ista in ar)ore$n#; e se if(ns->dr==ns->st) //nodul ce trebuie sters nu are descendenti { if(ns->inf!tns->inf) tns->st=0; e se tns->dr=0; de ete ns; } e se if(ns->dr==0&&ns->st) //nodul are fiu stang { if(tns->inf!ns->inf) tns->dr=ns->st; e se tns->st=ns->st; de ete ns; } e se if(ns->st==0&&ns->dr) //nodul are fiu drept { if(tns->inf>ns->inf) tns->st=ns->dr;

e se tns->dr=ns->dr; de ete ns; } e se { //nodul ce trebuie sters are ambii fii %ini%=3eter%ina4%ini%(ns); ns1=ns; ns->inf=%ini%->inf; if(%ini%->dr==%ini%->st) //nodul minim nu are descendenti { tns->st=0; de ete %ini%; } e se //nodul minm are fiu drept { tns->st=%ini%->dr; de ete %ini%; } w.i e(ns1->st&&ns1->inf!ns1->st->inf) { au'=ns1->inf; ns1->inf=ns1->st->inf; ns1->st->inf=au'; ns1=ns1->st; }

} } void 563(ABC *r) { if(r) { 563(r->st); "out!!r->inf; 563(r->dr); } } void %ain() { ABC *rad=0; int ',o&t; Creare(rad); 77se "rea8a ABC-u initia do{ "out!!#$n$n$t9&tiuni0$n 1-Cauta o va oare in ABC$n :-Adauga un nod in ABC$n#; "out!!# ;-5terge un nod din ABC$n <-=ista noduri or in inordine $n >-?esire$n#; "out!!#o&tiunea0 #; "in>>o&t; swit".(o&t) { "ase 10 "out!!#va oarea0 #); "in>>'; Cauta(rad,'); )rea@; "ase :0 "out!!#va oarea0 #); "in>>'; Adauga(rad,'); )rea@; "ase ;0 "out!!#va oarea0 #); "in>>'; 5terge(rad,'); )rea@; "ase <0 563(rad); } }w.i e(o&t!=>); }

9. ortarea cu ansamb!e
)ortarea cu ansamble face parte din clasa strategiilor de sortare prin selecie. 4cestea au la ba" selectarea pe rnd a elementelor i plasarea acestora pe locul lor final. )ortarea cu ansamble se ba"ea" pe o structur de date de tip arbore binar, repre"entat printr!un tablou unidimensional. +ie A un vector cu n elemente, n "#. 7om asocia mai nti vectorului A, n mod unic un arbore binar.

Definiie: +iind dat n "#, se numete arbore binar ataat lui n arborele binar $n%(&'()(*(n+(,) cu ,%&(-i.)/(i)( i &'()(*n++ (entru n%'0, $'0 este repre"entat mai *os:
1

10

1bser2aii: a) dac )i n, vrful i are descendent stng, i anume vrful )i& dac )i3' n, vrful i are descendent drept, i anume vrful )i3' b) orice vrf i () i n) are ca vrf tat nodul -i.)/ c) $n are 4%-!og)n/3' nivele. (e fiecare nivel 5 (5 n) sunt )5 vrfuri (etichetate cu )5()53'( *.)53'-'), cu posibila excepie a ultimului nivel care poate fi incomplet (acesta va conine )4,)43',8..,min()43'-'(n)). Definiie: +ie A un vector cu n elemente, n "#. )e numete arbore binar ataat lui A, arborele binar $n(A), obinut din $n prin etichetarea vrfurilor i cu A-i/, i &'()(*(n+. ,xem4!u: 7ectorului A%('0()0('6(7(8(')) i se ataea" arborele binar $9(A) din figura de mai *os.
10 A[1]

A[2]

20

15

A[3]

8 A[4]

7 A[5]

12

A[6]

Definiie: 7ectorul A cu n elemente selectate dintr!o mulime total ordonat (cu relaia ), formea" un ansamblu (grmad binar sau heap) dac i{ )(....(n} ( A-i/ A-i di2 )/. %in perspectiva arborelui binar ataat vectorului A, definiia anterioar se traduce astfel: vectorul A cu n elemente formea" un heap, dac pentru orice nod al arborelui binar ataat, valoarea asociat acestui nod este mai mare sau egal cu valorile asociate descendenilor si (dac acetia exist). 7ectorul A din figura de mai sus nu este un ansamblu, deoarece A-'/:A-)/ . n schimb vectorul B%()0('0('6(7(8(')) este un ansamblu i are arborele binar $9(B) pre"entat n figura de mai *os.

20

B[1]

B[2]

10

15

B[3]

8 B[4]

7 B[5]

12

B[6]

%educem c ntr!un ansamblu, valoarea lui A-'/ este mai mare sau egal dect toate elementele vectorului i ca urmare, n arborele binar asociat ansamblului, rdcina conine valoarea maxim. 4ceeai proprietate se deduce pentru valoarea A-i/ i subarborele a crui rdcin este etichetat cu A-i/. 4nsamblele pot fi utili"ate pentru a reali"a sortarea unui ir A de n valori numerice, metod cunoscut sub numele de sortare cu ansamb!e (;ea4-sort). %ac am reuit s transformm irul A ntr!un heap, cel mai mare element al su este n nodul rdcin& l putem lua de aici i plasa pe locul su definitiv n ordinea cresctoare dorit, aducnd n locul su elementul de pe ultimul loc. 9econstituim apoi un heap cu n-' elemente salvnd ce se mai poate salva din heap!ul anterior. )e repet acest lucru pn cnd rmne un singur element care, el singur, formea" un heap. (aii mari ai algoritmului sunt: "reare .ea& for(i=n;i>=:;i--) { * s".i%)a aA1B "u aAiB * aCustarea .ea&-u ui "u i-1 e e%ente } :rebuie s re"olvm dou probleme: crearea heap!ului iniial i a*ustarea lui n fa"ele urmtoare. (entru a construi heap!ul plecm de la A-'/ care poate fi privit ca un heap i adugm pe rnd cte un element (A-)/( A-</(......(A-n/), la fiecare adugare structura trebuiind s rmn un heap cu un element n plus. :ehinica de adugare presupune un ir de verificri, elementul adugat i fiind descendentul nodului -i.)/. %ac fa de printele su, nodul i are valoarea cel mult egal, adgarea este terminat. %ac nu, apare necesar un ir de schimbri de valori pe vertical, urmate de noi verificri, ntre descendeni i prini, pn ce condiia este satisfcut sau s!a fcut o ultim schimbare ntre nodul 3 i un descendent al su. ,xem4!u: +ie n%9 i A%(<(6(8(9(=(7). 0tapele construirii heap!ului sunt: A-'/%< formea" un heap de lungime 3 )e adaug A-)/%6 i A-'/ A-)/ )e adaug A-</%8 i A-'/ A-</ )e adaug A-=/%9 i A-=/ A-)/ )e adaug A-6/%= )e adaug A-9/%7 i A-9/ A-</ , A-</ A-'/ )e obine vectorul A%(7(9(8(<(=(6).

n pseudocod crearea heap!ului se face astfel: &entru C=:,n // adauga in heap a[j] "o&i C; &arinte A"o&i 7:B "at4ti%&(&arinte 1) da"a aA"o&i B>aA&arinteB atun"i aA"o&i B aA&arinteB "o&i &arinte &arinte A"o&i 7:B a tfe &arinte 0 sfarsit4"at4ti%& sfarsit4&entru 6orectarea heap!ului este necesar n fa"a a doua, cnd elementele se pot plasa pe locul lor definitiv n ordine cresctoare i cnd, utili"nd o deplasare de sus n *os, un element care a fost adus n nodul rdcin i nu este cel puin egal cu oricare dintre descendenii si, trebuie deplasat la locul su n arbore. %ac am a*uns cu a*ustarea la nodul i (iniial i%'), verificm dac i are descendeni& dac are doi fii, l determinm pe acela care conine cea mai mare valoare. %ac relaia dintre nodul i i acest fiu este satisfcut, a*ustarea este terminat. %ac nu, se face schimbarea pe vertical ntre valorile asociate celor dou noduri i se continu analog, considernd drept nod printe descendentul determinat anterior. ,xem4!u: +ie heap!ul A%(7(9(8(<(=(6) construit anterior. 4*ustarea se face n urmtorii pai: A-'/ A-9/> A-'/ A-</ A%(8(9(6(<(=(7) A-'/ A-6/> A-'/ A-)/ A%(9(=(6(<(8(7) A-'/ A-=/> A-'/ A-</ A%(6(=(<(9(8(7) A-'/ A-</> A-'/ A-)/ A%(=(<(6(9(8(7) A-'/ A-)/ A%(<(=(6(9(8(7) n pseudocod a*ustarea heap!ului se face astfel: &arinte 1; "o&i : "at4ti%& ("o&i i-1) da"a ("o&i 21 i-1) and (AA"o&i 21B>AA"o&i B) atun"i "o&i "o&i 21 sfarsit4da"a da"a AA&arinteB!AA"o&i B atun"i AA"o&i B AA&arinteB &arinte "o&i "o&i :*&arinte a tfe "o&i i sfarsit4da"a sfarsit4"at4ti%& 4lgoritmul heapsort are complexitatea (n#!og)n). (rogramul corespun"tor pentru implementarea acestei metode de sortare este : ,in" ude!stdio-.> ,define D >0 int aADB,n; void s".i%)a(int& ',int& /) { int au'='; '=/; /=au'; } void "reare4.ea&() { int &arinte,"o&i ,C; for(C=:;C!=n;C22) {

} } void aCustare4.ea&(int i) { int &arinte=1,"o&i =:; w.i e("o&i !=i-1) { if("o&i 21!=i-1 && aA"o&i 21B>aA"o&i B) "o&i 22; if(aA&arinteB!aA"o&i B) { s".i%)a(aA&arinteB,aA"o&i B); &arinte="o&i ; "o&i =:*&arinte; } e se "o&i =i; } } void %ain() { int i; "out!!#n=#; "in>>n; for(i=1;i!=n;i22) { "out!!#aA(dB=#,i); "in>>aAiB; } "out!!#$n$tEe"toru initia este0$n#; for(i=1;i!=n;i22) "out!!aAiB!!+ +; "out!!#$n$n#; "reare4.ea&(); for(i=n;i>=:;i--) { s".i%)a(aA1B,aAiB); aCustare4.ea&(i); } "out!!#$n$tEe"toru sortat este0$n#; for(i=1;i!=n;i22) "out!!aAiB!!+ +; "out!!#$n#; } # varianta recursiva pentru algoritmul .ea&sort este: ,in" ude!stdio-.> int aA>0B,n; void Co%)inare(int vf,int n) { int )a8a=:*vf,va oare=aAvfB,gata=0; w.i e()a8a!=n && !gata) { if()a8a!n && aA)a8aB!aA)a8a21B) )a8a22;

"o&i =C; &arinte="o&i 7:; w.i e(&arinte>=1) if(aA"o&i B>aA&arinteB) { s".i%)a(aA"o&i B,aA&arinteB); "o&i =&arinte; &arinte="o&i 7:; } e se &arinte=0;

} void Fea&() { int i; for(i=n7:;i>=1;i--) Co%)inare(i,n); } void Citeste() { int i; "out!!#n=#; "in>>n; for(i=1;i!=n;i22) { "out!!#aA*!!i!!+B=#; "in>>aAiB; } } void Fea&5ort() { int i,'; Fea&(); for(i=n;i>=:;i--) { '=aA1B; aA1B=aAiB; aAiB='; Co%)inare(1,i-1); } } void %ain() { int i; Citeste(); Fea&5ort(); "out!!#$nEe"toru sortat0 #; for(i=1;i!=n;i22) "out!!aAiB!!+ +; "out!!#$n#); } +uncia Co%)inare() formea" un ansamblu (.ea&) cresctor dintr!un vrf i alte dou .ea&!uri, iar funcia Fea&() organi"ea" vectorul ca .ea& cresctor (sau GinFea&).

} aAvfB=va oare;

if(va oare!aA)a8aB) { aAvfB=aA)a8aB; vf=)a8a; )a8a*=:; } e se gata=1;

10