Lucrarea nr.2

TDA ARBORE BINAR

1. Definitie

Un arbore binar e o multime de n >= 0 noduri, care daca nu este vida, contine un nod numit radacina, restul nodurilor formand doi arbori disjuncti numiti subarborele stang si subarborele drept.

Aceasta structura de date e importanta pentru ca e usor de reprezentat si prelucrat, orice arbore putand fi transformat in arbore binar .

2. Tehnica transformarii unui arbore generalizat in arbore binar

Un arbore generalizat poate fi transformat intr-un arbore binar, astfel incat secventele de noduri pentru parcurgerea in preordine sa fie identice in cazul ambilor arbori.

Un arbore generalizat A cu radacina A1 si subarborii A1,1, A1,2, ...,A1,k se transforma in arbore binar avand radacina A1, A1,1 fiul sau stang, iar A1,i devin fiii drepti ai lui A1,i-1 pentru 2<=i<=k.

Secventele de noduri in parcurgerea in preordine a arborelui generalizat si a celui binar obtinut prin transformare, sunt identice. Fig. 1 . Exemplu de transformare a unui arbore generalizat

Exemplu: Se considera arborele generalizat din figura 1. Aplicand regula descrisa mai sus, se obtine arborele binar din figura.

3.Tehnici de implementare a TDA arbore binar

3.1. Implementarea cu ajutorul tablourilor

Varianta a.) O prima implementare se poate realiza printr-un tablou de dimensiune egala cu numarul nodurilor, fiecare intrare avand trei campuri: cheia nodurilor si cate un cursor la fiul stang si drept.

var t : array [1..maxnod] of record
			        cheie : tip_cheie;
        			stang,drept : 0..maxnod
     end;

Varianta b.) O alta implementare se bazeaza pe doua leme ce se vor preciza mai jos.

Lema1: Numarul maxim de noduri al nivelului i al unui arbore binar este 2i-1. Astfel numarul maxim de noduri al unui arbore binar de inaltime h este 2h-1.

Arborele binar de inaltime h cu exact 2h-1 noduri se numeste arbore binar plin de inaltime h.

Numerotand secvential nodurile unui arbore binar plin de inaltime h, incepand cu nodul radacina (de pe nivelul 1) si continuand nivel cu nivel, de la stanga la dreapta, se poate realiza o implementare eleganta a structurii de arbore, asociind fiecarui nod locatia corespunzatoare numarului sau intr-un tablou liniar:

const nr_noduri={2h-1};
     var t : array [1..nr_noduri] of tip_cheie;

Un arbore binar oarecare va pastra numerotarea nodurilor existente, ca intr-un arbore complet.

Lema urmatoare precizeaza maniera simpla in care se poate determina tatal, fiul stang si fiul drept al unui nod precizat.

Lema 2: Pentru un nod oarecare cu indicele i, 1<=i<=n, sunt valabile relatiile:

TATA(i) - e nodul cu indicele [i/2], daca i <> 1;

FIUL_STANG(i) - e nodul cu indicele 2*i daca 2*i <= n;

FIUL_DREPT(i) - e nodul cu indicele 2*i+1 daca 2*i+1 <= n.

Aceasta implementare e avantajoasa doar pentru arbori binari completi, dar dezavantajoasa la insertia sau suprimarea unui nod.

Exemplu: Se considera arborele binar din figura 2. Acesta poate fi memorat intr-un tablou in forma indicata in figura. Fig. 2. Implementarea arborilor binari cu ajutorul tablourilor

3.2. Implementarea cu ajutorul pointerilor

Un arbore binar poate fi descris cu ajutorul urmatoarei structuri de date dinamice:
type ref = ^nod;
     nod =  record
           cheie:tip_cheie;
	   stang,drept:ref
       end;
var radacina:ref;
Aceasta implementare e cea mai avantajoasa, inlaturand limitarile reprezentarii secventiale si utilizand proprietatile recursive ale tipului arbore.

4. Operatorii TDA arbore binar

4.1. Traversarea arborilor binari

Pentru un arbore binar, notand cu R radacina si cu A si cu B subarborele sau stang, respectiv drept, cele 3 posibilitati de traversare sunt:

preordine - lista R, A, B

inordine - lista A, R, B

postordine- lista A, B, R.

Cele trei metode de traversare se concretizeaza in trei proceduri recursive in care Prelucrare e operatia ce trebuie facuta asupra fiecarui nod (tipul nod e cel definit mai sus). Se va prezenta procedura Preordine. Algoritmul de parcurgere este acelasi, indiferent de metoda de implementare a arborelui. Diferentele de implementare vor consta in modul de gasire a fiilor nodului curent(fiul stang si drept).

procedure preordine(r:ref);
  begin
    if r <> nil then
      begin
           prelucrare(r^);
           preordine(r^.stang);
           preordine(r^.drept)
      end
  end;
Urmatoarea parcurgere in inordine permite vizualizarea pe nivele a arborelui (rotit cu 90 grade spre dreapta ):
procedure tipareste_arbore(r:ref; h:integer);
  var i:integer;

	  begin {tipareste arborele r}

	    if r<>nil then
	     with r^ do
	       begin
		 tipareste_arbore(stang,h-5);
		 for i:=1 to h do write(' ');
		 writeln(cheie);
		 tipareste_arbore(drept,h-5)
	       end {with}
	 end; {tipareste_arbore}

4.2. Arbori binari ordonati. Arbori binari de inaltime minima

Arborele binar ordonat e arborele binar cu proprietatea ca parcurgand nodurile in inordine, secventa cheilor este monoton crescatoare.

Are proprietatea ca daca un nod oarecare al arborelui are cheia c, toate nodurile din subarborele stang al nodului au cheile mai mici decat valoarea c, respectiv toate cheile din subarborele drept au cheile mai mari sau egale cu c. De aici rezulta procedeul de cautare foarte simplu, prin trecerea la fiul stang sau drept de la nodul curent, functie de relatia dintre cheia cautata si cea a nodului curent.

Cum inaltimea minima a unui arbore binar ordonat cu n noduri este hmin=[log2 (n+1)], rezulta ca o cautare intr-un arbore binar ordonat necesita aproximativ log2n comparatii de chei, fata de n/2 comparatii intr-o lista liniara.

4.3. Tehnici de cautare intr-un arbore binar ordonat

Pentru a cauta un nod cu o cheie data x in cadrul unui arbore binar ordonat, se parcurge arborele, incepand cu radacina, pana la gasirea nodului cautat sau pana la terminarea drumului in arbore. La fiecare nod, se va urma in continuare calea spre fiul stang sau spre cel drept, dupa cum cheia x este mai mica sau mai mare decat cheia nodului curent. Se va returna pointerul spre nodul cu cheia cautata sau nil daca nu s-a gasit o astfel de cheie.

  	
function loc(x:integer;t:ref):ref;
  var gasit:boolean;
    begin
	      gasit:=false;
	      while (t <> nil) and not gasit do
	        begin
	          if t^.cheie = x then gasit:=true
          else
	            if t^.cheie < x then t:=t^.stang
                        else t:=t^.drept
        end;
      loc:=t
    end;
Cautarea se poate simplifica aplicand metoda fanionului, modificand structurile arborelui astfel incat orice referinta nil se inlocuieste cu cea spre nodul fanion. inainte de inceperea cautarii, cheia nodului fanion se asigneaza cu valoarea cautata x, astfel incat va exista in arbore cel putin un nod cu acea cheie.
var fanion:ref;
function loc1(x:integer;t:ref):ref;
  begin
    fanion^.cheie:=x;
    while t^.cheie <> x do
      if x < t^.cheie then t:=t^.stang
      else t:=t^.drept;
    loc1:=t
  end;
Faptul ca valoarea cautata x exista in arbore e indicat de o valoare returnata de functia loc1 diferita de fanion.

4.4. Tehnici de creare a arborilor binari ordonati

Procesul de creare consta in insertia cate unui nod intr-un arbore binar ordonat, care initial este vid, astfel incat dupa insertie el sa ramana ordonat.

Pentru aceasta se traverseaza arborele incepand cu radacina si se selecteaza fiul stang sau drept, dupa cum cheia de inserat e mai mica sau mai mare decat a nodului parcurs. Se repeta pana cand se ajunge la un pointer nil care se inlocuieste cu pointerul spre noul nod creat. Pentru ca sortarea sa fie stabila, se trece la fiul drept chiar daca valoarea cheii e egala.

procedure inarbior(x:integer; var t:ref);
  begin
    if t <> nil then
      if x < t^.cheie then inarbior(x,t^.stang)
  else inarbior(x,t^.drept)
    else { t = nil }
      begin
        new(t);
        with t^ do begin
            cheie:=x;
            stang:=nil;
            drept:=nil
        end { with }
      end
  end;

4.5. Tehnica suprimarii unui nod dintr-un arbore binar ordonat

In urma suprimarii unui nod avand cheia x dintr-un arbore binar ordonat, acesta trebuie sa ramana ordonat.

Cazurile ce se disting sunt functie de numarul de fii ai nodului ce se suprima. Daca numarul fiilor este:

cel mult unu - referinta spre nodul de suprimat se inlocuieste cu referinta spre unicul sau fiu ( sau nil daca nodul e terminal ); Fig. 3. Stergerea unui nod dintr-un ABO, cazul in care nodul de sters are 2 fii

doi fii

4.6. Construirea unui arbore binar total echilibrat

Se numeste arbore binar total echilibrat (sau perfect echilibrat), un arbore in care, pentru fiecare nod, numarul nodurilor din subarborele sau stang difera cel mult cu unu de cel al nodurilor subarborelui drept. In consecinta, toate nodurile terminale ale unui asemenea arbore sunt pe ultimele doua nivele.

Avand secventa ordonata crescator a celor n noduri ale arborelui ( cea care se va obtine la parcurgerea in inordine ), construirea ABO total echilibrat se realizeaza prin urmatorul algoritm recursiv: