UNIVERSITATEA TITU MAIORESCU

Facultatea de Ştiinţa şi Tehnologia Informaţiei
Lector univ. dr. DANIELA

JOITA

Curs pentru învăţământul la distanţă

BUCUREŞTI – 2009

UNIVERSITATEA TITU MAIORESCU BUCUREŞTI Facultatea Ştiinţa şi Tehnologia Informaţiei Învăţământ la Distanţă

Structuri de date si algoritmi
Acest material este destinat studentilor anului II, invatamant la distanta. Modul de prezentare are în vedere particularităţile învăţământului la distanţă, la care studiul individual este determinant. Pentru orice nelămuriri faţă de acest material vă rugăm să contactaţi tutorele de disciplină care are datoria să vă ajute oferindu-vă toate explicaţiile necesare. Obiective specifice disciplinei Structuri de date si algoritmi sunt: Cunoasterea principalelor structuri de date liniare si neliniare folosite in informatica; Asimilarea metodelor de analiza a eficientei unui algoritm; Cunoasterea principalilor algoritmi de sortare si cautare; Implementarea algorimilor si a structurilor de date invatate in limbajul C. Materialul a fost elaborate astfel incat algoritmi prezentati pot fi implementati in orice limbaj de programare. Pentru a face o alegere, limbajul de programare folosit in aplicatii va fi limbajul C. Este foarte important ca parcurgerea materialului sa se faca in ordinea modulelor incluse (Modulul I – Modulul V). Fiecare modul contine, pe langa prezentarea notiunilor teoretice, teme de laborator dupa fiecare lectie, care faciliteaza o intelegere mai rapida a materialului inclus. Pe langa aceste exemple, prezentarea modulului contine si o serie de probleme propuse repartizata pe module si care testeaza cunoasterea notiunilor teoretice de catre student. Mentionam ca aceste probleme nu sunt ordonate dupa gradul lor de dificultate. Structura modulelor este urmatoarea: Modulul I. Structuri de date liniare Modulul II. Structuri de date neliniare Modulul III. Analiza algoritmilor Modulul IV. Algoritmi de sortare Modulul V. Algoritmi de cautare Vă precizăm de asemenea că, din punct de vedere al verificărilor şi al notării, cu adevărat importantă este capacitatea pe care trebuie să o dobândiţi şi să o probaţi de a rezolva toată tipologia de probleme aplicative aferente materialului teoretic prezentat în continuare. Conceptele si experienta dobandite in acest curs formeaza o baza importanta pentru urmatoarele cursuri de programare si o neintelegere a notiunilor fundamentale poate genera dificultati in asimilarea conceptelor mai complexe ce vor fi introduse in aceste cursuri. Materialul inclus contine, pe langa acest cuvant inainte, continutul fiecarui modul in fisiere separate, cuprinsul si o lista de probleme propuse. In speranta ca organizarea si prezentarea materialului va fi pe placul dumneavoastra, va uram MULT SUCCES! Coordonator disciplină: Lector univ. dr. Daniela Joita

Cuprins Modulul I. Structuri de date liniare
1. Liste liniare
1.1 Alocarea secventiala 1.2 Alocarea inlantuita

2. Stive
2.1 Alocarea secventiala 2.2 Alocarea inlantuita

3. Cozi
3.1 Alocarea secventiala 3.2 Alocarea inlantuita

4. Liste circulare 5. Liste dublu inlantuite

Modulul II. Structuri de date neliniare
6. Grafuri

6.1 Notiuni generale 6.2 Reprezentarea grafurilor

7. Arbori
7.1 Reprezentare 7.2 Traversare 8. Arbori binari 8.1 Notiuni generale 8.2 Reprezentare 8.3 Traversare

Modulul III. Analiza algoritmilor
9. Analiza eficientei algoritmilor

Modulul IV. Algoritmi de sortare
10. 11. 12. Sortare prin numarare Sortare prin inserare Sortare prin interschimbare
12.1 Bublesort 12.2 Quicksort

13. 14.

Sortare prin selectie Mergesort

Modulul V. Algoritmi de cautare
15. 16. 17. Cautare secventiala Cautare binara Arbori binari de cautare.
17.1 Cautare in arbori binari de cautare 17.2 Inserare si stergere arbori binari de cautare

Modulul I. Structuri de date liniare
Capitolul 1. Liste liniare
In viata de fiecare zi construim liste ca o modalitate de a pune lucrurile in ordine: list astudentilor unei grupe, lista numerelor din cartea de telefon, programul TV, lista de cumparaturi. O lista liniara este un set finit de elemente ordonate liniar, adica exista un element considerat primul in lista, un element considerat ultimul si pentru orice alt element din lista exista un element precedent si un element urmator. Principalele operatii cu liste sunt: − accesarea sau modificarea unui element din lista − inserarea unui element in lista − eliminarea unui element din lista Modul in care aceste operatii sunt efectuate depinde de modul in care sunt reprezentate listele. Exista doua feluri de reprezentari: secventiala si inlantuita.

1.1 Alocarea secventiala
In alocarea secventiala o lista se reprezinta ca un sir in care elementele sunt memorate in locatii consecutive de memorie. In C, o astfel de lista este, de fapt, un sir care se defineste, in general: nume_tip nume_sir[nr_elemente]; unde nume_tip este tipul elementelor sirului, nume_sir este numele sirului (listei), iar nr_elemente este o constanta ce reprezinta numarul maxim posibil de elemente ale sirului. In C, se poate face referire la elementele sirului prin intermediul indicelui. Primul element in lista are indice 0 si se noteaza nume_sir[0], ultimul este nume_sir[nr_elemente – 1], iar un element de indice k, 1 ≤ k ≤ nr_elemente - 2 este nume_sir[k] si are ca precedent elementul nume_sir[k - 1] si este urmat de elementul nume_sir[k + 1]. Elementele sirului sunt memorate astfel incat: adresa lui nume_sir[k] = adresa lui nume_sir[0] + k *sizeof (nume_tip) unde sizeof(nume_tip) returneaza numarul de octeti necesari memorarii unei singure variabile de tipul nume_tip. In cele ce urmeaza, presupunem ca avem un sir definit T x[N]; unde N este o constanta suficient de mare, T este un tip de date definit anterior (eventual printr-o definitie de tipul typedef), iar n este numarul de elemente din lista, n ≤ N. x[0] x[1] x[2] x[N] ... ... ... Operatiile cu liste prezentate mai sus, se pot descrie astfel: − accesarea/ modificarea unui element se face prin intermediul indicelui elementului − inserarea unui element se poate face intr-o pozitie data, dupa sau inaintea unui element dat. Prezentam in continuare inserarea unui element numit elem_nou intro pozitie data k, deoarece celelalte se reduc la aceasta.

1

. Se actualizeaza numarul de elemente al sirului. -1 x[i+1] = x[i] endfor endif x[k] = elem_nou n = n +1 − eliminarea elementului de indice k din lista. altfel lista nu poate fi creata sau sa gasim o alta metoda de reprezentare a listei in care elementele sa nu mai fie memorate in locatii consecutive. Daca.1 x[i] = x[i+1] endfor endif n = n –1 Lab 1 Scrieti un program care implementeaza algoritmii de mai sus pentru o lista liniara alocata secvential. x[n-1]. pentru a pastra ordinea listei va trebui sa stim care este primul element al listei. Se muta elementele sirului x[k+1]. cate un bloc de memorie spre stanga. de exemplu. Mai precis. Mai precis. ar trebui sa gasim o modalitate de reorganizare a memoriei. n-2.. . . cate un bloc de memorie spre dreapta. 1. dar nu exista nici un bloc de memorie de marime M. memoria nu este ocupata la rand. continand doua campuri: info (folosit pentru memorarea informatiei corespunzatoare elementului) si link (un pointer la 2 .. desi exista trei blocuri de memorie de marime M/2. al doilea etc. Se salveaza informatia continuta de elementul de indice k pentru cazul in care se doreste prelucrarea ei. incepand cu x[k+1]. iar pentru a sti care este urmatorul element in lista fiecare element va trebui sa contina (sa memoreze) pe langa informatia corespunzatoare lui si un pointer la elementul urmator in lista.. algoritmul se scrie: if n = 0 then UNDERFLOW else elem_sters = x[k] for i = k. k.. Ultimul element in lista va avea drept componenta pointerul NULL. Alocarea secventiala a unei liste se poate face daca exista blocuri de memorie suficient de mari pentru a o memora. Se actualizeaza numarul de elemente al sirului.. algoritmul se scrie: if n = N then OVERFLOW else for i = n-1. vrem sa alocam spatiu pentru o lista cu M elemente. Din acest motiv. fiecare element va fi de tip structura. Pentru aceasta vom folosi un pointer la primul element al listei (numit pointerul listei si notat HEAD). x[n-1]. Elementele nemaifiind memorate in locatii consecutive. Presupunem 0 ≤ k ≤ n-1. incepand cu ultimul.2 Alocarea inlantuita De multe ori. acesti pointeri ajuta la reconstituirea listei. Acesta din urma este cazul alocarii inlantuite. In caz contrar se muta elementele sirului x[k]. In alocarea inlantuita. Algoritm: Daca n = 0 atunci se produce UNDERFLOW adica lista este vida si deci eliminarea unui element din lista nu este posibila.Algoritm: Presupunem 0 ≤ k ≤ n. Se introduce elementul nou in pozitia k. zone de memorie libere alternand cu zone de memorie ocupate. Daca n = N atunci se produce OVERFLOW adica spatiul alocat listei este ocupat in totalitate si ca nici o alta inserare nu este posibila.

gasit = false daca elementul cu valoarea k nu a fost gasit in lista si true in caz contrar si iter de tip pointer la un nod care initial pointeaza la primul nod al listei si va parcurge lista pana cand nodul dorit este gasit sau pana cand se ajunge la ultimul nod al listei. k de tip T. p NULL info nou Observatie: Algoritmul functioneaza chiar daca lista este nula si se poate folosi pentru crearea unei liste prin introducerea pe rand.elementul urmator). elementele unei astfel de liste se mai numesc si noduri. Algoritm: Folosim variabilele gasit de tip boolean. Aloca memorie pentru un nod nou. 3 . in caz contrar. struct nod *link. operatiile cu liste se pot descrie astfel: − accesarea/ modificarea unui element ce contine o valoare data k.. a elementelor listei. HEAD info link info link info NULL . putem defini tipul de date asociat unui nod astfel: struct nod { T info.. }. Acestea fiind date.. unde T este presupus definit anterior (eventual printr-o definitie typedef). if p ≠ NULL then p -> link = HEAD p -> info = info_nou HEAD = p else OVERFLOW endif HEAD . gasit = false iter = HEAD while (not gasit and iter ≠ NULL) if iter -> info = k then gasit = true else iter = iter -> link endif endwhile if gasit then acceseaza nodul pointat de iter else afiseaza mesajul "Nu exista nici un nod cu informatia data." endif − inserarea unui nou nod o la inceputul listei: Algoritm: Folosim variabilele info_nou ce contine valoarea informatiei nodului ce trebuie introdus in lista si p pointer la un nod. In C. Returneaza p. un pointer la noul nod. unul cate unul. typedef struct nod NOD.. Datorita reprezentarii structurate.

. inainte p .. sterge este pointer la nodul care trebuie eliminat din lista si iter care initial pointeaza la primul nod al listei si va parcurge lista pana cand acesta va pointa la nodul dinaintea nodului de sters din lista. iter = HEAD while (iter ≠ NULL and iter -> link ≠ sterge) 4 . if p ≠ NULL then p -> link = inainte ->link inainte -> link =p p -> info = info_nou else OVERFLOW endif . Returneaza p. Aloca memorie pentru un nod nou.. info nou − eliminarea unui nod dat din lista: Algoritm: Folosim variabilele sterge si iter de tip pointer.. iter p NULL info nou NULL o dupa un nod dat: Algoritm: Folosim variabilele info_nou ce contine valoarea informatiei nodului ce trebuie introdus in lista si p pointer la un nod si inainte pointer la nodul dupa care se doreste introducerea noului nod. if p ≠ NULL then p -> link = NULL p -> info = info_nou iter = HEAD while (iter ≠ NULL and iter -> link ≠ NULL) iter = iter -> link endwhile if iter = NULL then HEAD = p else iter ->link =p endif else OVERFLOW endif HEAD ..o la sfarsitul listei: Algoritm: Folosim variabilele info_nou ce contine valoarea informatiei nodului ce trebuie introdus in lista. Returneaza p. un pointer la noul nod. un pointer la noul nod.. Aloca memorie pentru un nod nou.. p pointer la un nod si iter care initial pointeaza la primul nod al listei si va parcurge lista pana cand acesta va pointa la ultimul nod din lista.

Lista este vida.." else recupereaza informatia nodului de sters sterge->info iter ->link = sterge -> link endif .. 5 .. .. iter sterge Lab 2 Scrieti un program care implementeaza algoritmii de mai sus pentru o lista liniara alocata inlantuit. UNDERFLOW.iter = iter -> link endwhile if iter = NULL then tipareste mesajul "Eroare.

inserare stergere .. T este un tip de date definit anterior (eventual printr-o definitie de tipul typedef). iar n este numarul de elemente din stiva. iar elementul din varful stivei este considerat elementul x[n-1]. Structuri de date liniare Capitolul 2. iar stergerea unui element a dintr-o stiva S: S ⇒ a. eventual eliminata din stiva este cea din varful stivei.. Singurul element care poate fi accesat la un moment dat este cel din varful stivei.Modulul I.. Cele doua operatii se mai numesc si push respectiv pop. x[0] x[1] x[2] x[n -1] .. numit varful stivei. unde N este o constanta suficient de mare. n ≤ N..1 Alocarea secventiala In alocarea secventiala. Se poate face o analogie intre o stiva folosita in programare si o stiva de carti. Stive Stiva este o lista liniara in care inserarile si stergerile din lista se pot face numai pe la un capat al listei.. Stivele se mai numesc si liste push-down sau LIFO (last in/first out) deoarece primul element care este extras din stiva este ultimul introdus in stiva.. . Vom nota inserarea unui element a intr-o stiva S: a ⇒ S. 2. atunci operatia de inserare elem_nou ⇒ S se poate descrie astfel: if n = N then OVERFLOW else n = n + 1 x[n-1] = elem_nou endif iar operatia de stergere S ⇒ elem_sters se poate descrie astfel: if n = 0 then UNDERFLOW else elem_sters = x[n-1] n=n–1 endif 1 . Adaugarea unei carti se poate face numai in varful stivei de carti.. presupunand ca stiva este definita T x[N]. peste cartile existente si singura carte ce poate fi accesata. .

Returneaza p. NOD *top. if p ≠ NULL then p -> link = top p -> info = info_nou top = p else OVERFLOW endif top info p info_nou ..... NULL Lab 3 Scrieti un program care implementeaza algoritmii de mai sus pentru o stiva. typedef struct nod NOD..2.. Cu aceste notatii. struct nod *link.. folosim aceeasi structura ca si in cazul listei liniare struct nod { T info.2 Alocarea inlantuita In alocarea inlantuita........ unde T este presupus definit anterior (eventual printr-o definitie typedef) si notam cu top pointerul stivei (adica pointerul care pointeaza la elementul din varful stivei). 2 . un pointer la noul nod.. endif Aloca memorie pentru un nod nou. operatiile cu stive se pot descrie astfel: − stergerea/accesarea unui nod: − inserarea unui nod nou: Algoritm: Folosim variabilele info_nou ce Algoritm: if top = NULL then UNDERFLOW contine valoarea informatiei nodului ce else elem_sters = top -> info trebuie introdus in lista si p pointer la un top = top -> link nod.. top NULL .. }..

3 .

1 then OVERFLOW else if R > 0 then x[R – 1] = elem_nou R = R –1 else for i = F. cu indicii 0 ≤ R ≤ F ≤ N – 1.1 Alocarea secventiala In alocarea secventiala. . x[F].....Modulul I. Vom nota inserarea unui element a intr-o coada C: a ⇒ C... T este un tip de date definit anterior (eventual printr-o definitie de tipul typedef). unde N este o constanta suficient de mare. x[R+1].. atunci operatia de inserare elem_nou ⇒ C se poate descrie astfel: if R = 0 and F = N . Se poate face o analogie intre o coada folosita in programare si.. presupunand ca avem o coada definita T x[N]. 3. .. iar inserarea se face la celalalt capat al cozii. R. iar stergerea unui element a dintr-o coada C: C ⇒ a. de exemplu. Pentru tiparirea unui nou fisier va trebui sa asteptam pana cand toate fisierele sunt tiparite in ordinea in care comenzile de tiparire au fost efectuate. numit front. rear inserare Cozile se mai numesc si liste FIFO (first in/first out) deoarece primul element care este extras din coada este primul introdus. -1 x[i+1] = x[i] endfor x[0] = elem_nou F = F +1 endif endif iar operatia de stergere C ⇒ elem_sters se poate descrie astfel: if R > F then UNDERFLOW 1 . Cozi O coada este o lista liniara in care stergerea si accesarea unui element se pot face numai pe la un capat al cozii. stergere front .. . Structuri de date liniare Capitolul 3. x[R] x[R+1] x[F] .. numit rear. o coada pentru tiparirea mai multor fisiere text. iar elementele cozii sunt in ordine x[R].

}... pointerul la primul nod al cozii.. typedef struct nod NOD..... si respectiv rear... NOD *front.. if p ≠ NULL then p -> link = NULL p -> info = info_nou rear -> link = p rear = p else OVERFLOW endif front info front . operatiile cu cozi se pot descrie astfel: − inserarea unui nod nou: − stergerea/accesarea unui nod: Algoritm: Folosim variabilele info_nou Algoritm: if front = NULL then UNDERFLOW ce contine valoarea informatiei nodului else elem_sters = front -> info ce trebuie introdus in lista si p pointer la front = front -> link un nod.. si respectiv la ultimul nod. endif Aloca memorie pentru un nod nou. . folosim aceeasi structura ca si in cazul listei liniare struct nod { T info. rear rear NULL p info_nou NULL Scrieti un program care implementeaza algoritmii de mai sus pentru o coada. unde T este presupus definit anterior (eventual printr-o definitie typedef) si notam cu front. struct nod *link..2 Alocarea inlantuita In alocarea inlantuita. rear. 2 Lab 4 . un pointer la noul nod........ Returneaza p... Cu aceste notatii..else elem_sters = x[F] F = F -1 endif 3.

3 .

un pointer la noul nod.Modulul I. if p ≠ NULL then p -> link = HEAD p -> info = info_nou iter = HEAD while (iter -> link != HEAD) iter = iter -> link endwhile iter -> link =p HEAD = p else OVERFLOW endif HEAD ... HEAD info link info link . Aloca memorie pentru un nod nou. p info nou o dupa un nod dat: se face la fel ca in cazul listei liniare. elem_sters = HEAD -> info iter = HEAD while (iter -> link != HEAD) iter = iter -> link endwhile iter -> link = HEAD -> link . se face la fel ca in cazul listei liniare. info Operatiile cu o lista circulara se descriu astfel: − accesarea/ modificarea unui element ce contine o valoare data k. p pointer la un nod si iter care initial pointeaza la primul nod al listei si va parcurge lista pana cand acesta va pointa la ultimul nod din lista. Liste circulare O lista circulara este o lista in reprezentare inlantuita care are proprietatea ca ultimul nod pointeaza la primul nod al listei in loc sa aiba drept componenta pointerul NULL. Structuri de date liniare Capitolul 4.. Returneaza p. este acelasi lucru): Algoritm: Folosim variabilele info_nou ce contine valoarea informatiei nodului ce trebuie introdus in lista. k de tip T. − eliminarea unui nod dat din lista: o eliminarea primului nod Algoritm: Folosim variabila iter care initial pointeaza la primul nod al listei si va parcurge lista pana cand acesta va pointa la ultimul nod din lista.. algoritm descris in capitolul 1. − inserarea unui nou nod o la inceputul listei (sau la sfarsitul listei. algoritm descris in capitolul 1.

.. iter = HEAD while (iter ≠ NULL and iter -> link ≠ HEAD and (iter -> link) ->link ≠ HEAD) iter = iter -> link endwhile if iter = NULL then UNDERFLOW else if iter -> link = HEAD then elem_sters = iter ->info else elem_sters = (iter ..HEAD = HEAD -> link HEAD info link info link .. iter info link info o eliminarea altui nod din lista se face la fel ca in cazul listei liniare.. Lab 5 .>link) ->info iter -> link = HEAD endif endif HEAD info link . info o eliminarea ultimului nod: Algoritm: Folosim variabila iter care initial pointeaza la primul nod al listei si va parcurge lista pana cand acesta va pointa la penultimul nod din lista. algoritm descris in capitolul 1. Scrieti un program care implementeaza algoritmii de mai sus.

FIRST NULL llink info rlink . orice nod va avea forma: llink info rlink Orice lista dublu inlantuita va avea doi pointeri FIRST. O astfel de reprezentare a unei liste se numeste lista dublu inlantuita.. pentru fiecare nod al listei nu numai un pointer la elementul urmator ci si unul la nodul precedent. se fac urmatoarele setari FIRST->llink=NULL si LAST->rlink= NULL.. parcurgandu-se lista fie de la inceput la sfarsit. Operatiile cu liste dublu inlantuite se pot descrie astfel: − accesarea/ modificarea unui element ce contine o valoare data se face ca si in cazul listei liniare simplu inlantuite. Aloca memorie pentru un nod nou. care pointeaza la primul nod si LAST care pointeaza la ultimul nod.. Observati ca pentru orice pointer p la un nod avem: (p -> rlink) -> llink = p si (p -> llink) -> rlink = p.Modulul I. un pointer la noul nod. LAST llink info rlink NULL NULL p llink info rlink 1 . fie de la sfarsit la inceput. − inserarea unui nou nod o la inceputul listei: Algoritm: Folosim variabilele info_nou ce contine valoarea informatiei nodului ce trebuie introdus in lista si p pointer la un nod. LAST llink info rlink NULL Deasemenea. Liste dublu inlantuite Pentru folosirea mai usoara a listelor liniare putem avea. Returneaza p.. Astfel. Structuri de date liniare Capitolul 5. if p ≠ NULL then p -> llink = NULL p -> rlink = FIRST p -> info = info_nou FIRST -> llink = p FIRST = p else OVERFLOW endif FIRST NULL llink info rlink .

p − eliminarea unui nod o eliminarea primului nod: Algoritm: elem_sters = FIRST -> info 2 . un pointer la noul nod.o la sfarsitul listei: Algoritm: Folosim variabilele info_nou ce contine valoarea informatiei nodului ce trebuie introdus in lista. llink info rlink rlink llink info rlink . Returneaza p. if p ≠ NULL then p -> rlink = NULL p -> info = info_nou p -> llink = LAST LAST -> rlink =p LAST=p else OVERFLOW endif FIRST NULL llink info rlink . LAST llink info rlink NULL llink info p rlink NULL o dupa un nod dat: Algoritm: Folosim variabilele info_nou ce contine valoarea informatiei nodului ce trebuie introdus in lista si p pointer la un nod si inainte pointer la nodul dupa care se doreste introducerea noului nod... if p ≠ NULL then p -> llink = inainte p -> rlink = inainte -> rlink inainte -> rlink = p (p -> rlink ) -> llink = p p -> info = info_nou else OVERFLOW endif inainte llink info .. Returneaza p... un pointer la noul nod. p pointer la un nod Aloca memorie pentru un nod nou.. Aloca memorie pentru un nod nou.

elem_sters = sterge -> info inainte = sterge -> llink dupa = sterge -> rlink dupa ->llink = inainte inainte ->rlink = dupa rlink llink info rlink NULL inainte . NULL o eliminarea ultimului nod: Algoritm: elem_sters = LAST -> info LAST = LAST -> llink LAST ->rlink = NULL LAST llink info ...FIRST = FIRST -> rlink FIRST ->llink = NULL FIRST NULL llink info rlink llink info rlink .... pointer la nodul dinainte si dupa.. Lab 6 Scrieti un program care implementeaza algoritmii de mai sus. NULL − eliminarea unui nod dat din lista: Algoritm: Folosim variabilele sterge. un pointer la nodul care trebuie eliminat din lista. llink info rlink sterge llink info rlink dupa llink info rlink .. 3 .. pointer la nodul dupa nodul ce trebuie sters. inainte.

Grafuri 6. d}. Doua varfuri ale unui graf neorientat intre care exista o muchie se numesc adiacente. urmatorul graf orientat G2 = (V2. Multimea V se numeste multimea varfurilor grafului G. De exemplu.1 Notiuni generale Definitie: Se numeste graf neorientat o structura G = (V. c). b. notat d+(x). b). Structuri de date neliniare Capitolul 6. c]. iar E o multime de perechi neordonate de elemente din V. d]} se reprezinta: Definitie: Se numeste graf orientat o structura G = (V. iar E2 = {(a. De exemplu. Multimea V se numeste multimea varfurilor grafului G. iar E multimea arcelor. iar arcele prin sageti de la primul varf la cel de al doilea. E1) unde V1 = {a. notat d-(x). In reprezentare grafica. [b. (b. b. Gradul unui varf x al unui graf neorientat. (c. varfurile se reprezinta prin cercuri. a)} se reprezinta: Observati ca in cazul grafurilor orientate sunt permise arce cu varful de inceput acelasi cu cel de sfarsit. c). Un varf de grad zero se numeste izolat. c]. iar E o multime de perechi ordonate de elemente din V.Modulul II. Pentru grafuri orientate se definesc gradul de intrare al unui varf. (a.b ∈V. b sunt doua varfuri ale unui graf orientat astfel incat exista un arc de la a la b atunci spunem ca b este adiacent varfului a. b]. In reprezentare grafica. E) in care V este o multime finita. iar E1 = {[a. Mai exact E ⊆ V×V. iar muchiile prin linii ce unesc varfurile. iar E multimea muchiilor. b} | a. Mai exact E ⊆ {{a. urmatorul graf neorientat G1 = (V1. iar b extremitatea finala. E) in care V este o multime finita. a ≠ b}. Notam muchiile sub forma [a. este dat de numarul de varfuri adiacente cu el. se 1 . Daca a. ca fiind numarul de arcuri care au ca extremitate finala varful respectiv iar gradul de iesire. c. c. varfurile se reprezinta prin cercuri. Daca (a. b) ∈ E atunci a se numeste extremitatea initiala a arcului. d}. [a. E2) unde V2 = {a. b ∈V. notat d(x). unde a.

. c) este un drum de la a la c de lungime 2 in G2 − (a. Un drum intr-un graf orientat (x. .. Graful G1 x = varf a b c d d(x) = grad 2 1 2 1 x = varf a b c d Graful G2 d-(x) = grad intrare 1 1 2 0 d+(x)= grad iesire 2 1 1 0 Dat un graf G = (V. x1.. astfel incat: [x. ... y) sunt arce (daca G este orientat).b) de lungime 2... Pentru exemplele de mai sus. . y] daca G este neorientat si (x. . E) pentru care fiecarei muchii i se asociaza o pondere data de obicei de o functie w: E →R. x1. c. c. .. x2. 6. b) este un drum elementar de la a la b de lungime 2 in G2 − nu exista nici un drum de la d la orice alt nod in G2 − G1 este aciclic − G2 are un singur ciclu: (b. c) este un drum de la a la c de lungime 3 in G2 − (a.. (x1. x1). Un drum intr-un graf neorientat [x.. x2. a. x2.. y) daca G este orientat.. Un graf neorientat se numeste conex daca intre orice doua varfuri ale sale exista un drum... drumul contine cel putin un arc si toate arcele pe care le contine sunt distincte se numeste circuit. y] pentru care x = y. . b. a. y] sunt muchii (daca G este neorientat) sau (x. Componentele conexe ale unui graf sunt clasele de echivalenta ale varfurilor aflate in relatia "exista drum intre"..c.. dar are 2 componente conexe. orientate sau neorientate se poate face in doua feluri: 1) Matricea de adiacenta 2 . E) daca V' = V si E' ⊆ E. Se numeste graf ponderat (sau cu ponderi) un graf G = (V. xp .. xp . E). x2.. Exemple: − [d. Un graf G' = (V'. De exemplu. drumul contine cel putin o muchie si toate muchiile sunt distincte se numeste ciclu. x1. E) daca V'⊆ V si E' ⊆ E.. se numeste drum de la varful x la un varf y. b] este un drum elementar de la d la b de lungime 3 in G1 − (a. o succesiune de varfuri.2 Reprezentarea grafurilor Reprezentarea grafurilor.. x1].. y) pentru care x = y.. Un graf fara cicli se numeste aciclic. [xp .. [x1. x2). Un graf neorientat se numeste complet daca exista muchie intre oricare doua varfuri. c. xp sunt distincte si x1. .. Un graf G' = (V'. x1. xp .defineste ca numarul de arcuri ce au ca extremitate initiala varful respectiv. E') este subgraf al grafului G = (V. y sunt de asemenea distincte. G1 este conex in timp ce G2 nu este conex. xp . E') este graf partial al grafului G = (V. x2]. x2. . Un drum se numeste elementar daca x. pe care o notam [x. x1. xp . Lungimea unui drum este data de numarul muchiilor (arcelor) drumului. (xp . x2.

. n astfel incat Adj[i] contine toate varfurile j pentru care (i. b↔ 2. b↔ 2. de multe ori aceasta matrice este rara daca ca se foloseste memorie Observati ca matricea de adiacenta a unui graf neorientat este simetrica. In aceasta reprezentare. 2. .Fie G = (V.) Matricea de adiacenta a lui G1 Matricea de adiacenta a lui G2 1 2 3 4 1 0 0 1 1 2 0 0 1 0 3 1 1 0 0 4 1 0 0 0 1 2 3 4 1 1 0 0 0 2 0 0 1 0 3 1 1 0 0 4 0 0 0 0 Folosirea acestui mod de reprezentare a unui graf prezinta avantaje si dezavantaje. 1 ≤ i. E) un graf dat si n = numarul de varfuri pe care le vom nota 1. . Matricea de adiacenta este o matrice A= (aij).. j ≤ n definita astfel: aij = 1 daca (i. Exemple: Listele de adiacenta ale celor doua grafuri de mai sus sunt: (Pentru ambele grafuri vom nota varfurile: a↔ 1. numita lista de adiacenta. De obicei. c ↔3 si d↔ 4. c ↔3 si d↔ 4. De asemenea... E) avem un sir Adj cu n elemente unde n = numarul de varfuri pe care le vom nota 1. n. j) ∈ E. varfurile in fiecare lista de adiacenta sunt sortate intr-o anumita ordine... pentru un graf dat G = (V. dar acest lucru nu este obligatoriu. j) ∈ E si 0 in caz contrar Exemple: Matricile de adiacenta ale grafurilor de mai sus sunt: (Pentru ambele grafuri vom nota varfurile: a↔ 1. 2) Liste de adiacenta Pentru fiecare varf asociem lista varfurilor adiacente cu varful dat. in special in cazul in care numarul de varfuri este mare. 2. ) 1 2 3 4 3 3 1 1 4 NULL 2 NULL NULL NULL 1 2 3 4 1 3 2 NULL 3 NULL NULL NULL 3 . Avantajele Dezavantajele ar fi in primul rand folosirea unui spatiu mare de memorie.

Scrieti un program care adauga si/ sau sterge o muchie dintr-un graf neorientat. Scrieti un program care pentru un graf neorientat determină dacă graful este conex. 4 . 2.Lab 7 1.

Corolar: Un arbore cu n varfuri are n . v. G este fara cicluri maximal (Intre orice doua varfuri distincte exista exact un singur drum elementar).1 muchii. similare arborilor genealogici. G este conex si are n . Exemple: Urmatoarele grafuri sunt arbori: Arbore 1 Arbore 2 Prezentam in continuare teorema de caracterizare a arborilor: Teorema: Daca G este un graf neorientat cu n = numar de varfuri. G nu are cicluri si are n . Deci putem spune ca un arbore este o multime de noduri legate intre ele prin muchii ce indica relatiile dintre noduri. G este minimal conex (G este conex dar daca este eliminata orice muchie a grafului graful obtinut nu mai este conex). iii. Editura Universitatii din Bucuresti. Pentru demostratia acestei teoreme puteti consulta Ioan Tomescu.1 muchii. In informatica arborii sunt vizualizati cu radacina in sus si frunzele in jos. in teoria grafurilor. Pe nivelul 0 se afla un singur nod. n ≥ 3 atunci urmatoarele conditii sunt echivalente: i. (In teoria grafurilor acest tip de arbore se numeste arbore cu radacina). Nodurile sunt arajate pe nivele. similara cu un arbore din natura sau cu un arbore genealogic. relatii de tip tata-fiu. Acesta este tipul de arbore folosit in algoritmii computationali si in continuare vom folosi aceasta definitie a notiunii de arbore. radacina. Un tip special de arbore il constituie un arbore. in care se pune in evidenta un nod. Arbori 7. Structuri de date neliniare Capitolul 7. numit radacina. Nodurile fiecarui nivel al aborelui sunt fii nodurilor nivelului precedent. iv.1 Notiuni generale Definitie: Un graf neorientat conex fara cicluri se numeste arbore. o structura arborescenta. 1997. Data Structures. G este arbore. ii. in literatura de specialitate. Definitia de mai sus a notiunii de arbore este cea folosita.Modulul II. Un nod care are fii se 1 .1 muchii.

Daca orice nod al unui arbore nu are mai mult de n fii atunci arborele se numeste arbore nar. De asemenea. 1 . in figura de mai sus. Se numeste inaltime a unui arbore lungimea celui mai lung drum de la radacina la un nod terminal din arbore. reprezentarea arborelui pe nivele este: iar nodul 2 este tatal nodurilor 6. iar 8 este fiul lui 7. 4 si 8 sunt urmasii lui 2. Nodurile 5. nodurile 5. De exemplu. 4 este fiul lui 3. Scrieti un program care gaseste drumul de la radacina la un nod dat intr-un arbore dat. 3 si 7 sunt urmasii lui 2. iar nodul 2 este stramosul tuturor nodurilor (mai putin el insusi). 8.numeste tata. 3. 1 . ramuri. 2 fiind radacina raborelui. 5 este fiul lui 6. si 1 nu au nici un fiu. In general. 2 adica radacina este singurul nod care nu are tata. iar muchiile dintre noduri. Nodurile 6. 3 si 7 sunt frati. daca alegem 2 ca fiind radacina. in cazul aborelui 1. Observati ca intre orice nod si radacina exista exact un singur drum. Despre acest tip de arbori vom vorbi in capitolul urmator. Fii cu acelasi tata se numesc frati. Lab 8 2 . un nod al unui arbore poate avea un numar arbitrar de fii. 4. Nodurile care nu au fii se mai numesc frunze sau noduri terminale. si 7. Pentru arborele de mai sus inaltimea este 2. 1. Un arbore in care orice nod nu are mai mult de 2 fii se numeste arbore binar. Nodurile 6.

cel care are drept radacina fiul stang si subarborele drept. arborii binari se pot reprezenta in doua moduri. unde i este indicele asociat 1 . In calculator. radacina 10. subarborele stang. INFO[i].Modulul II. Un arbore binar pentru care orice nod neterminal are exact doi fii se numeste arbore plin ("full"). cel care are ca radacina fiul drept. Nota: Un arbore binar poate fi si vid (adica fara nici un nod). contin pe langa informatia corespunzatoare si informatii despre cei doi fii stang si drept. nodul 21 are subarborele stang format din nodul 15 si subarborele drept format din nodurile 23 si 28. 8. ST[i] si DR[i]. iar fiu drept nodul 21.2 Reprezentare De obicei. nodurile unui arbore. Reprezentarea secventiala Pentru fiecare nod al arborelui se precizeaza informatia si descendentii directi ca elemente a trei vector diferiti. are drept fiu stang nodul 4. Arbori binari Arborii binari sunt cele mai importante structuri de date neliniare folosite in informatica. Structuri de date neliniare Capitolul 8. arborele de mai jos este un arbore binar. Orice aubarbore al unui arbore binar este el insusi arbore binar. De exemplu. 8. Radacina unui arbore binar are doi subarbori. in particular binar.1 Notiuni generale Un arbore binar este un arbore in care orice nod are cel mult doi descendenti facandu-se distincatie clara intre descendentul drept si descendentul stang.

drept un pointer la radacina arborelui. sau. Daca unul din subarbori este vid. 0. 28). typedef struct nodarbore NODARB. }. Cei trei vectori au dimensiunea egala cu numarul de noduri din arbore.unui nod. 1. 15. unde T este presupus definit anterior (eventual printr-o definitie typedef).0. apoi subarborele stang urmat de subarborele drept o in inordine (simetrica): intai vizitam subarborele stang. Pentru arborele de mai sus. 0). 0. apoi radacina arborelui si apoi subarborele drept o in postordine: intai vizitam subarborele stang si subarborele drept si ultima data radacina arborelui. iar drept este pointer la subarborele drept al nodului. examinarea tuturor nodurilor unui arbore se numeste traversare si se poate face: o in preordine: intai vizitam radacina arborelui. Pentru identificarea radacinii arborelui vom defini NODARB rad. Reprezentarea inlantuita Pentru fiecare nod al arborelui se precizeaza informatia si descendentii directi ca elemente ale unei structuri definita astfel: struct nodarbore { T info. ST=(1. 5. 6. struct nodarbore *drept. pentru arborele de mai sus. 8. 0. 23. Pentru arbori aceasta accesare. 4. mai exact. struct nodarbore *stang. 2 . 21. atunci pointerul la acel subarbore este NULL. 7. 4. DR = (3. de la stanga la dreapta. stang este pointer la subarborele stang al nodului. 0. obtinem urmatorii vectori. De exemplu. cu conventia ca radacina este nodul 1: INFO= (10. 0.3 Traversare De multe ori dorim sa accesam ("vizitam") nodurile unei structuri (lista sau arbore). reprezentarea inlantuita este: 8. 0. . daca numerotam nodurile incepand cu nivelul 0. 0). 9. examinare a unui nod.

23. 1. 21. Scrieti un program care calculeaza numarul de noduri intr-un arbore binar dat. 15. 28 o inordine (simetrica): 1. Algoritmi de traversare a unui arbore binar (recursivi): preordine (rad) /* traversare in preordine a arborelui cu pointerul la radacina rad */ if rad ≠ NULL then viziteaza nodul pointat de rad call preordine (rad -> stang) call preordine (rad -> drept) endif inordine (rad) /* traversare in inordine a arborelui cu pointerul la radacina rad */ if rad ≠ NULL then call inordine (rad -> stang) viziteaza nodul pointat de rad call inordine (rad -> drept) endif postordine (rad) /* traversare in preordine a arborelui cu pointerul la radacina rad */ if rad ≠ NULL then call postordine (rad -> stang) call postordine (rad -> drept) viziteaza nodul pointat de rad endif Lab 9 1. 9. 23. 3 . 2. Scrieti un program care calculeaza inaltimea unui arbore binar dat. 3. 4.Actiunea explicita de vizitare a unui nod depinde de scopul traversarii (de exemplu. Pentru arborele de mai sus. 4. 15. 4. 10. 28. 9. 23. in cele trei moduri si afiseaza informatia continuta in fiecare nod. 21. gasirea unei valori date in arbore). 9. de exemplu. Scrieti un program care traverseaza un arbore binar dat. 21. aflarea numarului de elemente ale arborelui. 28 o postordine: 1. traversarile sunt: o preordine: 10. 15.

numarul de comparatii este N (cele de tipul i ≤ N) + (N –1) (cele de tipul max < x[i]).. i =N+1). i=3. Cand se face analiza unui algoritm trebuie sa se ia in considerare toate clasele de valori de intrare posibile.. N if max < x[i] then max = x[i] endif endfor write max Daca lista de intrare este in ordine descrescatoare atunci numarul de instructiuni de atribuire este 1 (cea dinaintea instructiunii for) + N (cele de tipul i=2. Observati ca numarul de comparatii este acelasi pentru orice tip de lista si ca cele doua cazuri difera prin numarul de instructiuni de atribuire de tipul max = x[i]. i=3. Daca lista de intrare este in ordine strict crescatoare atunci numarul de instructiuni de atribuire este 1 (cea dinaintea instructiunii for) + N (cele de tipul i=2..Modulul III. Analiza algoritmilor se face independent de calculatorul pe care va fi implementat sau de limbajul in care va fi scris. discutand despre necesarul de memorie numai atunci cand acest lucru devine important. dar nu acesta nu constituie o modalitate de masurare a eficientei algorimului deoarece un algoritm nu este "mai bun" decat altul doar daca il vom rula pe un calculator mai rapid sau este "mai incet" daca il rulam pe un calculator mai putin performant.. Pentru algoritmul de mai sus acestea sunt: 1. valori de intrare pentru care elementul maxim este in doua pozitie . ci in numarul de operatii pe care le efectueaza. Vom determina. .. Analiza algoritmilor ne permite alegerea celui mai bun algoritm pentru o problema data. pentru un algoritm dat care rezolva aceasta problema sau numarul de comparatii necesar sortarii unei liste de N elemente. Numarul de operatii este strans legat de timpul efectiv de executie (in secunde) a algoritmului. putem folosi urmatorul algoritm: max = x[1] for i = 2. Acesta nu se masoara in secunde. Cand analizam un algoritm intai trebuie sa ne asiguram ca algoritmul duce la rezolvarea problemei si apoi sa vedem cat de eficient o face.. i =N+1) + N – 1 (cele de tipul max = x[i]) . Analiza algoritmilor Capitolul 9. De exemplu. Analiza eficientei algoritmilor Pentru rezolvarea unei probleme exista de obicei mai multi algoritmi. numarul de operatii efectuate pentru a inmulti doua matrici de marimi N ×N. valori de intrare pentru care elementul maxim este in prima pozitie 2. Sigur ca eficienta unui algoritm depinde si de spatiul de memorie necesar rularii algoritmului. numarul de comparatii este N (cele de tipul i ≤ N) + (N –1) (cele de tipul max < x[i]). In cele ce urmeaza insa ne vom concentra in evaluarea numarului de operatii efectuate (si deci a timpului de executie) de catre un algoritm. daca se considera problema determinarii celui mai mare element dintr-o lista x de N elemente. In schimb. 1 .. presupune estimarea numarului de operatii efectuate. Analiza unui algoritm presupune determinarea timpului necesar de rulare al algoritmului. Un rol important in evaluarea eficientei unui algoritm il au valorile de intrare pentru care se aplica algoritmul.. . de exemplu.

. iar ultima clasa constituie cazul cel mai rau. adica timpul de executie in cazul cel mai bun si timpul maxim. orice algoritm prezinta un necesar de timp si de memorie ce formeaza asa numita complexitatea algoritmului. Sigur ca nu vom putea calcula chiar timpul de executie a algoritmului ci vom determina o functie care depinde de marimea problemei de rezolvat si care este direct proportionala cu timpul de executie. Comparand functiile de crestere a doi algoritmi putem determina care dintre ei este mai rapid si deci eficient. Algoritm 1 suma = 0 for i = 1. cazul in care se efectueaza cele mai putine operatii. acest lucru este mai greu si uneori ne vom limita la estimarea timpului maxim al unui algoritm.. adica timpul de executie in cazul cel mai rau. + n. Observati. Procesul de masurare a complexitatii unui algoritm se numeste analiza algoritmului. Determinam intai numarul de operatii efectuate de fiecare algoritm. timpii de executie ai celor N cazuri posibile. Ne propunem sa facem analiza fiecarui algoritm si sa il determinam pe cel mai eficient. sunt urmatorii: 3N. numarul de operatii in acest caz fiind: (N+1+N– 1=2N) atribuiri + (2N-1) comparatii. Daca n creste suma are mai multi termeni si deci sunt mai multe operatii ce trebuie efectuate. deci exact N clase de valori posibile.Vrem sa determinam functiile de crestere ale celor trei algoritmi. 3N +1. vom putea estima timpul minim. iar daca este in ordine strict crescatoare atunci este face parte din ultima clasa. proportionali cu numarul operatiilor efectuate. sau mai exact exista o singura clasa de valori intrare. i suma = suma + 1 endfor endfor Algoritm 3 suma = n * (n .. Aceasta functie se numeste rata de crestere a algoritmului.N. Prezentam trei algoritmi diferiti pentru rezolvarea acestei probleme. nu exista un "cel mai bun caz" sau "cel mai rau caz" pentru ca dat un n algoritmi efectueaza acelasi numar de operatii. n suma = suma + i endfor Algoritm 2 suma = 0 for i = 1. 2 . Din pacate. Exemplu: Sa consideram urmatoarea problema: Dat n > 0 intreg sa se calculeze suma 1 + 2 + . n for j = 1.. In cele ce urmeaza ne vom concentra asupra complexitatii timpului de executie al unui algoritm. Pentru algoritmul de mai sus. Asa cum am discutat mai sus. Observati ca pentru toti algoritmi. de asemenea ca algoritmul determina primul maxim in cazul in care exista doua sau mai multe elemente cu aceeasi valoare maxima. cel mai rau caz este cazul in care se efectueaza cele mai multe operatii. valori de intrare pentru care elementul maxim este in a N-a pozitie. Aceasta functie examineaza modul de crestere al timpului de executie in cazul cresterii marimei problemei rezolvate de catre algoritm. Cele doua cazuri extreme apar foarte rar si o analiza completa presupune determinarea timpului mediu de executie definit ca media aritmetica a timpilor de executie corespunzatoare tuturor cazurilor posibile. timpul mediu este dat de 1 N ∑ (3N + i) = (3N ( N − 1) + N ( N − 1) / 2) = i =1 1 N N −1 7 2 ( N − 1) . Numim cel mai bun caz. Pentru algoritmul de mai sus prima clasa de valori de intrare constituie cazul cel mai bun. numarul de operatii in acest caz fiind: (N+1) atribuiri + (2N-1) comparatii.1) / 2 Marimea problemei este data de n.. Pentru un algoritm dat. . Observati ca daca lista de intrare este in ordine descrescatoare atunci ea face parte din prima clasa de valori de intrare. 4N –1 si deci.

∀ n≥ N. 3. sau ca algoritmul 2 este de ordin cel mult n2. n! si altele. De obicei. pentru valori mari ale lui n. 4n+3 se comporta ca n. Observatie importanta: In general. n log n n n log n n2 n3 2n n! 2 3 3 10 33 10 3 10 10 10 105 102 7 102 664 104 106 1030 1094 3 3 6 9 301 10 10 10 9966 10 10 10 101435 104 13 104 132877 108 1012 103010 1019335 5 5 10 15 30103 10 17 10 1660964 10 10 10 10243338 6 6 12 18 301030 10 20 10 19931569 10 10 10 102933369 Deci avem: 1 << log n << n << n log n << n2 << n3 << 2n << n!. Algoritmul 3 este O(1) (adica independent de n). La comportarea algoritmilor ne intereseaza comportarea lor pentru valori mari ale problemei. log n. pentru analiza unui algoritm nu vom calcula numarul tuturor operatiilor pe care un algoritm le efectueaza. n. n2. putem spune ca cel mai bun algoritm este Algoritmul 3. Deoarece n2 >> n >> 1 pentru n mare. faptul ca rata de crestere a algoritmului 2 este proportionala cu n2 se spune ca algoritmul 2 este O(n2). respectiv n in cazul nostru. Informaticienii folosesc o notatie pentru reprezentarea complexitatii unui algoritm si anume. iar rata de crestere a algoritmului 3 este independenta de n. f(n) = 4n+3 = O(n). f(n) = 4 = O(1). De asemenea. c real ∃ N natural astfel incat f(n)≤ c g(n). algoritmii intalniti pot avea rate de crestere de ordinuri: 1. In exemplul de mai sus avem: Algoritmul 1 este O(n). Definitie: Timpul de rulare al unui algoritm f(n) este de ordin cel putin g(n). e. nu vom lua in calcul modul de implementare al unui for loop si implicit numarul de atribuiri 3 . 2n . f(n) = 2n2+ n+3 = O(n2). ca de exemplu. Algoritmul 2 este O(n2). n3. urmat in ordine de Algoritmul 1 si Algoritmul 2. Deoarece n2 este mult mai mare decat n+3 (fapt pe care il scriem n2 >> n+3). putem spune ca 2n2+ n+3 se comporta ca si n2.Algoritm 1 Atribuiri: 2n+2 Comparatii: n+1 Adunari/scaderi: n Inmultiri/impartiri: 0 Total operatii: 4n+3 Algoritm 2 Atribuiri: n2+2 Comparatii: (n2+3n +2)/2 Adunari/scaderi: n(n-1)/2 Inmultiri/impartiri: 0 Total operatii: 2n2 + n+3 Algoritm 3 Atribuiri: 1 Comparatii: 0 Adunari/scaderi: 1 Inmultiri/impartiri: 2 Total operatii: 4 Daca presupunem ca pentru efectuarea tuturor acestor operatii este necesar acelasi numar de unitati de timp. i. f(n) = O(g(n)) daca ∃ c >0. putem spune ca: rata de crestere a algoritmului 1 este direct proportional cu 4n+3 rata de crestere a algoritmului 2 este direct proportional cu 2n2+ n+3 rata de crestere a algoritmului 3 este direct proportional cu 4. Exemplu: Se poate demonstra ca 1. Tabelul urmator ne arata cum se comporta cateva functii de crestere pentru valori crescatoare ale lui n. 2.

nici chiar fiecare atribuire sau operatie de adunare/scadere/inmultire/impartire ci lua in considerare numai acele operatii importante. avem fie f(n) = O(g(n)) or g(n) = O(f(n)). Determinati care din cele doua relatii este adevarata pentru urmatoarele functii: a) f(n) = (n2 – n) /2. g(n) = n 4 . Lab 10 Pentru fiecare dintre perechile de functii f(n) si g(n). in cazul unui algoritm de inmultire a doua matrici.sau comparatii efectuate pentru stabilirea valorii indicelui. in functie de marimea problemei. dar nu amandoua cazurile in acelasi timp. deci vom defini una sau mai multe operatii de baza pe care le efectueaza un algoritm si vom calcula numarul de operatii de acel tip. in cazul unui algoritm de cautare a unui element dat intr-o lista. g(n) = n n d) f(n) = n2 + 3n +4. de care depinde timpul de rulare al unui algoritm. g(n) = n2 c) f(n) = n + n log n. De exemplu. operatia de baza fiind inmultirea. numarul de comparatii intre elementul dat si elementele din lista este esential. numarul de inmultiri este esential. g(n) = n3 e) f(n) = n log n g(n) = n n /2 f) f(n) = n + log n. g(n) = 6n b) f(n) = n + 2 n .

Asa cum mentionam in finalul capitolului 9 Analiza eficientei algoritmilor. Deci vrem sa gasim o permutare p a numerelor 1... R2. poz[i] va reprezenta pozitia lui Ki in sirul ordonat. Deci algoritmul este 2 i =1 2 O(N ) (deci nu este un algoritm rapid) si. Se foloseste sirul auxiliar poz cu N elemente intregi. putem aranja studentii unei grupe in ordine alfabetica dupa numele de familie sau in ordine descrescatoare a mediei fiecarui student. KN. Pentru memorarea pozitiei se foloseste un sir auxiliar. sau chiar dupa culoare. RN ce trebuie sortata intr-o anumita ordine. De fapt. 2. daca stabilim in prealabil o ierarhie a culorilor. N-1 for j = i+1. in cazul nostru de N −1 1 comparatii. sa zicem crescator dupa una din caracteristicile comune ale obiectelor din colectie pe care o vom numi cheie si o vom nota K. . Analiza algoritmului: Observati ca exista o singura clasa de valori posibile de intrare. Dupa terminarea algoritmului. nu am prezentat acest algoritm pentru eficienta sa ci pentru simplitatea sa. . astfel incat Kp(1) ≤ Kp(2) ≤ . Lab 11 Scrieti un program care implementeaza algoritmul de mai sus. Algoritm de sortare prin numarare: Se dau K1. cate elemente au cheile mai mici decat cheia lui gasim pozitia elementului in sirul ordonat... Se determina pozitia fiecarui element in sirul ordonat.... ≤ Kp(N) sau o modalitate de rearanjare a obiectelor astfel incat K1 ≤ K2 ≤ ... Numar total comparatii = ∑ ( N − i ) = N ( N − 1) . ≤ KN.Modulul IV. in plus. In cele ce urmeaza presupunem ca avem o colectie de obiecte R1.. N. for i = 1... putem aranja cartile dintr-o biblioteca in ordine alfabetica dupa autor sau dupa titlu. . Capitolul 10. Sortare prin numarare Aceasta tehnica de sortare se bazeaza pe faptul dupa sortare elementul aflat pozitia i are cheia mai mare decat cheile a i -1 elemente si deci numarand pentru fiecare element din lista. N if Kj < Ki then poz[i] = poz[i] + 1 else poz[j] = poz[j] + 1 endif endfor endfor Observatie: ca algoritmul functioneaza chiar si daca elementele au chei egale.. . N poz[i] = 1 endfor for i = 1. De exemplu. necesita si un spatiu de memorie pentru cele N elemente ale sirului auxiliar. Algoritmi de sortare Orice colectie de obiecte intre care exista o relatie de ordine poate fi sortatat adica aranjata in ordine crescatoare sau descrescatoare. vom determina numai numarul de operatii de baza efectuate. K2.

. N. Ki-1 se deplaseaza o pozitie spre dreapta. ... Deci numarul de comparatii= ∑1 = N − 1 si deci timpul minim ∼ N. ≤ Ki – 1 si vrem sa introducem Ki astfel incat secventa primelor i elemente sa fie ordonate crescator. N elem = Ki j = i-1 while j >= 1 and Kj > Ki j = j –1 endwhile pozitie = j +1 for j= i... incepand de la sfarsitul secventei... lista este ordonata crescator.. Sa estimam intai timpul minim de executie. .. Algoritm de sortare prin inserare: Se dau K1. Aceasta nu necesita memorie auxiliara si este de asemenea o metoda simpla. Deci nici acesta nu este un algoritm rapid si. . Cand pozitia j a fost gasita. -1 Kj = Kj-1 endfor Kpozitie = elem endfor Analiza algoritmului: Intai sa observam ca operatia principala care se efectueaza este comparatia dintre elementele listei. Deci daca se presupune ca K1 ≤ K2 ≤ . si deci pentru fiecare i=2. pozitie+1. intreaga secventa Kj+1.... ciclul while va repeta numarul maxim de comparatii care este (i-1) pentru fiecare i=2. iar elementul Ki se insereaza in pozitia j+1.. Algoritmi de sortare Capitolul 11.. in plus. . N nu se face decat o comparatie Ki-1 > Ki. Ideea principala este urmatoarea: se considera pe rand fiecare element al listei ce trebuie sortata si se introduce in pozitia necesara astfel incat atunci cand este examinat elementul i toate elementele de pe pozitiile 1. atunci cautam pozitia j astfel incat Kj ≤ Ki ≤ Kj+1. for i = 2. In cel mai rau i =2 N caz... caz ce corespunde unei liste de intrare ordonata strict descrescator.Modulul IV. Lab 12 Scrieti un program care implementeaza algoritmul de mai sus. 2.. . Deci N 1 numarul de comparatii= ∑ i − 1 = N ( N − 1) si deci timpul maxim ∼ N2. In cel mai bun caz. aceasta aparand numai in ciclul while. Se poate 2 i =2 2 demonstra ca timpul mediu ∼ N si deci algoritmul este O(N2). KN. Sortare prin inserare Una din cele mai importante metode de sortare este sortarea prin inserare. i-1 sunt deja sortate.. K2. necesita si deplasari de blocuri de elemente cate o pozitie spre dreapta.

In cel mai i =1 N −1 rau caz. Deci nici acesta nu este un algoritm rapid dar nu necesita deplasari de blocuri mari de elemente. si daca nu sunt in ordine atunci cele doua elemente se interschimba.. Sortare prin interschimbare Acest tip de sortare se refera la interschimbarea sistematica a elementelor listei ce trebuie ordonata pana ca toate elementele sunt in ordinea dorita. Sa estimam intai timpul minim de executie. In cel mai bun caz. Lista se parcurge de mai multe ori. 12.. comparam apoi K2 si K3. 1 . Numarul de comparatii= ∑1 = N − 1 si deci timpul minim ∼ N. Algoritm Bublesort: Se dau K1.1 Bublesort Idea principala este de a permite elementelor mici sa se mute la inceputul listei iar cele mari spre sfarsitul listei. ultim -1 if Ki > Ki+1 then Ki ↔ Ki+1 schimba = true endif endfor ultim = ultim –1 endwhile Analiza algoritmului: Intai sa observam ca operatia principala care se efectueaza este comparatia dintre elementele listei. Se poate demonstra ca timpul mediu ∼ N si deci algoritmul este O(N2).d. . KN.m.Modulul IV. Algoritmul se opreste atunci cand este efectuata o trecere prin lista si nici o interschimbare nu a fost efectuata.Se foloseste o variabila schimba care este true atunci cand se cere o interschimbare si false cand nu mai este nevoie de nici o interschimbare. iar ultima data KN-1 si KN. Lab 13 Scrieti un program care implementeaza algoritmul de mai sus.a. caz ce corespunde unei liste de N −1 1 intrare ordonata strict descrescator. La fiecare trecere oricare doua elemente vecine se compara si daca nu sunt in ordine crescatoare se interschimba. nici o interschimbare nu este efectuata si algoritmul se opreste. Incepem comparand K1 si K2. K2. ultim = N schimba = true while schimba = true schimba = false for i = 1.. lista este ordonata crescator. apoi K3 si K4 s. va fi necesara parcurgerea listei de N-1 ori. Algoritmi de sortare Capitolul 12. se efectueaza o singura trecere printre elementele listei. Observati ca deja dupa prima trecere elementul cel mai mare al listei se va afla in ultima pozitie in lista si deci a doua trecere va trebui sa parcurga lista numai de la K1 la KN-1.. Deci numarul de comparatii= ∑ i = N ( N − 1) si 2 i =1 2 2 deci timpul maxim ∼ N .

12. Prima parte a algoritmului o constituie partitionarea listei prin gasirea pozitiei pivotului. In final.. Elementele din cele doua parti (inainte si dupa element) nu sunt neaparat in ordine. Exista cel putin doua metode de alegere a pivotului. pentru acesta neexistand decat un singur caz. KN (tot o lista ordonate crescator dar cu N-1 elemente). daca N > 1 si C1 = 0 deci CN = N −1 1 ∑ i = 2 N ( N − 1) deci timpul maxim ∼ N2. daca pivotul este mutat in pozitia i. ultim) /* Sorteaza elementele Kprim. Scrieti un program care implementeaza algoritmul de mai sus. Deci numarul de operatii necesare sortarii unei liste ordonate crescator cu N elemente K1. Kultim.. Cand gaseste un element mai mic decat pivotul. Lab 14 2 ... astfel incat toate elementele mai mici decat pivotul sunt mutate inaintea lui. pozpivot +1. Se poate demonstra ca acest algoritm este i =1 O(N log N). deci elementul mai mic se schimba cu un altul mai mare. Apelarea initiala este pentru prim = 1 si ultim =N*/ if prim < ultim then valoarepivot = Kprim pozpivot = prim for i = prim + 1. i-1 sunt mai mici decat pivotul... Surprinzator. pentru care se distinge timpul minim. Tot ceea ce stim este ca. se pozitioneaza pivotul in pozitia nou gasita.2 Quicksort Quicksort alege un element din lista. . . numit pivot si rearanjeaza lista. atunci toate elementele din pozitiile 1. acest numar este N-1) + numarul de operatii necesare sortarii listei K2. Quicksort (K. . Desigur aceasta nu se intampla si pentru intregul algoritm Quicksort.. una vida iar cealalta avand cu 1 mai putine elemente decat lista originala. cel mai rau caz pentru acest algoritm este cazul in care lista este deja ordonata crescator. dupa ca a fost parcursa toata lista. pozitia pivotului ramane neschimbata adica de fiecare data pozpivot = prim si deci se imparte lista originala in doua liste. . pozpivot –1) call Quicksort (K. ultim) endif Analiza algoritmului: Operatia principala care se efectueaza este comparatia dintre elementele listei. K2. 2. Motivatia este urmatoarea: Lista fiind ordonata crescator. Algoritm Quicksort: Se dau K1. K2.. prin interschimbarea primului element cu elementul aflat in pozitia pivotului. KN. Noi o vom prezenta pe cea mai simpla si anume se alege ca pivot elementul de inceput al listei. N sunt mai mari.. Apoi Quicksort este apelat recursiv pentru cele doua parti ce trebuie sortate.. prim.. .... prim. iar toate elementele din pozitiile i+1. KN va fi = numarul de operatii necesarii partitionarii (asa cum am vazut. Deci se parcurge lista comparand acest pivot cu toate elementele listei.. daca vreti = ultim – prim). Obtinem deci urmatoarea relatie de recurenta: CN = N-1 + CN-1. iar toate elementele mai mari sunt mutate dupa pivot.... cel mic mutandu-se mai aproape de inceput. . mediu si maxim. pozitia pivotului este incrementata si elementul mai mic este intershimbat cu elementul aflat in noua pozitie a pivotului. inaintea pivotului. ultim if Ki < valoarepivot then pozpivot = pozpivot +1 Ki ↔ Kpozpivot endif endfor Kprim ↔ Kpozpivot call Quicksort (K. prin interschimbari. Aceasta partitionare necesita un numar de comparatii = numarul de elemente din secventa analizata –1 (sau.

if i ≠ index_min then Ki ↔ Kindex_mic endif endfor Algoritm de sortare prin selectie (varianta recursiva): Se dau K1.. Fie index_mic acesta. 2 i =1 Lab 16 Scrieti un program care implementeaza algoritmii de mai sus. K2. Kultim. N-1 Determina indexul celui mai mic element dintre Ki. numarul de comparatii efectuate fiind acelasi indiferent de lista de intrare. Algoritmi de sortare Capitolul 13. Kprim+1. 3. if prim ≠ index_min then Kprim ↔ Kindex_mic endif call Selectie (K. prim +1. Observati ce numarul de comparatii necesar determinarii celui mai mic element intrun sir cu n elemente este n-1 si deci relatia de recurenta care ne da acest numar de comparatii efectuate de algoritmul descris mai sus este CN = N-1 + CN-1... . .... Apelarea initiala este pentru prim = 1 si ultim =N*/ if ( prim < ultim) then Determina indexul celui mai mic element dintre Kprim... Acest algoritm prezinta o singura clasa de valori de intrare posibile. KN.. daca N > 1 si N −1 1 C1 = 0 deci CN = ∑ i = N ( N − 1) deci complexitatea algoritmul este O(N2).. prim. . .. . Sortare prin selectie Ideea algoritmului este: gaseste cel mai mic element si muta-l in prima pozitie prin interschimbarea cu elementul de pe prima pozitie si repeta procedeul pentru elementele listei de indici 2. KN. K2. Fie index_mic acesta.. for i = 1. ultim) /* Sorteaza elementele Kprim. Selectie (K. KN. ultim) endif Analiza algoritmului: Operatia principala care se efectueaza este comparatia dintre elementele listei. ..Modulul IV.. N. Kultim.. . Ki+1... Algoritm de sortare prin selectie (varianta iterativa): Se dau K1..

Lista C va fi lista nou creata indexA = 1 indexB = 1 indexC = 1 while indexA ≤ N and indexB ≤ M if AindexA < BindexB then CindexC = AindexA indexA = indexA +1 else CindexC = BindexB indexB = indexB +1 indexC = indexC +1 endwhile while indexA ≤ N CindexC = AindexA indexA = indexA +1 indexC = indexC +1 endwhile while indexB ≤ M CindexC = BindexB indexB = indexB +1 indexC = indexC +1 endwhile Algoritm Mergesort: Se dau K1. Mergesort (K. prim.. de dimensiuni egale sau foarte apropriate.. Sa vedem intai algoritmul de efectuare a operatiei de combinare a celor doua liste. K2. dupa care indicele listei din care facea parte acest element minim este incrementat cu 1. desigur). va fi cel mai mic dintre A1 si B1. Deoarece cel mai mic element din lista A este A1.. ≤ AN si B: B1 ≤ B2 ≤ . mijloc) 1 .. o impartim in doua liste.. Se continua procedeul pana cand una din liste se termina (chiar daca listele au acelasi numar de elemente. Atunci C2 va fi fie B1 sau A2 daca lista A inca mai contine elemente mai mici decat B1. KN. prim.. ordonam cele doua liste (folosind acelasi algoritm) si apoi efectuam operatia "merge". Idea algoritmul Mergesort este urmatoarea: Data o lista neordonata.Modulul IV. obtinand astfel lista originala ordonata. iar cel mai mic element din lista B este B1. Algoritm Merge: Se dau A1 ≤ A2 ≤ . una din liste se va termina inaintea celeilalte). C1... ultim) /* Sorteaza elementele Kprim. Deci presupunem ca avem doua liste A: A1 ≤ A2 ≤ . Kultim. ≤ AN si B: B1 ≤ B2 ≤ . ≤ CN+M. Pentru a putea hotari ce element urmeaza in lista C. Sa presupunem ca cel mai mic este A1. . adica vom combina cele doua liste ordonate intr-una singura.. stim ca cel mai mic element din lista C. astfel incat: C1 ≤ C2 ≤ . unul pentru lista A si unul pentru lista B.. Apelarea initiala este pentru prim = 1 si ultim =N*/ if prim < ultim then mijloc = ⎣(prim + ultim)/2⎦ call Mergesort(K. Este usor de vazut ca algoritmul Mergesort este recursiv.. Mergesort "Merge" inseamna a combina una sau mai multe liste ordonate (crescator. ≤ BM. .. Elementul cel mai mic este introdus in lista C.. Algoritmi de sortare Capitolul 14.... vom folosi doi indici. ≤ BM si vrem sa obtinem o lista C cu N+M elemente (toate elementele celor doua liste). sa presupunem) intr-o singura lista ordonata (tot crescator. caz in care elementele ramase in lista cealalta se scriu in ordine in lista C.

call Mergesort(K. caz ce corespunde celui mai rau caz. in cel mai bun caz. Cmin(1) = Cmin(0) = 0 Se poate arata ca Cmax(N) = Cmin(N) = O(N log N). deci numarul de comparatii efectuate va fi N. etc.. din nou. 2 . In acest caz numarul comparatiilor este N + M – 1.. Dezavantajul acestei metode este faptul ca algoritmul de combinare al celor doua liste ordonate necesita un spatiu de memorie destul de mare. mijloc +1. Acum. Deci ordinul de complexitate al algoritmului Mergesort este N log N.. Se poate arata ca. M). si deci mergesort este un algoritm eficient. ultim) call Merge(Kprim ≤ . algoritmul Merge asa cum este aplicat in algoritmul de sortare Mergesort. Lab 17 Scrieti un program care implementeaza algoritmul de mai sus. Similar. Deci numarul maxim de comparatii este N – M – 1. Obtinem urmatoarele relatii de recurenta: Cmax(N) = 2 Cmax(N/2) + N-1.. comparatia dintre elementele listei. ultim Ki = Ci endfor endif Analiza algoritmului: Operatia principala care se efectueaza este. va efectua un numar minim de comparatii = N/2 si un numar maxim de comparatii = N/2 + N/2 –1 = N –1. . cunoscand ordinul de complexitate al algoritmului Merge. Notam cu Cmin (N) = numarul de comparatii efectuate in cel mai bun caz si cu Cmax (N)= numarul de comparatii efectuate in cel mai rau caz. putem considera algoritmul Mergesort. Ce se intampla daca toate elementele listei A sunt mai mici decat cele din lista B? Aceasta ar insemna ca fiecare element al lui A va fi comparat cu B (deoarece toate sunt mai mici decat acesta ele vor fi copiate in C iar elementele lui B vor fi apoi copiate).. Intai observati ca algoritmul Merge va compara un element al listei A cu un element al listei B pana cand una din liste se termina. B2 ≤ A2 ≤ B3. daca toate elementele listei B sunt mai mici decat cele din lista A atunci numarul de comparatii efectuate va fi M.. Cultim for i = prim. ≤ Kmijloc si Kmijloc+1 ≤ . cu alte cuvinte B1 ≤ A1 ≤ B2. numarul de comparatii va fi min(N. Cmax(1) = Cmax(0) = 0 Cmin(N) = 2 Cmin(N/2) + N/2. Sa consideram acum cazul in care elementele listei A sunt printre elementele listei B. Conform analizei anterioare.. ≤ Kultim)⇒ Cprim.

K = KN caz in care se efectueaza N comparatii Deci in medie numarul de comparatii va fi: 1 (1 + 2 + . R2. presupunem ca cele N chei sunt distincte. .. In cazul unei cautari cu succes putem avea urmatoarele clase de valori de intrare: K = K1 caz in care se efectueaza 1 comparatie K = K2 caz in care se efectueaza 2 comparatii . Algoritmi de cautare Ca si in cazul sortarii. K2. Capitolul 15. Cel mai rau caz daca avem o cautare cu succes: elementul cautat este in ultima pozitie si deci sunt efectuate N comparatii. vom ignora orice alta caracteristica pe care ar putea avea-o obiectele din colectie si vom lua in considerare numai caracteristica cheie. daca a fost localizat obiectul cu cheia K sau fara succes daca nu a fost gasit nici un obiect cu cheia K. Algoritm de cautare secventiala: Se dau K1. In general. presupunem ca avem o colectie de obiecte R1. In continuare.. RN si ca fiecare obiect prezinta o caracteristica pe care o vom numi cheie. KN si K..Modulul V. Se cauta K in lista.. element cu element.. Cautarea poate fi cu succes. + N + N ) = N + 1 − 1 = O( N ) N +1 2 N +1 Cel mai bun caz: elementul cautat este in prima pozitie si deci numarul minim de comparatii este 1. In cazul unei cautari fara succes numarul de comparatii este N. Cautare secventiala Cautarea secventiala presupune cautarea in colectie a elementului dat... pentru o intelegere mai buna a algoritmilor de cautare..... fie cand a fost parcursa intreaga colectie si elementul nu a fost gasit. incepand cu primul si oprindu-ne fie cand elementul a fost gasit. . Cel mai rau caz daca elementul avem o cautare fara succes: N comparatii. Folosim variabila de tip boolean gasit care este initial falsa si devine adevarata atunci cand elementul a fost gasit... gasit = false i=1 while ( i ≤ N and not gasit) if K = Ki then gasit = true else i = i+1 endif endwhile if gasit then tipareste "Cautare cu succes" K a fost gasit in pozitia i else tipareste "Cautare fara succes" endif Analiza algoritmului: Operatia principala care se efectueaza este comparatia dintre elementul cautat si elementele listei. Data o valoare K problema este de gasi obiectul din colectie care are cheia K. .

+ N ) = 1 N ( N + 1) = N + 1 − 1 = O( N ) 2N +1 2N +1 2 4 4(2 N + 1) Lab 18 Scrieti un program care implementeaza algoritmii de mai sus...... In cazul unei cautari fara succes putem avea urmatoarele clase de valori de intrare: K < K1 caz in care se efectueaza 1 comparatie K1 < K < K2 caz in care se efectueaza 2 comparatii K2 < K <K3 caz in care se efectueaza 3 comparatii .. gasit = false i=1 while ( i ≤ N and not gasit) if K = Ki then gasit = true else if K < Ki then gasit = false else i = i+1 endif endif endwhile if gasit then tipareste "Cautare cu succes" K a fost gasit in pozitia i else tipareste "Cautare fara succes" endif Analiza algoritmului: Operatia principala care se efectueaza este comparatia dintre elementul cautat si elementele listei.. Cel mai rau caz daca avem o cautare cu succes: elementul cautat este in ultima pozitie si deci sunt efectuate N comparatii.. Se cauta K in lista.. In cazul unei cautari cu succes putem avea urmatoarele clase de valori de intrare: K = K1 caz in care se efectueaza 1 comparatie K = K2 caz in care se efectueaza 2 comparatii . Cel mai bun caz daca avem o cautare fara succes: K < K1 si deci numarul minim de comparatii este 1. KN-1 < K < KN caz in care se efectueaza N comparatii K > KN caz in care se efectueaza N comparatii Deci in medie numarul de comparatii va fi: 1 (1 + 2 + .. + N + 1 + 2 + . Cel mai bun caz daca avem o cautare cu succes: elementul cautat este in prima pozitie si deci numarul minim de comparatii este 1.Algoritm de cautare secventiala intr-un sir ordonat crescator: Se dau K1 < K2 < . K = KN caz in care se efectueaza N comparatii.. ... Cel mai rau caz daca avem o cautare fara succes: K > KN: se efectueaza N comparatii.. Folosim variabila de tip boolean gasit care este initial falsa si devine adevarata atunci cand elementul a fost gasit. < KN si K...

.

. in acest caz vom lua drept element de mijloc pe cel cu indicele mai mic) (mijloc = 4). l = 1. exista de fapt doua elemente de mijloc.. Algoritm de cautare binara (varianta iterativa): Presupunem K1 < K2 < . b) 21 in lista: Elementul din mijloc este 10 (mijloc = 4)... cautam 7 in secventa din lista formata numai din elementul K3.. KN. cautam 21 in a doua jumatate a listei adica printre elementele K5.. sa presupunem ca avem o lista de numere intregi ordonate crescator: 1 4 9 10 15 21 23 38 si cautam a) 7 in lista: Elementul din mijloc este 10 (deoarece numarul de elemente din lista este par. Cautare binara Presupunem ca lista de elemente este ordonata crescator.. Deoarece 7 < K3 = 9... Deoarece 21 = K6. K > Kmijloc. deci K nu este gasit. cheia data a fost gasita si algoritmul se termina. De exemplu. se obtine o cautare cu succes si algoritmul se termina. 1 4 9 10 15 21 23 38 Elementul din mijloc al noii secvente din lista este 21 (mijloc = 6). 1 4 9 10 15 21 23 38 Elementul din mijloc al noii secvente din lista este evident 9 (mijloc = 3).. caz in care K trebuie cautat printre elementele Kmijloc + 1 .. putem aveam unul din urmatoarele cazuri: i. Deoarece 7 < K4 =10. Deoarece 7 > K2 =3. K2. gasit = false while (l ≤ u and not gasit) m = ⎣( u + l) / 2⎦ if K = Km then gasit = true else if K < Km then u = m-1 else l = m+1 . Folosim doi indici l. Algoritmi de cautare Capitolul 16. K8. K3. In caz contrar.. 1 4 9 10 15 21 23 38 Elementul din mijloc al noii secvente din lista este 4 (mijloc = 2). ii. u pentru a preciza limitele intre care se cauta cheia K.. < KN si se cauta K in lista. caz in care K trebuie cautat printre elementele K1. cautam 7 in prima jumatate a listei adica printre elementele K1. Folosim si variabila de tip boolean gasit care este initial falsa si devine adevarata atunci cand elementul a fost gasit. secventa in care 7 trebuie cautat este vida. < KN si se cauta K in lista. Initial l = 1 si u = N.Modulul V. . Daca da. Kmijloc – 1. u =N. K < Kmijloc. . Procedeul continua pana cand K este gasit sau pana cand K se cauta intr-o lista vida. Idea algoritmului de cautare binara este de a testa intai daca elementul K coincide cu elementul din mijloc al listei. deci 7 nu a fost gasit si algoritmul se termina. K1 < K2 < . Deoarece 21 > K4 = 10. .

u) if l ≤ u then m = ⎣( u + l) / 2⎦ if K = Km then gasit = true stop else if K < Km then call Cautarebinara(K. s. la a doua trecere se compara K cu elementul din mijloc al unei liste cu 2k-1 –1 elemente. atunci numarul maxim de comparatii este ⎣log2(N+1)⎦. . u pentru a preciza limitele intre care se cauta cheia K. Deci in cel mai rau caz se efectueaza k = log2(N+1) comparatii.. Initial l = 1 si u = N. < KN si se cauta K in lista.d. la a k-a trecere se cauta K intr-o lista cu 21-1 =1 elemente. m –1) else call Cautarebinara(K. daca nu este gasit se face cautarea intr-o lista de doua ori mai mica. in cel mai rau caz. Folosim doi indici l. Folosim si variabila de tip boolean gasit care este initial falsa si devine adevarata atunci cand elementul a fost gasit.m. Cautarebinara(K. atunci la prima trecere prin lista se compara K cu elementul din mijloc al unei liste cu 2k –1 elemente. Lab 19 Scrieti un program care implementeaza algoritmii de mai sus. Se poate arata ca algoritmul de cautare binara este O(⎣log2(N+1)⎦). l.endif endif endwhile if gasit then tipareste "Cautare cu succes" K a fost gasit in pozitia m else tipareste "Cautare fara succes" endif Algoritm de cautare binara (varianta recursiva): Presupunem K1 < K2 < . Daca N este oarecare. m+1. Sa presupunem ca N = 2k –1. u) endif endif else gasit = false endif Analiza algoritmului: Operatia principala care se efectueaza este comparatia dintre elementul cautat si elementele listei.a.. l. Se observa ca de fiecare data cand se incearca gasirea elementului se face comparatia cu elementul din mijlocul listei. dupa care. pana cand.

In continuare prezentam arborii binari de cautare in care operatiile de baza sunt proportionale cu inaltimea arborelui. Arbore care nu este arbore binar de cautare 1 . Algoritmul este eficient dar structura de date folosita este o lista liniara.Modulul V. In capitolul precedent. daca se presupune ca fiecarui nod ii asociem un element al colectiei de obiecte ce dorim sa o sortam. care pt un arbore binar complet cu n noduri este log n. iar toate nodurile ce se afla in subarborele drept au o valoare mai mare decat valoarea nodului. Arbori binari de cautare. toate nodurile ce se afla in subarborele stang al oricarui nod dat au o valoare mai mica decat valoarea nodului dat. in care inserarile si stergerile nu sunt eficiente ( mai exact sunt de ordin n). Exemple: 1. Definitie: Un arbore binar de cautare este un arbore binar in care. Algoritmi de cautare Capitolul 17. am folosit algoritmul de cautare binara pentru a sorta elementele unei liste. Asa cum am vazut. Arbore care este arbore binar de cautare 2. dupa fiecare iteratie algoritmul reduce numarul de elemente in care se face cautarea la jumatate.

in exemplul 1 de mai sus. comparam 9 cu 10 valoarea radacinii. 17. v) else if v < T -> info then call Insert (T-> stang.17. Dar acest lucru se intampla numai cand arborele este echilibrat. v) if T = NULL then Aloca memorie pentru un nod nou. Algoritm de inserare (varianta recursiva): Se dau arbore binar de cautare T = pointer la radacina arborelui si v noua valoare ce trebuie inserata in arbore. si cum 9 < 10 comparam valoarea cautata cu radacina subarborelui stang adica vom compara 9 si 4 si cum 9>4 se merge si mai jos un nivel si se compara valoarea cautata cu valoarea radacinii subarborelui drept. Fiecare comparatie reduce numarul de elemente comparate la jumatate si deci algoritmul este similar cautarii binare intr-o lista liniara. pentru un arbore ca cel din figura de mai jos timpul de cautare este proportional cu numarul de elemente ale intregii colectii. depinde cum este valoarea cautata fata de valoarea radacinii. v) else write "valoare deja in arbore" stop endif endif 2 . Returneaza p. Insert (T. pentru a cauta valoarea 9. De exemplu. p -> info = v p ->stang = NULL p -> drept = NULL T=p else if v > T -> info then call Insert (T->drept. De exemplu. un pointer la noul nod. si observam ca am gasit valoarea cautata.2 Inserare si stergere arbori binari de cautare Operatiile de inserare si stergere trebuie efectuate astfel incat proprietatea de arbore binar de cautare sa se mentina.1 Cautare in arbori binari de cautare Pentru a cauta o valoare data intr-un arbore binar de cautare incepem comparand valoarea data cu radacina arborelui si mergem apoi in jos la stanga sau la dreapta.

endif Algoritm de stergere: Se dau arbore binar de cautare T = pointer la radacina arborelui si nodul N ce trebuie eliminat din arbore. N este nod terminal atunci daca se noteaza cu P un pointer la tatal nodului N atunci nodul N este inlocuit cu NULL. Lab 20 1. In acest caz exista trei cazuri: 1. adica P->stang = NULL daca N este fiu stang or P->drept = NULL daca N este fiu drept. N are un singur fiu si fie X un pointer la fiul lui N atunci fiul lui N devine fiul tatalui lui N. Scrieti un program care cauta un element dat intr-un arbore binar de cautare. adica daca se noteaza cu P un pointer la tatal nodului N atunci P->stang = X daca N este fiu stang or P->drept = X daca N este fiu drept. 2. Scrieti un program care insereaza un element dat intr-un arbore binar de cautare. 3 . Scrieti un program care sterge un element dat intr-un arbore binar de cautare. 3. N are 2 fii: algoritmul este: Gaseste R cel mai din dreapta nod al subarborelui stang al lui N Inlocuieste informatia nodului N cu informatia din nodul R Sterge nodul R. 3. 2.

codul continutului vagonului (9 cifre). Scrieti un program care afiseaza un arbore binar dat pe ecran. Scrieti un program care printr-o singura traversare a unui arbore binar gaseste elementele maxim si minim din acel arbore. Intr-o gara se considera un tren de marfa ale carui vagoane sunt inventariate intr-o lista. Lista contine. . / si * iar operanzii sunt constante. Scrieti un program pentru obtinerea listei predecesorilor unui nod dintr-un graf reprezentat prin liste de adiacenta. va determina nodul vizitat dupa v in preordine. Deoarece in gara se inverseaza pozitia vagoanelor. Se consideră o masă circulară la care sunt aşezaţi copii şi fie n un număr întreg pozitiv. -.adresa expeditorului (4 cifre). Pornind de la un anumit copil ei încep să numere pe rând.codul vagonului (9 cifre). Scrieti un program care cauta un element dat intr-un arbore binar. 2. Scrieti un program care insereaza un element dat intr-o pozitie data. pentru fiecare vagon. Scrieti un program care evalueaza o expresie aritmetica in care apar operatorii +. inordine si respectiv postordine. Scrieti un program care pentru un arbore binar dat T si un nod dat v. 3. 5. Programul va conţine funcţii pentru: crearea listei vide afişarea elementelor listei căutarea unui student în listă adăugarea unui student la lista (la început. 7. 2. . 9. Să scrie un program care să calculeze produsul a două polinoame utilizându-se pentru reprezentarea unui polinom o listă simplu înlănţuită. 4. la sfârşit.Probleme propuse Modulul I. Să se implementeze o listă dublu înlănţuită ale cărei elemente să fie studenţii unei facultăţi. Jocul se opreşte atunci când râmâne un singur copil. Structuri de date liniare 1. a carui pozitie in arbore se cunoaste. 6. Modulul II. după un anumit nod specificat). urmatoarele date: . Atunci când unul din copii ajunge numărul n acesta se ridică de la masă şi se reia numărătoarea pornind de la 1. in ordinea vagoanelor. Scrieti un program care calculeaza numarul de noduri terminale ale unui arbore binar dat. 8. Realizaţi un program ce utilizează o listă circulară pentru a afişa ordinea în care copiii se ridică de la masă. Scrieti un algoritm nerecursiv pentru traversare in inordine a unui arbore binar 1 . 3. 5. 4. Structuri de date neliniare 1. . Scrieti un program pentru obtinerea listei succesorilor unui nod dintr-un graf reprezentat prin liste de adiacenta.adresa destinatarului (4 cifre). se cere listarea datelor despre vagoanele respective in noua lor ordine.

Analizati cei doi algoritmi. de la stanga la dreapta. i = 1. Analizati ordinul de complexitate a algoritmului. .. s = 0 for i = 1. aflati ordinul de complexitate in functie de n: a. Scrieti un program care tipareste nodurile unui arbore binar. i s=s+i Modulul IV. 2*n for j = 1. Implementati algoritmul bucket sort.. Aceasta versiune noua modifica analiza algoritmului in cel mai rau caz? 2. incepand cu cele de pe nivelul 0. 2. p = 1 for i = 1. Scrieti doi algoritmi. s = 0 for i = 1. i s=s+i e. Analiza algoritmilor 1.. x[i].. Descrieti o metoda simpla de calcul a valorii unui polinom intr-un punct.. 10. x[1]. n2 p = p* i d. s = 0 for i = 1. 2*n p = p* i c. Modulul III. Algoritmi de sortare 1. 2.. x[n].. Afiseaza al n-lea intreg intr-un sirf de intregi Calculeaza suma primilor n par intregi intr-un sir de intregi. Implementati algoritmul Heapsort. O versiune diferita a algoritmului Bubblesort memoreaza locul in care a fost facuta ultima modificare si la pasul urmator nu va analiza elementele sirului care dincolo de acel loc. 2 . . 3. 4. n2 for j = 1... . n s=s+i b. 4. Pentru urmatoarele cicluri for. Pentru aceeasi problema aplicati schema lui Horner. unul quadratic si unul liniar pentru problema urmatoare: Dat un sir x de n elemente. Implementati algoritmul Shellsort. x[2].si implementati-l. p = 1 for i = 1. n astfel incat a[i] = media aritmetica a elementelor x[1]. calculati un sir a[i]. Care este complexitatea urmatorilor algoritmi in cel mai rau caz? Afiseaza toti intregii unui sir de numere intregi Afiseaza toti intregii unei liste inlantuita. 3. Scrieti algoritmul acestei noi versiuni si implementati-l.

Problema este sa determinam lungimea celui mai scurt drum de la sursa catre fiecare varf din graf. ale carui varfuri trebuie colorate astfel incat oricare doua varfuri adiacente sa fie colorate diferit. Folosind cele trei programe. Se dau două mulţimi de numere întregi A şi B. daca avem trei clienti cu t1 = 5. 6. 1 ≤ i ≤ n. Se consideră o mulţime formată din n elemente numere întregi. Fie G = <V. t2 = 10. 4. clientul 2 asteapta pana este servit clientul 1 si apoi este servit. Scrieti un program care verifica daca un arbore binar este arbore binar de cautare. dupa ce a vizitat fiecare din celelalte orase exact o data. De exemplu. Fiecare element al matricei este o camera. Se da un labirint sub forma de matrice cu n linii si m coloane. 3. Scrieti un program care calculeaza reuniunea. Fiecare camera are 0 pana la 3 usi. Implementati oricare trei algoritmi de sortare prezentati in materialul teoretic. Implementati algoritmul de cautare prin interpolare. comparati timpurile de rulare ale lor pentru siruri de elemente generate aleator. Să se genereze toate submulţimile acestei mulţimi având proprietatea că suma elementelor lor este egală cu S. 9. Unul din varfuri este desemnat ca varf sursa. 2. Timpul de servire necesar fiecarui client este cunoscut in prealabil: pentru clientul i este necesar un timp ti. pompa de benzina etc) trebuie sa satisfaca cererile a n clienti. Timpul total de asteptare a celor trei clienti este 38. 7. 5. 2. Modulul VI. Singura statie de servire (procesor. clientul 1 este servit primul. Algoritmi de cautare 1. ceea ce este acelasi lucru cu a minimiza timpul mediu de asteptare. Folosind metoda Divide-et-Impera. sunt posibile sase ordini de servire. intersectia si cele doua diferente ale doua multimi date. 3. Să se genereze toate funcţiile f : A → B . t3 = 3. unde V este multimea varfurilor si M este multimea muchiilor. M> un graf orientat. 2 si apoi este servit. Problema este de a obtine o colorare cu un numar minim de culori. Problema este de a minimiza lungimea drumului parcurs. Se cunosc distantele dintre mai multe orase. Modulul V. scrieti un program care gaseste cel mai 3 . clientul 3 asteapta pana sunt serviti clientii 1.5.+tn. Se da o pozitie initiala si sa se gaseasca toate posibilitatile de a iesi din labirint. 4. Metode de elaborare a algoritmilor 1. Scrieti un algoritm recursiv de cautare a unui element intr-un sir. Fie G = <V. Scrieti un program care verifica daca un arbore binar este arbore binar echilibrat. Sa se descompuna numarul natural n in toate modurile posibile ca suma de p numere diferite (p≤n). 8. Dorim sa minimizam timpul total de asteptare t1 + t2 +. Fiecare muchie are o lungime nenegativa. M> un graf neorientat. In primul caz. examinand ultimul element al sirului. Un comis-voiajor pleaca dintr-un oras si doreste sa se intoarca in acelasi oras. care este T/n. 5..

4 . 10.mare element al unui sir. Scrieti un program de adunare si multiplicare a doua numere foarte mari.

DO-optionala. Structuri de date neliniare Arbori. Alocarea inlantuita. Structuri de date liniare Liste liniare. The MIT Press. DE-economica/manageriala. dr... DL-liber aleasa (optionala) Discipline anterioare Obligatorii (conditionate) Recomandate Programare procedurala Obiective Cunoasterea modului de organizare a principalelor structuri de date liniare si neliniare (liste. Heapsort 5. 1.2 STRUCTURI DE DATE ŞI ALGORITMI Semestrul 3 Numarul de credite 5 Stiinta si tehnologia Informatiei Informatica Informatica DF DI Categoria formativa a disciplinei DF-fundamentala. Brian Kernighan si Denis Ritchie. Data Structures. Alocarea secventiala..3. Cautare si inserare in arbori binari de cautare. Knuth D.E. Reprezentare. cozi. 2001 Coordonator de discplina DANIELA JOITA Grad didactic. Algoritmi de cautare Cautare secventiala. Liste circulare. E 60 20 10 10 Continut (descriptori) Forma de evaluare (E-examen. Algoritmi de sortare Sortare prin numarare. Bublesort. Cunoasterea metodologiei de analiza a algoritmilor. grafuri). titlul. Complexitatea algoritmilor 4.Universitatea TITU MAIORESCU Bucureşti PROGRAMA ANALITICA Denumirea disciplinei Codul disciplinei Facultatea Profilul Specializarea I. 3. Sortare prin inserare. Insusirea principalilor algoritmi de sortare si cautare. LP-lucrari de control) Stabilirea -raspunsurile la colocviu Notei finale -activitati aplicative atestate/ laborator/ lucrari practice (procentaje) -teste continua pe parcursul semestrului -activitati gen referate/ proiecte Bibliografie 1. Arta programarii calculatoarelor. stive. Traversare 3. nume Lector univ.2.H. Leiserson C. Grafuri. arbori. Ioan Tomescu. 19982004. cozi. stive. Introduction to Algorithms. Cautare binara. prenume.E. Limbajul C. Quicksort. Sortare prin selectare. Mergesort. 1997 2. DS-de specialitate. Stein C. DU-umanista Categoria de optionalitate a disciplinei: DI-impusa..L. C-colocviu/test final. Editura Universitatii din Bucuresti. Analiza algoritmilor Metode de analiza a eficientei algoritmilor. DANIELA JOITA Semnatura 1 . Cormen T. Liste dublu inlantuite 2. Editura TEORA. Rivest R. Editura TEORA 4. Arbori binari. DG-generala.

Proiect . prenumele si grupa studentului sa fie trimis ca attachment la urmatoarea adresa de email: joita. . programul/ programele care contine/contin implementarea algoritmului (aici includeti suficiente comentarii explicative) 4. ce algoritm ati alege? Dar pentru un sir de 500 de elemente? Dar 50000 de elemente? Dupa ce raspundeti la aceste intrebari.utm@gmail. raspunsurile dvs la intrebarea de mai sus (inclusiv justificarea raspunsurilor) 2.com cu subiectul proiect -algoritmi structuri date pana la data de 15 ianuarie 2009 (inclusiv). un exemplu de rulare pentru un sir de 20 de elemente. sir care va fi ales de dvs. Proiectul – referat va trebui sa contina: 1. Aruncati o privire de ansamblu asupra acestora si incercati sa raspundeti la urmatoarele intrebari: Exista un cel mai bun algoritm de sortare? Daca ar fi sa alegeti un algoritm de sortare pentru a sorta un sir de 50 de elemente (sa zicem numere intregi). alegeti unul din algoritmii de sortare prezentati (poate fi si cel mai bun si/sau cel mai putin bun) si implementati-l. scurta descriere a algoritmului 3.Algoritmi si structuri de date Materialul inclus pe acest CD prezinta o serie de algoritmi de sortare. Proiectul trebuie sa fie redactat pe calculator sa fie individual sa contina numele.

Sign up to vote on this title
UsefulNot useful