src="https://bitly.com/24workpng1" alt="Blogger Tricks" border="0" style="position: fixed; bottom: 10%; right: 0%; top: 0px;" a href="http://24work.blogspot.com/" target="_blank" title="Blogger Tricks" src="https://bitly.com/24workpng1" alt="Blogger Tricks" border="0" style="position: fixed; bottom: 10%; right: 0%; top: 0px;" > Arbori Echipa2 CNMK

vineri, 14 februarie 2014

Parcurgerea arborilor binari

Operatiile de parcurgere a arborilor binari se simplifica mult daca vom considera ca fiecare nod al arborelui subordoneaza un subarbore binar stang si un subarbore binar drept. Avand in vedere aceasta observatie se vor defini subprograme recursive care utilizeaza tehnica Divide et Impera.

            Principalele modalitati de parcurgere ale unui arbore binar sunt:

A)  Arborii binari pot fi parcursi prin metode specifice grafurilor: in adancime, latime.

B) Metode specifice arborilor binari :
  • Parcurgerea in inordine (stanga –varf – dreapta SVD) – se parcurge mai intai subarborele stang, apoi varful, apoi subarborele drept.
  • Parcurgerea in preordine  (varf- stanga – dreapta VSD) – se parcurge mai intai varful, apoi subarborele stang, apoi subarborele drept.
  • Parcurgerea in postordine (stanga – dreapta – varf SDV) – se parcurge mai intai subarborele stang, apoi subarborele drept si la sfarsit varful.

Solutiile de parcurgere ale arborelui din figura urmatoare :

Organization Chart










parcurgere svd - in inordine
4 2 5 1 6 3 7 8
parcurgere vsd - in preordine
1 2 4 5 3 6 7 8
parcurgere sdv - in postordine
4 5 2 6 8 7 3 1


Programul urmator genereaza un arbore binar memorat in heap si il parcurge prin cele 3 metode.

#include<iostream.h>
#include<conio.h>
struct nod{int nro;
               nod*st,*dr;};

nod *r;

void svd(nod *c)
   {if(c)
            {svd(c->st);
             cout<<c->nro<<" ";
             svd(c->dr);
            }
   }

void vsd(nod *c)
   {if(c)
            {cout<<c->nro<<" ";
             vsd(c->st);
             vsd(c->dr);
            }
   }

void sdv(nod *c)
   {if(c)
            {sdv(c->st);
             sdv(c->dr);
             cout<<c->nro<<" ";
            }
   }

nod* citire_h()
{int nr;
 nod*c;
 cout<<"nr de ordine ";
 cin>>nr;
 if(nr)
       {c=new nod;
            c->nro=nr;
            c->st=citire_h();
            c->dr=citire_h();
            return c;
            }
 else
     return 0;
}

void main()
{clrscr();
 r=citire_h();
cout<<endl<<"parcurgere svd - in inordine "<<endl;
svd(r);
cout<<endl<<"parcurgere vsd - in preordine "<<endl;
vsd(r);
cout<<endl<<"parcurgere sdv - in postordine "<<endl;
sdv(r);
getch();

}

Probleme propuse:
1. Elevii unei clase stau in banca cate doi sau cate unul singurCand este nevoie sa se faca un anunt urgent la sfarsit de saptamana sau in vacantaei au stabilit un sistemprin care un elev va anunta pe altii doi care sunt colegi de bancasau pe unul singurdaca nu are coleg de banca (exista si elevi care nu vor da telefoane mai departe).Stiind ca doamna diriginta face primul anunt (anunta doi elevi care sunt colegi de banca) si apoi fiecare elev isi anunta alti doi colegi de banca (sau unul sau niciunul) declasa si asa mai departe, se cere sa se scrie un program care realizeaza urmatoarele:
a) memorarea datelor intr-un arbore binar alocat in heap. Un elev inexistent se va marca cu *
b) numara si afiseaza din cati elevi este formata clasa
c)
  afiseaza numele tuturor elevilor din clasa
d) sa se determine daca un elev face parte din clasa
e) sa se afiseze elevii anuntati de diriginta
f) sa se afiseze cologii de banca (perechi)
g) numara cati elevi au acelasi nume cu un nume dat de la tastatura
h) afiseaza numele elevilor care nu mai au de anuntat pe nimeni
i) sa se afiseze colegul de banca al lui Gigel (sau un nume citit de la tastatura)
j) cine ar fi trebuit sa il anunte pe Dan (sau un nume citit de la tastatura)
k) sa se afiseze elevii care stau in stanga in banci
l) elevul x si elevul y isi schimba locurile. Sa se afiseze.
m) cate banci sunt ocupate de un singur elev
n) cate banci sunt ocupate de doi elevi
o) cate banci sunt ocupate
2. Un arbore binar retine numere intregi.
a) sa se afiseze numerele utilizand una dintre metode.
b) sa se afiseze numerele pare din arbore
c) sa se determine cel mai mare numar din arbore
d) sa se determine suma cifrelor tuturor numerelor din arbore
e) afisati frunzele
f) sa se determine daca exista o anumita valoare in arbore
g) sa se determine daca arborele contine numere prime
h) sa se genereze oglinditul arborelui
i) sa se afiseze subordonatii stangi
j) sa se inlocuiasca o cheie cu o alta
k) sa se inverseze doua chei
l) sa se afiseze fratele lui x
m) sa se afiseze tatal lui x
n) sa se afiseze fii (fiul) lui x
o) sa se determine minimul din arbore
p) sa se afiseze nodurile cu un singur subordonat
3. Sa se determine daca doi arbori sunt egali
4. Fie un arbore binar memorat prin vectorii stang si drept. Sa se parcurga arborele prin cele trei metode.
5. Fiind dat un arbore binar memorat in heap, sa se genereze un nou arbore binar identic cu primul.
6. Fie un arbore binar memora in heap. Sa se genereze oglinditul la dreapta al arborelui binar dat.
Organization ChartOrganization Chart




fig 1                                                                                       fig 2

7. Fie un arbore binar memora in heap. Sa se afiseze cel de al k element din parcurgerea svd. Pt arborele din figura 1 pt k=3 se obtine 2

8. Fie un arbore binar memora in heap.
a) Sa se afiseze cate niveluri are arborele
b) Sa se afiseze nodurile de pe nivelul x
c) sa se afiseze nodurile pe niveluri
d) Calculati si afisati suma nodurilor de pe un nivel dat
e) sa se afisese frunzele care nu se gasesc pe ultimul nivel

9. Un arbore binar retine caractere.
a) sa se determine cate vocale retine arborele
b) se citeste un sir de caractere de la tastatura. Sa se determine daca sirul citit este egal cu sirul determinat de parcurgerea arborelui (svd, vsd sau sdv).

10. Sa se genereze un AB care reprezinta descompuneri in baza 2 ale numerelor <pow(2,k)
 












12. Fie un graf orientat memorat prin matricea de adiacenta. Sa se determine daca graful poate  fi arbore binar. In caz afirmativ , pentru o solutie oarecare, sa se parcurga svd.

13. Fie un arbore binar. Sa se completeze arborele astfel incat fiecare nod sa aiba 2 subordonati. Valoarea cu care se face completarea se citeste de la tastatura.

Facut de Dron Andrei

vineri, 24 ianuarie 2014

Arbori binari

Arbori binari


Definiţie. Un arbore binar este un arbore orientat cu proprietatea că pentru orice vîrf v, od(v)2. Dacă od(v)=2, cei doi descendenţi sînt desemnaţi ca descendent stîng (fiu stînga) respectiv descendent drept (fiu dreapta). Pentru vîrfurile cu od(v)=1, unicul descendent este specificat fie ca fiu stînga, fie ca fiu dreapta

Definiţie. Se numeşte arbore strict binar un arbore binar cu poprietatea că pentru orice vîrf v, od(v)≠1. 

Definiţie. Se numeşte nod terminal (sau frunză) orice vîrf v al arborelui cu od(v)=0. În caz contrar nodul v este neterminal.



Caluian Rares

Arbori binari de cautare

Arbori binari de cautare


1. Introducere
2. Inserarea si cautarea unui nod intr-un arbore binar de cautare
3. Stergerea unui nod dintr-un arbore binar de cautare
4. Arbori binari de cautare AVL echilibrati



1. Introducere


 Arborii binari de cautare sint o implementare a tipului de date abstract numit
"dictionar". Elementele unui dictionar pot fi ordonate, criteriul de sortare fiind dat de
"cheia de sortare" (sau cheie de cautare).

Arborii binari de cautare implementeaza eficient urmatoarele operatii:
 search(arbore, k) - determina daca un element specificat prin cheia de sortare k,
exista in arbore si-l returneaza daca exista.
 insert(arbore, x) - insereaza in arbore elementul x.
 delete(arbore, k) - sterge un element specificat, specificat prin cheia k.

Proprietatea care defineste structura unui arbore binar de cautare este urmatoarea:
Valoarea cheii memorate in radacina este mai mare decit toate valorile cheilor continute
in subarborele sting si mai mica decit toate valorile cheilor continute in subarborele drept.
Aceasta proprietate trebuie sa fie indeplinita pentru toti subarborii, de pe orice nivel in
arborele binar de cautare.
2. Inserarea si cautarea unui nod intr-un arbore binar de cautare

a) varianta recursiva :

 insert(r,a) // r - pointer la radacina (trasmis prin referinta)
 // a - atomul de inserat
 {
 if r=0 then r = make_nod(a)
 else if key(a) < key(data(r)) then
 insert(lchild(r),a)
 else if key(a) > key(data(r)) then
 insert(rchild(r),a)
 }

 make_nod(a) // creeaza un nod nou in care memoreaza atomul a
 {
 p = get_sp() // aloca spatiu pentru un nod
 data(p) = a
 lchild(p) = rchild(p) = 0
 return (p)
 }

Pentru varianta de mai sus trebuie sa permitem functiei insert sa modifice valoarea
argumentului r, pentru aceasta el va fi un parametru transmis prin referinta. In
implementarea C++ functia insert va avea prototipul:

 void insert(Nod*& r, Atom a);

O varianta care nu necesita argument referinta (deci poate fi implementata in C) este data
mai jos.

 insert(r,a)
 {
 if r=0 then return ( make_nod(a) )
 else if key(a) < key(data(r)) then
 lchild(r) = insert(lchild(r),a)
 else if key(a) > key(data(r)) then
 rchild(r) = insert(rchild(r),a)
 return (r)
 }

Apelul acestei variante va avea de fiecare data forma:

 rad = insert(rad, a)


Procedura search intoarce pointer la nodul cu cheia de cautare data sau pointerul NULL
daca nu exista nodul respectiv. Laborator de Structuri de Date si Algoritmi – Lucrarea nr. 6

 search(r,k)
 {
 if ( r=0 ) return NULL
 else if k < key(data(r)) then
 return ( search(lchild(r),k) )
 else if k > key(data(r)) then
 return ( search(rchild(r),k) )
 else return (r)
 }

 b) varianta nerecursiva

Trebuie observat ca atit operatia search cit si operatia insert parcurg o ramura a arborelui
(un lant de la radacina spre o frunza). Aceasta parcurgere poate fi efectuata iterativ. Este
vorba de a parcurge o inlantuire, deci se impune o analogie cu parcurgerea listei
inlantuite.

Parcurgerea listei inlantuite Parcurgerea unei ramuri in arbore

p=cap; p=rad;
while(p!=0){ while(p!=0){
 ┌────────────────────┐ ┌───────────────┐
 │ Prelucrare element │ │ Prelucrea nod │
 └────────────────────┘ └───────────────┘
 p = p->link; if(conditie) p=p->stg
 else p=p->drt;
 } }

Procedura de inserare in arborele binar de cautare, realizata nerecursiv, are urmatoarea
forma (presupunem ca r este parametru transmis prin referinta):

 insert(r,a)
 {
 if ( r=0 ) r = make_nod(a)
 else {p = r
 while ( p<>0 )
 {
 p1 = p
 if key(a)<key(data(p)) then p=lchild(p)
 else if key(a)>key(data(p)) then p=rchild(p)
 else return
 }
 if ( key(a)<key(data(p1)) )
 lchild(p1) = make_nod(a)
 else rchild(p1) = make_nod(a)
 }
 }
3. Stergerea unui nod dintr-un arbore binar de cautare 
 In continuare vom scrie functia C++ pentru stergerea unei valori dintr-un arbore binar 
de cautare care contine numere intregi. 
 Pentru stergerea unei valori din arbore este necesara mai intii identificarea nodului 
care contine aceasta valoare. Vom folosi pentru aceasta tehnica prezentata la operatia 
search. Pentru simplitate consideram nodurile etichetate cu numere intregi care vor 
contitui chiar cheile de cautare (key(data(p) = data(p)). 
struct Nod{ 
 int data; 
 Nod* stg, *drt; 
 }; 
void delete(Nod*& rad, int a) 
 if(rad==NULL) 
 printf("Eroare: Valoarea %d nu este in arbore!", a); 
 else if( a<rad->data ) delete(rad->stg,a) 
 else if( a>rad->data ) delete(rad->drt,a) 
 else deleteRoot(rad); 
Am redus sarcina initiala la a scrie functia deleteRoot care sterge radacina unui 
arbore binar de cautare nevid. Pentru aceasta avem urmatoarele cazuri: 
Atunci cind radacina nu are nici un descendent stergerea este o operatie 
imediata. 
 Laborator de Structuri de Date si Algoritmi – Lucrarea nr. 6 
Atunci cind radacina are un sigur descendent nodul sters va fi inlocuit cu 
subarborele descendent. 
Atunci cind radacina are doi descendenti, ea va fi inlocuita cu nodul cu 
valoarea cea mai mare din subarborele sting, acest nod avind intotdeuana cel 
mult un descendent. Nodul cel mai mare dintr-un arbore (subarbore) binar de 
cautare se gaseste pornind din radacina si inaintind cit se poate spre dreapta. 
Urmatoarea functie detaseaza dintr-un arbore binar de cautare nevid nodul cu 
valoarea cea mai mare si intoarce pointer la acest nod. 
 Nod* removeGreatest(Nod*& r) 
 { 
 Nod* p; 
 if( r->drt==0 ) { 
 p = r; 
 r = r->stg; 
 return p; 
 } 
 else return removeGreatest(r->rchild); 
 } 
 Varianta prezentata este recursiva. Se poate scrie usor si o varianta nerecursiva pentru 
aceasta procedura. 
Tinind cont de cazurile posibile prezentate procedura deleteRoot va trata separat cazurile: 
- daca subarborele sting este vid: promoveaza subarborele drept. Cazul in care si 
subarborele drept este vid nu trebuie tratat separat, in acest caz se promoveaza 
arborele vid (rad devine NULL); 
- altfel daca, subarborele drept este vid: promoveaza subarborele sting. 
- altfel (ambii subarbori nu sint vizi): inlocuieste radacina cu cel mai mare nod din 
subarborele sting.
void deleteRoot(Nod*& rad) 
 Nod* p = rad; 
 if( rad->stg==0) rad = rad->drt; 
 else if( rad->drt==0) rad = rad->stg; 
 else { 
 rad = removeGreatest (rad->stg); 
 rad->stg = p->stg; 
 rad->drt = p->drt; 
 } 
 delete p; 
TEMA 1 
1. Se citeste de la intrare un sir de valori numerice intregi, pe o linie, separate de spatii, 
sir care se incheie cu o valoare 0. 
 a) Sa se introduca valorile citite intr-un arbore binar de cautare (exclusiv valoarea 0 
care incheie sirul). 
 b) Sa se afiseze in inordine continutul arborelui. 
 c) Se citeste o valoare pentru care sa se raspunda daca este sau nu continuta in arbore. 
 d) Se citeste o valoare care sa fie stearsa din arbore si apoi sa se afiseze arborele in 
inordine. 
4. Arbori binari de cautare AVL echilibrati 
4.1. Introducere 
Arbori binari echilibrati 
 Un arbore binar echilibrat este definit de proprietatea ca, pentru fiecare nod, diferenta 
dintre adincimea subarborelui sting si cea a subarborelui drept este cel mult 1. 
 Se demonstreaza ca adincimea unui arbore echilibrat cu n noduri interne satisface 
relatia: 
 .1 4404 log ( )2 .0 328 h < ∗ 2
n + − 
Ca urmare, parcurgerea unei ramuri in arborele binar echilibrat se va face in O(log n) 
pasi. 
Arbori binari de cautare echilibrati 
 Operatia de cautare intr-un arbore binar de cautare care are si proprietatea de a fi 
echilibrat este o operatie O(log n). Se pune problema construirii operatiilor INSERT 
si DELETE astfel incit ele sa conserve proprietatea de arbore binar echilibrat dar, in 
acelasi timp, sa fie la rindul lor operatii O(log n). Costul pe care trebuie sa-l platim 
pentru a putea realiza acest lucru este marirea spatiului ocupat de un nod al arborelui prin 
memorarea in fiecare nod a unui "factor de dezechilibru" semnificind diferenta intre 
adincimea subarborelui drept si cel sting. 
 La inserare, arborele trebuie reorganizat modificindu-i-se structura, numai atunci cind 
o inserare dezechilibreaza un nod, care deja este dezechilibrat in acelasi sens. Operatiile 
prin care este realizata echilibrarea sint denumite rotatii si sint descrise mai jos. 
4.2. Mecanisme de conservare a proprietatii de arbore binar echilibrat: 
Rotatii 
In urmatoarele desene am reprezentat: 
- Un nod al arborelui 
- Un subarbore de adincime h 
- Un subarbore de adincime h-1 
Rotatiile se aplica arborilor (subarborilor) care, in urma inserarii, au nodul 
radacina dezechilibrat, dar toti subarborii sint echilibrati. Laborator de Structuri de Date si Algoritmi – Lucrarea nr. 6 
La inserarea unui nod X intr-un arbore, sint 4 cazuri posibile care necesita 
efectuarea unei rotatii: 
Si 
4.2.1. Rotatiile simple 
Rotatie simpla dreapta: 
 Starea initiala: Starea finala: Laborator de Structuri de Date si Algoritmi – Lucrarea nr. 6 
Subarborii T1, T2 si T3 au initial aceeasi adincime h, iar nodul A are factorul de 
dezechilibru -1. Prin inserarea unui nod in subarborele T1 se mareste adincimea acestuia 
si nodul A devine dezechilibrat. Prin operatia numita "rotatie simpla dreapta" se obtine 
un arbore care respecta inegalitatea valabila pentru starea initiala: 
 T1 < B < T2 < A < T3 
Adica: Toate nodurile din subarborele T1 sint etichetate cu valori mai mici decit B, B 
este mai mic decit etichetele tuturor nodurilor din subarborele T2, etc. 
 Arborele rezultat in urma rotatiei este echilibrat si, trebuie remarcat in mod deosebit, 
are aceeasi adincime cu arborele initial (h+2). 
Rotatie simpla stinga: 
 Se obtine din situatia simetrica celei prezentate mai sus: 
4.2.2. Rotatiile duble 
Situatiile rezolvate de rotatiile duble sint: 
 Laborator de Structuri de Date si Algoritmi – Lucrarea nr. 6 
Pentru a le reprezenta este nevoie sa reprezentam detaliat subarborele T2. Se va vedea 
mai tirziu ca acest arbore (T2) are cu siguranta subarborii descendenti de adincimi egale 
(h-1). 
Rotatiile duble au ca efect echilibrarea arborelui indiferent de subarborele (t2s sau t2d) in 
care este inserat nodul X. 
Rotatie dubla dreapta: 
 Stare initiala Starea finala 
Numele de rotatie dubla rezulta din faptul ca situatia finala poate fi atinsa aplicind doua 
rotatii simple: 
 A doua rotatie 
 Stare initiala Prima rotatie (simpla dreapta pt. A) 
 (simpla stinga pt. B) Starea finala Laborator de Structuri de Date si Algoritmi – Lucrarea nr. 6 
Initial subarborii T1 si T3 au adincimea h iar t2s si t2d au adincimea h-1. 
 Valoarea inserata va mari adincimea unuia din subarborii t2s sau t2d. In ambele 
cazuri se aplica mai intii o rotatie simpla spre stinga nodului B si apoi o rotatie simpla 
spre dreapta nodului A. Rezulta un arbore echilibrat indiferent in care din subarborii t2s 
si t2d s-a facut inserarea. Procedeul este corect si atunci cind nodul inserat este nodul C 
si fiecare din subarborii T1, t2s, t2d, si T3 este arbore vid. 
 Din nou trebuie notat faptul ca adincimea arborelui rezultat este egala cu cea a 
arborelui initial. 
TEMA 2 
Analizati urmatorul applet in care se poate vizualiza comportarea unui arbore binar de 
cautare AVL echilibrat : 
http://webpages.ull.es/users/jriera/Docencia/AVL/AVL%20tree%20applet.htm 
Efectuati operatii de inserare si stergere a unui nod din arbore. 
Analizati modul in care se efectueaza aceste operatii atat in cazul arborilor echilibrati cat 
si in cazul celor neechilibrati. 

Arbori de cost minim

de Dron Andrei

vineri, 17 ianuarie 2014

ARBORI

INTRODUCERE
Pentru multe aplicaţii, timpul de acces liniar la informaţia cuprinsă într-o listă este
foarte mare. De asemenea, uneori este necesară folosirea unei descrieri ierarhice pentru
modelarea diferitelor fenomene şi/sau obiecte din natură. Prin descrierea ierarhică se
înţelege descompunerea unei entităţi în subentităţi, fiecare dintre ele putând fi
caracterizate printr-un set de atribute sau însuşiri. De asemenea, utilizând o astfel de
descriere, se realizeazã şi o ierarhizare a părţilor unei entităţi pe unul sau mai multe
niveluri.
Organizarea ierarhică este întâlnită în diverse domenii, ca de exemplu:
organizarea administrativă a unei ţări, planificarea meciurilor în cadrul unui turneu
sportiv , evaluarea unor expresii de calcul ), etc.
În figurile de mai sus sunt date exemple de structuri cu organizare ierarhică.
Structurile cu organizare ierarhică pot fi reprezentate cu ajutorul arborilor.
Dron Andrei