You are on page 1of 5

Arbori binari de cutare

1. Ce este un arbore binar de cutare? Un caz particular de arbori binari sunt arborii de cutare, n care informaia din fiecare nod este mai mare dect informaia din nodul fiului stng i mai mic sau egal cu cea din nodul fiului drept. Un astfel de arbore se poate reprezenta printr-o structur de date nlnuit, n care fiecare nod este un obiect. Pe lng un cmp cheie i date adiionale, fiecare obiect nod conine cmpurile stnga, dreapta i p care puncteaz spre nodurile corespunztoare fiului stng, fiului drept i respectiv printelui nodului. nt-un arbore binar de cutare, cheile sunt ntotdeauna astfel memorate nct ele satisfac proprietatea arborelui binar de cutare: Fie x un nod dintr-un arbore binar de cutare. Dac y este un nod din subarborele stng al lui x, atunci cheie[y] cheie[x]. Dac y este un nod din subarborele drept al lui x, atunci cheie[x] cheie[y]. Exemple:

(a)

(b)

2. Operaii specifice ntr-un arbore binar de cutare Arborii de cutare sunt structuri de date ce posed multe operaii specifice structurilor dinamice, precum: CAUT, MINIM, MAXIM, PREDECESOR, SUCCEOSR, INSEREAZ i TERGE. Proprietatea arborelui binar de cutare ne permite s tiprim toate cheile n ordine cresctoare cu ajutorul unui algoritm recursiv simplu, numit traversarea arborelui n inordine: se tiprete cheia rdcinii unui subarbore ntre valorile din subarborele su stng i cele din subarborele su drept. Similar, o traversare a arborelui n preordine va tipri cheia rdcinii naintea cheilor din subarbori, iar o traversare a arborelui n postordine va tipri cheia rdcinii dup cheile din subarbori. Procedura de tiprire a elementelor unui arbore binar de cutare (apelul cu nodul rdcin): ARBORE-TRAVERSARE-INORDINE(x) 1. dac x NIL atunci 2. ARBORE-TRAVERSARE-INORDINE (stnga[x]) 3. afieaz cheie[x] 4. ARBORE-TRAVERSARE-INORDINE (dreapta[x]) Spre exemplu, traversarea n inordine a arborelui din exemplul (a) afieaz cheile: 2, 3, 4, 5, 8, 9. 2.1. Cutarea Procedura de cutare a unui nod avnd cheia cunoscut (un pointer x la rdcina arborelui i o valoare k a cheii) returneaz un pointer la nodul avnd cheia k (dac exist un asemenea nod n arbore) sau NIL n caz contrar. ARBORE-CAUT (x, k)

1. dac x = NIL sau k = cheie[x] atunci 2. returneaz x 3. dac k < cheie[x] atunci 4. returneaz ARBORE-CAUT (stnga[x], k) 5. altfel 6. returneaz ARBORE-CAUT (dreapta[x], k) Aceeai procedur se poate scrie i iterativ: ARBORE-CAUT-ITERATIV(x, k) 1. ct timp x NIL i k cheie[x] execut 2. dac k < cheie[x] atunci x stnga[x] 3. altfel x dreapta[x] 4. returneaz x 2.2. Minimul i maximul Determinarea elementului avnd cheia minim dintr-un arbore binar de cutare se realizeaz ntotdeauna urmnd pointerii fiu stnga ncepnd cu rdcina i terminnd cnd se ntlnete NIL. Procedura urmtoare ntoarce un pointer la elementul minim din subarborele a crui rdcin este nodul x: ARBORE-MINIM (x) 1. ct timp stnga[x] NIL execut 2. x stnga[x] 3. returneaz x Pseudocodul pentru procedura ARBORE-MAXIM este simetric. ARBORE-MAXIM (x) 1. ct timp dreapta[x] NIL execut 2. x dreapta[x] 3. returneaz x 2.3. Succesorul i predecesorul unui nod Structura de arbore binar de cutare permite determinarea succesorului unui nod chiar i fr compararea cheilor. Procedura urmtaore returneaz succesorul unui nod x dintr-un arbore binar de cutare (dac succesorul exist), sau NIL, dac x are cea mai mare cheie din arbore. ARBORE-SUCCESOR (x) 1. dac dreapta[x] NIL atunci 2. returneaz ARBORE-MINIM (dreapta[x]) 3. y p[x] 4. ct timp y NIL i x = dreapta[y] execut 5. x y 6. y p[y] 7. returneaz y Procedura ARBORE-PREDECESOR este similar. 2.4. Inserarea i tergerea Vom folosi procedura ARBORE-INSEREAZ pentru a insera o nou valoare v ntr-un arbore binar de cutare T. Procedurii i se transmite un nod z pentru care cheie[z] = v, stnga[z] = NIL i dreapta[z] = NIL. Ea va modifica arborele T i unele dintre cmpurile lui z astfel nct z va fi inserat pe poziia corespunztoare n arbore. ARBORE-INSEREAZ (T, z) 1. y NIL 2. x rdcin[T] 3. ct timp x NIL execut y x 4. dac cheie [z] < cheie[x] atunci x stnga[x] 5. altfel x dreapta[x] 6. p[z] y

7. dac y = NIL atunci rdcin[T] z 8. altfel dac cheie[z] < cheie[y] atunci stnga[y] z 9. altfel dreapta[y] z Pseudocodul procedurii ARBORE-TERGE permite tergerea unui nod dat z dintr-un arbore binar de cutare care primete ca argument un pointer la z. ARBORE-TERGE (T, z) 1. dac stnga[z] = NIL sau dreapta[z] = NIL atunci 2. y z 3. altfel y ARBORE-SUCCESOR(z) 4. dac stnga[y] NIL atunci x stnga[y] 5. altfel x dreapta[y] 6. dac x NIL atunci p[x] p[y] 7. dac p[y] = NIL atunci rdcin[T] x 8. altfel dac y = stnga[p[y]] atunci stnga[p[y]] x 9. altfel dreapta[p[y]] x 10. dac y z atunci cheie[z] cheie[y] {se copiaz i datele adiionale ale lui y} 11. returneaz y 3. Aplicaie Pentru evidena elevilor unei coli se definete un arbore binar de cutare, n care fiecare nod va memora numrul matricol, numele i numrul de absene ale unui elev. Cutarea n arbore se va face dup numrul matricol al elevilor. Scriei un program care, prin intermediul unui meniu, selecteaz n mod repetat, atta timp ct utilizatorul dorete acest lucru, una din urmtoarele aciuni: - adugarea unui elev; - afiarea absenelor pentru numrul matricol minim; - afiarea absenelor pentru numrul matricol maxim; - modific numrul de absene al unui elev pentru care se cunoate numrul matricol; - afieaz toi elevii al cror nume ncepe cu litera B. program aplicatie; type pnod=^nod; nod=record nr:integer; nume:string; abs:integer; st, dr: pnod; end; var r:pnod; n,op: integer; num:string; abs1:integer; exista:boolean; procedure creare (var p:pnod;n:integer; num:string; abs1:integer); {creeaza un nod al arborelui ce va contine un elev cu numarul matricol n, numele num si nr. de absente abs1} begin if p<>nil then begin if n<p^.nr then creare(p^.st, n, num, abs1) else if n>p^.nr then creare(p^.dr, n, num, abs1) else writeln(' elevul exista') end else begin new(p); p^.nr:=n; p^.nume:=num; p^.abs:=abs1;

p^.st:=nil;p^.dr:=nil; end; end; procedure SRD(p:pnod); begin if p<>nil then begin SRD(p^.st); writeln(' ',p^.nr,' ',p^.nume,' ',p^.abs); SRD(p^.dr); end; end; function min(p:pnod):integer; { cheia minima se gaseste in nodul cel mai din stinga, pornind de la radacina} begin if p^.st<>nil then min:=min(p^.st) else min:=p^.abs; end; function max(p:pnod):integer; {cheia maxima se gaseste in nodul cel mai din dreapta, pornind de la radacina} begin if p^.dr<>nil then max:=max(p^.dr) else max:=p^.abs; end; procedure elevi_B(p:pnod); { afiseaza elevii care au numele incepind cu litera B} begin if p<>nil then begin if (p^.nume[1]='B') then begin exista:=true; writeln(' ',p^.nr,' ',p^.nume,' ',p^.abs); end; elevi_B(p^.st); elevi_B(p^.dr); end end; procedure modifica_abs(p:pnod;n:integer); { modifica nr. de absente pentru care se cunoaste numarul matricol} begin if p<>nil then begin if n<p^.nr then modifica_abs(p^.st, n) else if n>p^.nr then modifica_abs(p^.dr, n) else begin write(' absenta='); readln(abs1); p^.abs:=abs1; end end else writeln(' Elevul cu numarul matricol ',n,' nu exista'); end; begin

r:=nil; repeat writeln(' alegeti optiunea:'); writeln(' 1 - ADAUGAREA unui elev'); writeln(' 2 Absente pentru matricol MINIM'); writeln(' 3 Absente pentru matricol MAXIM'); writeln(' 4 - MODIFICA numarul de absente'); writeln(' 5 - ELEVII cu numele - B'); writeln(' 6 - LISTA tuturor elevilor'); writeln(' 0 - IESIRE'); writeln; readln(op); case op of 1:begin write(' numar matricol= '); readln(n); write(' nume elev= '); readln(num); write(' numar absente= '); readln(abs1); creare(r,n,num,abs1); end; 2:begin writeln(' Valoarea absentei pentru matricol MINIM'); writeln(' min=',min(r)); end; 3: begin writeln(' Valoarea absentei pentru matricol MAXIM'); writeln(' max=',max(r)); end; 4: begin write(' numar matricol='); readln(n); modifica_abs(r,n); end; 5:begin exista:=false; elevi_B(r); if not exista then writeln(' nu exista elevi cu numele - B'); end; 6:begin writeln; writeln(' lista tuturor elevilor'); SRD(r); end; end; until op=0; readln; end.