5/28/2018 15827872 Tehnici de Programare
1/158
Decan Sef de catedra
Prof. Univ. Dr. Rodica TRANDAFIR Conf. Univ. Dr. Rodica IOANVIZAT
FISA DISCIPLINEI
I.
UNIVERSITATEA SPIRU HARET
FACULTATEA MATEMATICA-INFORMATICA
DOMENIUL DE LICENTA INFORMATICA
SPECIALIZAREA INFORMATICA
Anul universitar 2008 - 2009
Forma de invatamant ZI
II.
DENUMIRE DISCIPLINA TEHNICI AVANSATE DE PROGRAMARE
III.
CODUL DISCIPLINEI
IV.
Statut disciplina Obligatorie Optionala Facultativa
(se marcheaza cu X) X
V. Structura disciplinei (nr. ore)
Semestrul
(numar de
la 1 la 6)
Curs
(nr. ore/sapt.
si total
nr.ore/sem.)
Seminar
(nr. ore/sapt.
si total
nr.ore/sem.)
Laborator
(nr. ore/sapt.
si total
nr.ore/sem.)
Lucrari practice
(nr. ore/sapt.
si total
nr.ore/sem.)
Proiecte
(nr. ore/sapt.
si total
nr.ore/sem.)4 2/28 - 2/28 - -
VI.(ETCS)
Numar credite 6
VII.
OBIECTIVELE DISCIPLINEI
1. Valorificarea cunostintelor acumulate in cadrul cursurilor de Programare Procedurala,Algoritmi si Structuri de date, Proiectare si Programare Orientata Obiect in vederea
programarii unor algoritmi avansati elaborati cu metode specifice.
2. Crearea deprinderilor de a gandi si programa folosind sabloane (templates)3.
Insusirea unor algoritmi avansati in domeniul prelucrarii sirurilor.4. Cresterea capabilitatii in utilizarea in programarea generica a limbajelor C++ si Java.
5. Asigurarea compatibilitatii cu invatamantul de excelenta : University of Cambridge(http://www.cl.cam.ac.uk/DeptInfo/CST05/node30.html); Imperial College London
(http://www3.imperial.ac.uk/computing/teaching/undergraduate/computing/lectures);
Princeton University (http://www.cs.princeton.edu/academics/catalog/ugrad)
VIII.
CONTINUT TEMATIC
I. Structuri de date fundamentale (Recapitulare)
II. Metode avansate de proiectarea algoritmilor:
1. Recursivitate2. Metoda Greedy3. Metoda Backtracking
http://www.cl.cam.ac.uk/DeptInfo/CST05/node30.htmlhttp://www3.imperial.ac.uk/computing/teaching/undergraduate/computing/lectureshttp://www.cs.princeton.edu/academics/catalog/ugradhttp://www.cs.princeton.edu/academics/catalog/ugradhttp://www3.imperial.ac.uk/computing/teaching/undergraduate/computing/lectureshttp://www.cl.cam.ac.uk/DeptInfo/CST05/node30.html5/28/2018 15827872 Tehnici de Programare
2/158
4. Metoda Divide et impera5. Metoda Programrii dinamice6. Metoda Branch&Bound.7. Procesarea sirurilor
IX.
TEME SEMINAR-
X.
LUCRARI DE LABORATOR
1. Metode de elaborarea algoritmilor (14 ore)2. Biblioteca Standard de Sabloane (STL) a limbajului C++ (6 ore)3. Cautare in siruri (2 ore)4. Programare generica in Java (6 ore).
XI.
LUCRARI PRACTICE
-
XII.
PROIECTE
-
XIII. Forma de evaluare (procent din nota finala)
Examen Colocviu Verificare pe
parcurs
Lucrari
practice
Laborator Proiecte
- - 70% - 30% -
XIV. BibliografieObligatorie minimala Suplimentara Facultativa
1. Albeanu G.,Algoritmi si
limbaje de programare,
Editura FRM, 2000 (pag. 207-
233)
2. Albeanu G. (coord), L.
Rapeanu, L. Radu, A.
Averian, Tehnici de
programare, Editura FRM,
2003.
3.Doina Logofatu,Algoritmi
fundamentali in Java/C++.
Aplicatii. Polirom, 2007
(integral).
4. Valeriu Iorga, Cristian
Opincaru, Corina Stratan,
Alexandru Chirita, Structuri
de date si algoritmi. Aplicatii
in C++ folosind STL,
Polirom, 2005.
1. Java, Using and
Programming Generics
in J2SE 5.0,
http://java.sun.com/devel
oper/technicalArticles/J2
SE/generics/
2. C. Galatan,
Introducere in C++
Standard Template
Library, Ed. All, 2008.
3. R. Neapolitan, K.
Naimipour ,
Foundations of
Algorithms Using C++
Pseudocode, Jones and
Bartlett Publishers, 2004.
1. N.M. Josuttis, The C++
Standard Library, Addison-
Wesley, 1999.
2. A. Drozdek,Data structures
and algorithms in C++,
Brooks/Cole, 2001.
3. Roberge J., Brandle S.,
Whittington D.,A laboratory
course in C++ data structures
(ed. 2), Jones and Bartlett
Publishers, 2003.
XV.
http://java.sun.com/developer/technicalArticles/J2SE/generics/http://java.sun.com/developer/technicalArticles/J2SE/generics/http://java.sun.com/developer/technicalArticles/J2SE/generics/http://java.sun.com/developer/technicalArticles/J2SE/generics/http://java.sun.com/developer/technicalArticles/J2SE/generics/http://java.sun.com/developer/technicalArticles/J2SE/generics/5/28/2018 15827872 Tehnici de Programare
3/158
Metode didactice (clasice/moderne)
1. Prelegerea - proiecie in amfiteatru, programe demonstrative;
2. Recomandarea, pentru studiul individual, a unor paragrafe din bibliografia indicat, n
vederea aprofundrii sau extinderii cunotinelor cptate la curs/laborator ;
3. Prezentarea unor exemple i a unor probleme aplicative n cadrul cursului pentru sporirea
interesului cursantilor.4. Evaluare folosind platforma Blackboard.
Data Titular disciplina
Titlul didactic, Numele si
prenumele
Prof. Univ. Dr. GRIGORE
ALBEANU
_____________________ Semnatura
_______________________
5/28/2018 15827872 Tehnici de Programare
4/158
31
2. Structuri de date
O structurde date este o mulime de date organizate ntr-un anumitmod mpreuncu relaiile dintre acestea.n funcie de modul de alocare, structurile de date se clasificn:
structuri de date statice: tabloul, nregistrarea, mulimea, fiierul.Structurile de date statice ocupo zonde memorie constantpetoat durata de executare a blocului n care apare declaraia ielementele ocup poziii fixe. Fiierele sunt structuri de dateexterne (vezi capitolul 1).
structuri de date semistatice: stiva alocat static, coada alocat
static. Structurile de date semistatice ocupo zonde memorie dedimensiune constat, alocatpe toatdurata executrii blocului ncare apare declaraia de structur, iar elementele ocup poziiivariabile pe parcursul executrii programului.
structuri de date dinamice: lista nlnuit, structuri arborescente.Structurile de date dinamice ocup o zon de memorie dedimensiune variabil, alocatdinamic. Alocarea dinamicpermitegestionarea memoriei n timpul executrii programului. Ele suntmult mai flexibile dect cele statice i din aceast cauz sunt
extrem de avantajoase.Liste: Olisteste o colecie de elemente de informaie (noduri)
aranjate ntr-o anumit ordine. Lungimea unei liste este numrul denoduri din list. Structura corespunztoare de date trebuie s nepermit s determinm eficient care este primul/ultimul nod nstructur i care este predecesorul/succesorul (dac exist) unui noddat. Limbajele Pascal sau C(++) ofer posibiliti de implementare aacestor structuri att static ct i dinamic. Operaiile curente care sefac n liste sunt: inserarea unui nod, tergerea (extragerea) unui nod,
concatenarea unor liste, numrarea elementelor unei liste etc.Implementarea unei liste se poate face n principal n doumoduri:
Implementarea secvenial, n locaii succesive de memorie,conform ordinii nodurilor n list. Avantajele acestei tehnicisunt accesul rapid la predecesorul/succesorul unui nod igsirea rapid a primului/ultimului nod. Dezavantajele suntinserarea/tergerea relativ complicat a unui nod i faptul cnu se folosete ntreaga memorie alocatlistei.
Implementarea nlnuit. Fiecare nod conine dou pri:informaia propriu-zis i adresa nodului succesor. Alocarea
5/28/2018 15827872 Tehnici de Programare
5/158
memoriei fiecrui nod se poate face n mod dinamic, n timpulrulrii programului. Accesul la un nod necesit parcurgereatuturor predecesorilor si, ceea ce poate lua ceva mai mult
timp. Inserarea/tergerea unui nod este, n schimb, foarterapid.Listele se pot clasifica dupnumrul de legturi n:
liste simple liste duble liste circulare
O list simpl are o singur legtur, legtura ultimului element esteadresa NIL/NULL. Pentru a accesa lista avem nevoie de o variabilcare s pstreze adresa primului element (cap sau pr i m). O list
dubl are dou legturi: legtura de tip urmtor i legtura de tipprecedent sau anterior. O lista circular este o lista n care, dupultimul nod, urmeaz primul, deci fiecare nod are succesor ipredecesor.
Listele se pot clasifica dup locul n care se fac operaiile deadugare/eliminare astfel:
stive cozi
2.1. Liste simplu nlnuite
ntre nodurile unei liste simplu nlnuite este definito singurrelaiede ordonare. Fiecare nod conine un pointer a crui valoare reprezintadresa nodului urmtor din list.
Limbajul Pascal
type lista = ^nod
nod=recordinf:tip ;urm: lista;
end;
Limbajul C(++)typedef struct nod {
tip inf;struct nod *urm;
}lista;
unde urmeste adresa urmtorului nod (pointer ctre urmtorul nod),iar i nfeste un cmp de informaie util.
Operaii asupra listei simplu nlnuite Crearea unei liste simplu nlnuite:1. Se iniializeaz pointerul pr i mcu Ni l / NULL, deoarece lista la
nceput este goal;
2. Se rezervzonde memorie n memoria heappentru nodul curent;32
5/28/2018 15827872 Tehnici de Programare
6/158
3. Se ncarcnodul curent cu date;4. Se determin adresa ultimului nod i se realizeaz legtura cu
nodul creat;
5. Se reia cu pasul 2 dacse introduce un nod nou. Inserarea unui element x al crui cmp cheie a fost iniializat n
faa unei liste nlnuiteLISTA-INSEREAZA(p,x)1: urm(x) p2: dacpNIL atunci px
Cutarea ntr-o listnlnuitp a elementului x se realizeazprin subprogramul LISTA-CAUTA i returneazpointerul la acest
obiect.LISTA-CAUTA(p,x)1. qp2. ct timp qNIL i cheie(q)x executqurm(q)3. returneazq
Probleme rezolvate1. Fiind dato listsimplu nlnuitcu elemente numere ntregi sserealizeze un program care s execute urmtoarele operaii: crearea,
parcurgerea, adugarea unui nod la nceputul listei, adugarea unui nodla sfritul listei,tergerea unui nod de pe o poziie dat.
Observaii:
Limbajul C(++)Funcia MALLOC se folosete
pentru a rezerva octei dinmemoria heap. Trebuie inclusfiierul antet: stdlib.h saualloc.h
Limbajul Pascal:Procedura NEW(pointer)- alocareadinamica memoriei pentruvariabila dinamicpointer.Procedura DISPOSE(pointer)-eliberarea memoriei ocupate dectre variabila dinamicpointer.
Rezolvare:Parcurgerea unei liste liniare simplu nlnuite se realizeaz cu unpointer care pleacde la capul listei i va referi pe rnd fiecare nod,prelucrnd informaiile din nod apoi se trece la urmtorul nod, prelu-
crm informaiile din nod etc.33
5/28/2018 15827872 Tehnici de Programare
7/158
34
tergerea unui nod de pe o poziie dat p din interiorul listei serealizeaz astfel: se parcurge lista pn la pozitia p-1, se pstreaznodul de pe poziia p, se realizeazlegtura ntre nodul p-1 i p+1 i,
apoi se elibereazmemoria ocupatde nodul p.Implementare n Pascal:
type lista=^nod;nod=recordinf:integer; urm:lista end;
var p,x:integer;cap:lista;{adresa primului nod al listei}procedureadaug(varcap:lista;x:integer); {adaugarea la sfarsitul listei}
var nou,q:lista;
beginnew(nou);nou^.inf:=x;nou^.urm:=nil;ifcap=nil thencap:=nouelse begin
q:=cap;whileq^.urm nildoq:=q^.urm;q^.urm:=nou;end;
end;
procedureadaug_inc(varcap:lista;x:integer); {adaugarea la inceput}var nou:lista;beginnew(nou);nou^.inf:=x;nou^.urm:=nil; {crearea nodului nou}ifcap=nil thencap:=nouelse begin
nou^.urm:=cap;cap:=nou;{realizarea legaturii si primul nod devine nodul creat}
end;
end;procedurelistare(cap:lista);{listarea listei}vart:lista;begin
t:=cap;whiletnil do begin
write(t^.inf,' '); {prelucrarea informatiei}t:=t^.urm; {trecerea la urmatorul nod}end;
end;proceduresterge(varcap:lista; p:integer);
5/28/2018 15827872 Tehnici de Programare
8/158
35
{stergerea nodului de pe pozitia p}var q,w,t:lista;i:integer;begin
ifcap=nil thenwriteln('Lista vida !!! ')else ifp=1 then begin
{stergere la inceputul listei}q:=cap; cap:=cap^.urm; dispose(q);end
else if(cap nil) then begint:=cap; i:=1;while(t^.urm nil) and(i+1
5/28/2018 15827872 Tehnici de Programare
9/158
36
lista* sterg_inc(lista *prim){lista *p;
p=prim;
prim=prim->urm;free(p);return prim;}
void adauga(lista*prim) {/*adauga un nod la o lista simplu inlantuitasi returneaza pointerul spre nodul adaugat sau zero daca nu s-a realizatadaugarea*/
lista *p,*q;
for (p=prim;p->urm!=NULL;p=p->urm)q=(lista*) malloc(sizeof(q));scanf("%d",&q->inf);q->urm=NULL;
p->urm=q;}
void main(){lista *prim;
prim=creare(); parcurgere(prim); prim=sterg_inc(prim);
printf("\n");parcurgere(prim); adauga(prim); parcurgere(prim);}lista *creare(){
int n,i,inf; lista *prim,*p,*q;printf("nr. de elemente");scanf("%d",&n);printf("informatia primului nod"); scanf("%d",&inf);prim=(lista*)malloc(sizeof(prim)); prim->inf=inf;prim->urm=NULL;for(q=prim,i=2;iinf=inf;p->urm=NULL; q->urm=p; q=p;}
return(prim);}void parcurgere(lista *p){
lista *q;for (q=p;q;q=q->urm) printf("%d ",q->inf);
}
5/28/2018 15827872 Tehnici de Programare
10/158
2. Inversarea legturilor ntr-o listsimplu nlnuit.
Rezolvare:
Se parcurge lista iniial folosind trei variabile dinamice p1, p2, p3care vor face referire la elementele consecutive din list. p1 va ficapul listei modificate.
Implementare Pascal:programinvers;type lista=^nod;
nod=record inf:integer; urm:lista end;var i,n,x:integer; p:lista;
procedurecreare(varp:lista; x:integer);varq:lista;beginifp=nil then beginnew(p); p^.inf:=x; p^.urm:=nil endelse begin
q:=p; whileq^.urmnil doq:=q^.urm;new(q^.urm); q^.urm^.inf:=x; q^.urm^.urm:=nil;end;
end;
procedurelistare(p:lista);varq:lista;beginq:=p; whileqnil do beginwrite(q^.inf,' '); q:=q^.urm end;end;
Subprogramul de inversare n C:l i s ta* i nver s( l i s ta*p) {
l i st a *p1, *p2, *p3;p1=p;p2=p- >ur m;
p- >ur m=NULL;whi l e ( p2) {
p3=p2- >ur m;p2- >ur m=p1;p1=p2;p2=p3;}
r et ur n p1;}
functioninversare(p:lista):lista;varp1,p2,p3:lista;beginp1:=p;
p2:=p^.urm;p^.urm:=nil;whilep2nil do begin
p3:=p2^.urm;p2^.urm:=p1;p1:=p2;p2:=p3;end;
inversare:=p1;
end;37
5/28/2018 15827872 Tehnici de Programare
11/158
38
beginread(n);fori:=1 ton do beginread(x); creare(p,x) end;
listare(p);writeln;p:=inversare(p);listare(p)
end.
3. S se efectueze suma a dou polinoame rare (polinom cu foartemuli coeficieni egali cu zero) folosind liste simplu nlnuite.
Rezolvare:
Lista are ca informaie gradul i coeficientul fiecrui termen decoeficient nenul. Pentru a calcula suma este necesar s parcurgemlistele celor doupolinoame i sadugm corespunztor n cea de-atreia list.
Implementare Pascal:typelista=^nod;
nod=recordgrad:1..5000; coef:integer; urm:lista end;var a,b,p,q,r:lista;
i,n,m:integer;procedurecreare(varp:lista);beginwrite('cati coeficienti nenuli are polinomul');readln(n);
new(p);readln(p^.coef,p^.grad);p^.urm:=nil;b:=p; {b este adresa ultimului nod}
fori:=2 ton do beginnew(a);write('coef ',i,':');readln(a^.coef); write('grad ',i,':');readln(a^.grad);
b^.urm:=a; b:=a; b^.urm:=nilendend;procedurelistare(p:lista);vara:lista;begina:=p;whileanil do beginwrite(a^.coef,'x^', a^.grad,' +'); a:=a^.urm end;writeln(#8,' ');
end;
5/28/2018 15827872 Tehnici de Programare
12/158
39
procedureaduna(p,q:lista;var r:lista);vara,b,c,d:lista;begin
a:=p;b:=q; {c este adresa ultimului nod pentru lista suma}while(anil) and (bnil) doifa^.grad=b^.grad then begin
ifr=nil then beginnew(c);c^.grad:=a^.grad;c^.coef:=a^.coef +b^.coef;r:=c; r^.urm:=nil;end
else begin
new(d); d^.grad:=a^.grad;d^.coef:=a^.coef+b^.coef;c^.urm:=d;c:=d;c^.urm:=nilend;
a:=a^.urm;b:=b^.urm;end
else ifa^.grad
5/28/2018 15827872 Tehnici de Programare
13/158
40
ifanil then c^.urm:=a;ifbnil thenc^.urm:=b;
end;
begincreare(p);creare(q);listare(p);listare(q);r:=nil;aduna(p,q,r);listare(r);readln;
end.Exerciii:1. Sse implementeze n C aplicaia de mai sus.
2. S se scrie un subprogram pentru calcularea produsului a doupolinoame rare.3. Sse calculeze valoarea unui polinom ntr-un punct dat.
Indicaie:Calcularea produsului se va face prin parcurgerea tuturor perechilor determeni astfel:-fiecare pereche genereazun nod n polinomul produs-gradul noului nod va fi suma gradelor nodurilor din pereche
-coeficientul noului nod va fi produsul coeficienilor termenilor dinpereche-se eliminnodurile din lista de termeni prin pstrarea fiecrui grad osingur dat astfel: dac exist dou noduri cu acelai grad unul dinele va fi eliminat, iar coeficientul celuilalt va avea valoarea sumeicoeficienilor celor doi termeni.
Valoarea unui polinom se va calcula prin parcurgerea listei iadugnd la valoare produsul dintre coeficient i valoarea dat laputerea gradului din nod.
4.Dndu-se dou liste simplu nlnuite cu elemente numere intregidistincte, sse afiseze diferena celor douliste i elementele comunecelor douliste.Rezolvare:
Diferena celor dou liste conine elementele primeia care nusunt n cea de-a doua. Se parcurge prima listi pentru fiecare nod severific dac este n cea de-a doua list, dac nu se afl atunci seadaug listei trei. Intersecia celor douliste se determinparcurgnd
5/28/2018 15827872 Tehnici de Programare
14/158
41
prima listi pentru fiecare nod se verificdacelementul se afli ncea de-a doua list, dacda atunci se adaugn cea de-a treia list.
Implementare Pascal:type lista=^nod;
nod = recordinf:integer; urm:lista end;var q,cap1,cap2,cap3:lista;
gasit:boolean;procedurecreare(var cap:lista);var n,i:integer;
nou,q:lista;begin
write('nr elem'); read(n); new(cap); read(cap^.inf);cap^.urm:=nil;fori:=2 to n do begin
new(nou); read(nou^.inf); nou^.urm:=nil; q:=cap;whileq^.urmnil doq:=q^.urm;q^.urm:=nouend
end;procedurediferenta(cap1,cap2:lista);
var x:integer;q2:lista;begin
q:=cap1;whileqnil do begin
x:=q^.inf; gasit:=false; q2:=cap2;whileq2nil do begin
ifq2^.inf=x thengasit:=true; q2:=q2^.urmend;
if notgasit thenwrite(x, ' '); q:=q^.urmendend;procedureafisare(cap:lista);var q:lista;begin
q:=cap;whileqnil do beginwrite(q^.inf,' '); q:=q^.urm end;writeln;
end;
5/28/2018 15827872 Tehnici de Programare
15/158
42
procedureintersectie(cap1,cap2:lista; varcap3:lista);var q,q2,nou,q3:lista;
x:integer;
beginq:=cap1;whileqnil do begin
x:=q^.inf; gasit:=false; q2:=cap2;whileq2nil do begin
if q2^.inf=x thengasit:=true;q2:=q2^.urm;end;
ifgasit then ifcap3=nil then
beginnew(cap3); cap3^.inf:=x; cap3^.urm:=nil endelse beginnew(nou); nou^.inf:=x ; nou^.urm:=nil; q3:=cap3;whileq3^.urm nil doq3:=q3^.urm;q3^.urm:=nouend;
q:=q^.urmend
end;
begincreare(cap1); creare(cap2); afisare(cap1); afisare(cap2);diferenta(cap1,cap2);writeln; diferenta(cap2, cap1);writeln('intersectie'); intersectie(cap1,cap2,cap3); afisare(cap3);end.
Exerciiu: Sse implementeze aplicaia de mai sus in C.
5. Sse creeze o listsimplu nlnuit, cu informaie numericastfelnct la orice moment al inserrii lista sfie ordonatcresctor dupinformaie.
Rezolvare:Paii: -crearea unui nod nou
-dac informaia care se adaugeste mai micdect informaiadin capul listei atunci se insereazn faa primului nod
-altfel se parcurge lista pnla primul nod a crei informaie este
mai mare dect informaia noului nod i se insereaz.
5/28/2018 15827872 Tehnici de Programare
16/158
43
Implementare C:
#include
#include #include typedefstruct nod { int inf; struct nod*urm;} lista;lista *prim;lista *creare(void);void parcurgere(lista *p);
voidmain(){lista *prim;prim=creare();
parcurgere(prim);}lista *creare(){int n,inf; lista *prim,*p,*q,*nou;printf("nr. de elemente");scanf("%d",&n);prim=NULL;for(int i=1;iinf=inf;if(prim==NULL){prim=nou;prim->urm=NULL;}
else if(prim->inf>inf){nou->urm=prim;prim=nou;}
else{p=q=prim;
while(p&&p->infurm;}if (p) {q->urm=nou; nou->urm=p;}else{q->urm=nou; nou->urm=NULL;}}
}returnprim;}voidparcurgere(lista *p){ lista *q;for(q=p;q;q=q->urm) printf("%d ",q->inf);
}
5/28/2018 15827872 Tehnici de Programare
17/158
44
Exerciiu: Sse implementeze aplicaia de mai sus n Pascal.
6. Sse scrie un program pentru interclasarea a douliste ordonate
simplu nlnuite.
Rezolvare:Se va parcurge simultan cele dou liste urmnd ca introducerea unuinod n lista final s fie fcutdin lista care are valoarea informaieidin nod mai mic.
Implementare C:#include
#include #include typedefstruct nod {int inf; struct nod*urm;}lista;lista *inter(lista *prim1, lista*prim2){lista *prim,*ultim;if(prim1->inf>prim2->inf){
prim=prim2;prim2=prim2->urm;}
else {
prim=prim1;prim1=prim1->urm;}
ultim=prim;while(prim1&&prim2)
if(prim1->inf>prim2->inf){ultim->urm=prim2;ultim=prim2;prim2=prim2->urm;
}else{ultim->urm=prim1;ultim=prim1;prim1=prim1->urm;}
if(prim1) ultim->urm=prim1; elseultim->urm=prim2;returnprim;}lista *creare(void);
void parcurgere(lista *p);
5/28/2018 15827872 Tehnici de Programare
18/158
45
voidmain(){lista *prim1,*prim2,*prim;prim1=creare();
prim2=creare();/* parcurgere(prim1) */;prim=inter(prim1,prim2);parcurgere(prim1);
}lista *creare(){
int n,inf; lista *prim,*p,*q,*nou;printf("nr. de elemente");scanf("%d",&n);prim=NULL;
for(int i=1;iinf=inf;if(prim==NULL){
prim=nou;prim->urm=NULL;}
else if(prim->inf>inf){
nou->urm=prim;prim=nou;}else {
p=q=prim;while(p&&p->infurm;}
if(p) {q->urm=nou;nou->urm=p;}else {
q->urm=nou;nou->urm=NULL;}
}}returnprim;}voidparcurgere(lista *p){ lista *q;for (q=p;q;q=q->urm) printf("%d ",q->inf);}
Exerciiu: Sse implementeze aplicaia de mai sus n limbajul Pascal.
5/28/2018 15827872 Tehnici de Programare
19/158
2.2. Liste dublu nlnuite
Pentru liste duble create dinamic modul de definire a unui nod este:
Limbajul Pascaltype lista=^nod;
nod=recordinf:tip;urm, ant:lista;
end;
typedef struct nod{inf tip;struct nod *urm;struct nod *ant;
}lista;
Operaiile care se pot defini asupra listelor dublu nlnuite suntaceleai ca i n cazul listelor simplu nlnuite:- crearea unei liste dublu nlnuite;- accesul la un element al unei liste dublu nlnuite;- inserarea unui nod ntr-o listdublu nlnuit;- tergerea unui nod dintr-o listdublu nlnuit;- tergerea unei liste dublu nlnuite.
Probleme rezolvate
1. Sse scrie un program care va conine un meniu cu principaleoperaii asupra listei dublu nlnuite.
Implementarea Pascal a soluiei:typelista=^nod;
nod=recordinf:integer; urm,ant:lista end;var cap:lista;
x:integer;
procedurecreare(varcap:lista);beginnew(cap); write('inf=');readln(cap^.inf); cap^.urm:=nil;cap^.ant:=nil;
end;procedureadaugare(varcap:lista);varq,nou:lista;beginnew(nou);readln(nou^.inf);nou^.urm:=nil;q:=cap; whileq^.urm nil doq:=q^.urm; q^.urm:=nou;nou^.ant:=q;
end;46
5/28/2018 15827872 Tehnici de Programare
20/158
47
procedureinserare(var cap:lista);var nou,q:lista;
k,i:integer;
beginwriteln('unde inserezi? ');read(k);new(nou);write('ce? ');readln(nou^.inf);ifk=1 then begin
cap^.ant:=nou; nou^.urm:=cap; nou^.ant:=nil; cap:=nou;end
else beginq:=cap;
i:=1;while(q^.urmnil) and(i
5/28/2018 15827872 Tehnici de Programare
21/158
48
ifi=k then beginq:=p; p^.ant^.urm:=p^.urm;p^.urm^.ant:=p^.ant; dispose(q);
endelse beginwrite('nu exista'); readln end
endend;procedureparcurgere(varcap:lista);varq:lista;beginq:=cap;whileqnil do beginwrite(q^.inf, ' '); q:=q^.urm end;
readlnend;procedureparcurgere_inv(varcap:lista);varq:lista;beginq:=cap;whileq^.urmnil doq:=q^.urm;whileqnil dobeginwrite(q^.inf, ' '); q:=q^.ant end;readln;
end;beginwhilex 7 do begin
writeln('1.creare'); writeln('2.adaugare');writeln('3.inserare'); writeln('4.stergere');writeln('5.parcurgere'); writeln('6.parcurgere_inv');writeln('7.iesire');readln(x);casex of
1:creare(cap);2:adaugare(cap);3:inserare(cap);4:stergere(cap);5:parcurgere(cap);6:parcurgere_inv(cap);end
endend.
5/28/2018 15827872 Tehnici de Programare
22/158
49
2. Crearea i parcurgerea listei dublu nlnuite n limbajul C:
#include
#includetypedefstructnod{int inf; struct nod*urm,*ant; } lista;lista*prim ,*ultim;voidcreare(int n);voidparcurg(lista*prim);voidparcurg1(lista*ultim);voidmain(){
int n;printf("numarul de elemente:");scanf("%d",&n);
creare(n);puts("\n Parcurgere directa");parcurg(prim);puts("\n Parcurgere indirecta");parcurg1(ultim);}
voidcreare(int n){int i;lista *p;prim=(lista*)malloc(sizeof(lista));printf("informatia primului nod"); scanf("%d",&prim->inf);
prim->urm=prim->ant=NULL;ultim=prim;for(i=2;iinf);p->ant=ultim;ultim->urm=p;p->urm=NULL;ultim=p;}
}voidparcurg(lista*p){if(p){
printf("%d ",p->inf); parcurg(p->urm);}
}voidparcurg1(lista *p){lista *q;for(q=p;q;q=q->ant) printf("%d ",q->inf);
}
5/28/2018 15827872 Tehnici de Programare
23/158
50
2.3. Liste circulare
Dupnumrul de legturi, listele circulare se mpart n: liste simple iliste duble. Listele circulare simple sunt liste simple care au n pluspropietatea cvaloarea cmpului urmtor a ultimului nod este adresacapului listei. Listele circulare duble sunt liste duble care aupropietatea c legtura urmtor a celui de-al doilea cap este primulcap i legtura anteriora primului cap este al doilea cap.
Crearea i parcurgerea listei circulare simplu nlnuite n limbajulC:
#include#include#includetypedef structnod{ int inf; structnod *urm;}lista;voidmain(){
lista *prim,*p,*q;int i,n;/*crearea listei circulare*/printf("inf primului nod");
prim=(lista*)malloc(sizeof(lista));scanf("%d",&prim->inf);prim->urm=NULL;p=prim;printf("nr de elemente");scanf("%d",&n);for(i=2;iinf);p->urm=q;p=q;}
p->urm=prim;/*parcurgerea listei*/printf("%d ",prim->inf);for(q=prim->urm;q!=prim;q=q->urm)printf("%d ",q->inf);
}
Problem rezolvat: Se d un grup de n copii aezai n cerc, caresunt numrai din m n m. Copilul care a fost numrat cu valoarea meste eliminat. Dndu-se pasul de eliminare m se cere s se precizezeordinea ieirii din cerc.
5/28/2018 15827872 Tehnici de Programare
24/158
51
Rezolvare: Simularea eliminrii copiilor se realizeaz cu o listcircular la care se realizeaz eliminarea nodului care are cainformaie numrul copilului scos din joc. Numrarea se va face
parcurgnd m elemente de la poziia de unde s-a efectuat ultimatergere.
Implementarea Pascal (Lista circulareste simpl.)typelista=^nod;
nod=recordinf:integer; urm:lista end;var i,n,m,j:integer;
prim,q,p:lista;procedurecreare(varprim:lista;x:integer);
begin new(prim); prim^.inf:=x; prim^.urm:=prim end;procedureadaugare(var prim:lista;x:integer);varq,p:lista;begin
new(q);q:=prim;whileq^.urmprim doq:=q^.urm;new(p); p^.inf:=x;q^.urm:=p;p^.urm:=prim;
end;procedurelistare(prim:lista);varq:lista;beginnew(q);q:=prim;write(q^.inf,' ');whileq^.urmprim do beginq:=q^.urm; write(q^.inf,' ') end;end;begin {program principal}
read(n); creare(prim,1);fori:=2 ton doadaugare(prim,i); listare(prim);read(m); p:=prim;fori:=1 ton-1 do begin
ifi=1 then forj:=1 tom-2 dop:=p^.urmelse forj:=1 tom-1 dop:=p^.urm;
q:=p^.urm; write(q^.inf,' '); p^.urm:=q^.urm; dispose(q);end;
writeln('castigator=',p^.inf);
end.
5/28/2018 15827872 Tehnici de Programare
25/158
52
Implementarea C (Lista circulareste dubl).#include #include
typedef structnod{int inf; structnod *urm,*ant; }lista;lista *prim,*p,*q;voidcreare(void);voidparcurgere(void);int n,m,i,k;
voidmain(){creare();printf("pasul de numarare");scanf("%d",&m);parcurgere();
while(p!=p->ant){for( i=1;iurm;printf("%d ",p->inf);p->ant->urm=p->urm;p->urm->ant=p->ant;q=p;p=p->urm;free(q);}
printf("%d",p->inf);}
voidparcurgere(){for(p=prim,i=1;iurm) printf("%d",p->inf);/* p=p->urm;*/}voidcreare(){printf("nr. de copii");scanf("%d",&n);prim=(lista*)malloc(sizeof(lista));prim->inf=1;prim->urm=prim->ant=NULL; p=prim;for(i=2; iinf=i;p->urm=q;q->ant=p;p=q;}
q->urm=prim;prim->ant=q;}
5/28/2018 15827872 Tehnici de Programare
26/158
2.4. Stive
O stiv (stack) este o list liniar cu proprietatea c operaiile de
inserare/extragere a nodurilor se fac n/din vrful listei. Ultimul nodinserat va fi i primul ters, stivele se mai numesc i listeLIFO(eng.Last In First Out) sau listepushdown.
53
Cel mai natural mod de reprezentare pentru o stiveste implementareasecvenial ntr-un tablou S[1 .. n], unde n este numrul maxim denoduri. Primul nod va fi memorat n S[1], al doilea n S[2], iar ultimuln S[top], unde top este o variabil care conine adresa (indicele)
ultimului nod inserat. Algoritmii de inserare i de tergere (extragere)a unui nod:
pop
push
functionpush(x, S[1 .. n])
{adauga nodul x in stiva}iftop=nthen returnstiva plinatoptop+1S[top]x
returnsucces
functionpop(S[1 .. n]){sterge ultimul nod inserat din stiva si il returneaza}iftop=0 then returnstiva vida
xS[top]toptop-1
returnx
Cei doi algoritmi necesit timp constant, deci nu depind de mrimea
stivei.
5/28/2018 15827872 Tehnici de Programare
27/158
54
Problem rezolvat: Realizai un meniu n limbajul Pascal care sconinoperaii asupra stivei.
Rezolvare:Implementarea Pascal:typestiva=^nod;
nod=recordinf:integer; urm:stiva end;varcap:stiva;
x:integer;procedureadauga(varcap:stiva);var nou:stiva;begin
new(nou);writeln('Ce sa adaug? ');readln(nou^.inf);nou^.urm:=nil;ifcap=nil thencap:=nou
else beginnou^.urm:=cap;cap:=nou;end;
end;proceduresterge(varcap:stiva);var q:stiva;beginifcap=nil thenwriteln('Stiva vida')
else beginq:=cap;cap:=cap^.urm;dispose(q)
end;end;procedureparcurgere(cap:stiva);var q:stiva;begin
q:=cap;whileq nil do begin
writeln('|',q^.inf,'|'); q:=q^.urm end;writeln('___')
end;
5/28/2018 15827872 Tehnici de Programare
28/158
55
beginwhilex 4 do begin
writeln('1.Adaugare');
writeln('2.Stergere');writeln('3.Listare');writeln('4.Iesire');writeln('Dati optiunea');readln(x);casex of
1:adauga(cap);2:sterge(cap);3:parcurgere(cap)
endendend.
Exerciiu: Sse implementeze n limbajul C aplicaia de mai sus.
Probleme propuse
1. Sse scrie un program care citind numere ntregi din fiierul in.txtcreeazo stivi o afieaz. Sse transforme un numr din baza
10 n baza b folosind o stiv.2. Pe o linie de cale ferat se gsesc, ntr-o ordine oarecare, n
vagoane numerotate de al 1 la n. Linia continucu alte k linii demanevr. Cunoscnd ordinea iniiala vagoanelor, sse obinlaieire vagoanele n ordine: 1,2 ,n; liniile de manevr sunt destulde lungi nct sncappe o singurlinie toate cele n vagoane.
Indicaie:Se dorete partiionarea vagoanelor n k submulimi care auvagoanele ordonate cresctor
2.5. CoziO coad(eng. queue) este o list liniar n care inserrile se fac doarn capul listei, iar extragerile doar din coada listei. Cozile se numesc ilisteFIFO(eng. First In First Out). O reprezentare secvenialpentruo coad se obine prin utilizarea unui tablou C[0 .. n-1], pe care ltratm ca i cum ar fi circular: dup locaia C[n-1] urmeaz locaiaC[0]. Fie p variabila care conine indicele locaiei predecesoare primeilocaii ocupate i fie uvariabila care conine indicele locaiei ocupateultima oar. Variabilele p i u au aceeai valoare atunci i numai
5/28/2018 15827872 Tehnici de Programare
29/158
56
atunci cnd coada este vid. Iniial, avem p= u= 0. Inserarea itergerea (extragerea) unui nod necesittimp constant.
Operaii asupra cozii:functioninsert-queue(x, C[0 .. n-1]){adauga nodul x in capul cozii}
p(p+1) modnifp=u then returncoada plinaC[p] x
returnsuccesfunctiondelete-queue(C[0 .. n-1])
{sterge nodul din coada listei si il returneaza}
if p=u then returncoada vidau(u+1) modnxC[u]
returnx
Testul de coad vid este acelai cu testul de coad plin. Dac s-arfolosi toate cele n locaii, atunci nu am putea distinge situaia decoadplina i cea de coadvid, deoarece n ambele situaii amavea p = u. Se folosesc efectiv numai n-1 locaii din cele n aletabloului C, deci se pot implementa astfel cozi cu cel mult n-1 noduri.
Problem rezolvat: Relizarea unui meniu pentru implementareastatica cozii.
Rezolvare: Cea mai simpl implementare a cozii static este folosireaunui tablou. Pentru gestionarea cozii este nevoie de douelemente: ppoziia primului element i u poziia de dup ultimul element dincoad. Se va face o utilizare circular a spaiului alocat astfel:urmtoarea poziie este p mod n +1.
Implementarea Pascal:TYPEcoada=array[1..50] of integer;varc:coada; p,n,u,o,x:integer;procedureadaugare(varc:coada; varp,u:integer;x:integer);begin
ifp(u mod n)+1 thenbeginc[u]:=x; u:=u mod n +1 end
elsewriteln('coada plina');
end;
5/28/2018 15827872 Tehnici de Programare
30/158
57
procedurestergere(varc:coada; varp,u,x:integer);beginifpu then beginx:=c[p]; p:=p mod n+1 end
elsewriteln('coada goala');end;procedurelistare(c:coada;p,u:integer);vari:integer;beginifp=u thenwriteln('coada goala')
else begini:=p;whileiu do beginwrite(c[i],' '); i:=i mod n+1 end;
end;end;begin
writeln('nr max de elem');read(n);n:=n+1;p:=1;u:=1;repeat
writeln('1..adaugare');writeln('2..stergere');
writeln('3..listare');write('citeste optiunea');readln(o);caseo of
1: beginwrite('introduceti numarul adaugat');readln(x);adaugare(c,p,u,x);end;
2: beginstergere(c,p,u,x);
ifpu thenwriteln(x);end;3: listare(c,p,u);
end;writeln;
untilo=4;end.
Exerciiu: Sse implementeze aplicaia de mai sus n limbajul C++.
5/28/2018 15827872 Tehnici de Programare
31/158
58
Problem rezolvat: S se creeze un program care s conin unmeniu cu operaii asupra unei cozi alocate dinamic.
Rezolvare:Implementarea n limbajul C++:#include #include#include // intrri-ieiri n C++typedef structnod {int inf; structnod *urm; }lista;voidadaug(lista* &prim, int x){
lista *nou, *p;nou=newlista; // crearea unui nod n C++
nou->inf=x;nou->urm=NULL;if (prim==NULL) prim=nou;else {
nou->urm=prim; prim=nou;}
}lista * creare(){
int n,x;lista*prim;
prim=NULL;clrscr();coutn;for(int i=0;i
5/28/2018 15827872 Tehnici de Programare
32/158
59
voidsterg(lista *&prim){lista *p;if(prim==NULL) couturm!=NULL){p=p->urm;}delete p->urm; p->urm=NULL;}
}void main(){
lista *prim=NULL;int opt,x;
do{ clrscr();cout
5/28/2018 15827872 Tehnici de Programare
33/158
60
Exerciiu: S se realizeze programul n Pascal corespunztoraplicaiei de mai sus.
Probleme propuse:1. Fiind dato listsimplu nlnuitavnd informaii numere ntregisse elimine numerele negative.
2. S se realizeze interclasarea a n liste simplu nlnuite ordonatecresctor.
3. Fiind date dou liste simple cu informaii de tip ntreg, s serealizeze subprograme pentru urmtoarele operaii: intersecia,reuniunea, diferena i diferena simetric a elementelor celordouliste.
4. S se scrie un program care citete cuvintele dintr-un fiier textin.txt, cuvintele sunt separate prin spaii i afieaz numrul deapariii al fiecrui cuvnt din fiier. Se vor folosi liste simplunlnuite.
5. Sse elimine dintr-o listsimplu nlnuittoate nodurile care auo informaie dat.
6. Sse realizeze operaii cu matrici rare folosind alocarea dinamica.7. Fiind dato listdubl, sse separe n douliste elementele de pe
poziii pare de elementele de pe poziii impare.
8. Fiind dato listdublcu informaii de tip ir de caractere, ssefacordonarea elementelor listei.9. Fiind dat o list dubl cu informaii de tip ntreg s se
construiasco listdublnumai cu elemente prime.10. Pe o tij sunt n bile colorate cu cel mult k culori, fiecare bil
avnd o etichetcu un numr de la 1 la n. Sse mute bilele pe altek tije, pe fiecare punnd numai bile din aceeai culoare. S seafieze bilele de pe fiecare din cele k tije, folosind structuridinamice.
Indicaie:Tija iniialreprezinto stiv, informaia dintr-un nod va ficompusdin numrul bilei i numrul culorii. Se va parcurge stiva ise adaug n stiva corespunztoare culorii, apoi se terge din stivainiial. Se va lucra cu un vector de stive pentru cele k tije.
11. Sse implementeze subprograme pentru operaiile de bazcu listecirculare duble.
12. Fie un traseu circular ce cuprinde n orae. O main trebuie sparcurg toate oraele i s se ntoarc de unde a plecat.
Parcurgerea se poate face n ambele sensuri. Se cere s se
5/28/2018 15827872 Tehnici de Programare
34/158
61
determine un traseu posibil de parcurgere astfel nct snu rmnn pan tiind c n fiecare ora exist o staie de benzin cu ocantitate de benzin suficient, iar maina consuma c litri la 100
de kilometri.13. Fiind dat o list circular dubl, s se fac un subprogram deinserare a unui element pe o poziie dat.
14. S se realizeze un subprogram care terge elementele egale cuzero dintr-o listcircular.
15. Sse creeze o listde liste, sse parcurgi sse tearg.16. S se scrie un program care citete cuvintele dintr-un text i
afieaznumrul de apariii al fiecrui cuvnt din textul respectiv.17. Sse scrie un program care citete cuvintele dintr-un text i scrie
numrul de apariie al fiecrui cuvnt, n ordinea alfabetic acuvintelor respective.18. ntr-o gar se consider un tren de marf ale crui vagoane sunt
inventariate ntr-o list. Lista conine, pentru fiecare vagon,urmtoarele date: codul vagonului, codul coninutului vagonului,adresa expeditorului, adresa destinatarului. Deoarece n gar seinverseaz poziia vagoanelor, se cere listarea datelor desprevagoanele respective n noua lor ordine.
Indicaie:se creeazo stivn care se pstreazdatele fiecrui vagon.
Datele corespunztoare unui vagon constituie un element al stivei,adicun nod al listei simplu nlnuite. Dupce datele au fost puse nstiv, ele se scot de acolo i se listeaz.
19. La o agenie CEC existun singur ghieu care se deschide la ora 8i se nchide la ora 16, dar publicul aflat la coadeste deservit ncontinuare. Deoarece la ora nchiderii coada este destul de mare seridic problema oportunitii deschiderii a nc unui ghieu laagenia respectiv. Se cunosc operaiile efectuate la agenie i
timpul lor de execuie. n acest scop se realizeaz o simulare pecalculator a situaiei existente care sstabileasco medie a orelorsuplimentare efectuate zilnic pe o perioadde un an.
Indicaie: Programul de simulare a problemei indicate construiete ocoadde ateptare cu persoanele care sosesc la agenie n intervalul detimp indicat. Se va folosi funcia randompentru a determina operaiasolicitat i apoi pentru a determina intervalul de timp ntre doupersoane care vin la agenie.
5/28/2018 15827872 Tehnici de Programare
35/158
62
20. S se realizeze un program care implementeaz subprogramepentru crearea i exploatarea unei cozi duble.
21. Se do matrice rarmemoratntr-o list. Se cere:
a) sse afieze toate elementele diferite de zero de pe diagonalaprincipal, secundar;b) sse afieze pe ecran matricea sub forma obinuit, frreconstituirea ei n memorie.
2.6. Grafuri
Noiuni introductive
Ungrafeste o pereche G= , unde Veste o mulime de vrfuri,
iar M= VxV este o mulime de muchii. O muchie de la vrful a lavrful b este notat cu perechea ordonat (a, b), dac graful esteorientat, i cu mulimea {a, b}, dac graful este neorientat. Douvrfuri unite printr-o muchie se numesc adiacente. Un drum este osuccesiune de muchii de forma (a1, a2), (a2, a3), ..., (an-1, an) sau deforma {a1, a2}, {a2, a3}, ..., {an-1, an} dupcum graful este orientat sauneorientat.Lungimeadrumului este egalcu numrul muchiilor care lconstituie. Un drumsimplu este un drum n care nici un vrf nu serepet. Un ciclueste un drum care este simplu, cu excepia primului i
ultimului vrf, care coincid. Un grafaciclic este un graf fr cicluri.Un subgraf al luiG este un graf , unde V'V, iar M' esteformatdin muchiile dinMcare unesc vrfuri din V'. Ungraf parialeste un graf
5/28/2018 15827872 Tehnici de Programare
36/158
uneori valori, iar muchiilor li se pot ataa informaii numite uneorilungimisau costuri.
Metode de reprezentare a grafurilora) Matricea de adiacen
Cea mai cunoscutmetodde memorare a grafurilor neorientate estematricea de adiacen, definitn felul urmtor: 1, dacexistmuchie(arc) de la vrful i la vrful j i 0, n caz contrar. n cazul grafurilorneorientate, aceastmatrice este simetric, folosindu-se efectiv numaijumtate din spaiul matricei. n unele probleme este eficient cacealalt jumtate a matricei s fie folosit pentru reinerea altor
informaii. Matricea de adiaceneste folositn general pentru grafuricu un numr mic de noduri, deoarece dimensiunea ei este limitatdedimensiunea stivei.
Exemplu de graf orientat:
0 0 1 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
0
1
2
3
4
7
5
6
0
0
0
0
0
1
0
0
8
0 0 0 0 0 0 0 08 0
1
4
5
6
3
2
8
7
0
b) Listele de muchii
Aceast metod de memorare presupune reinerea unei matrice cu 2linii i m coloane, pe fiecare coloanfiind reinute douextremiti aleunei muchii. Aceasta reprezentare este eficientatunci cnd avem de
examinat toate muchiile grafului.63
5/28/2018 15827872 Tehnici de Programare
37/158
64
Listele de muchii sunt folosite n cazul algoritmilor care prelucreazsecvenial muchiile, cum ar fi de exemplu algoritmul Kruskalde aflarea arborelui parial de cost minim n cazul grafurilor rare (cu numr
mic de muchii).
c) Listele de vecini.
Prin liste de vecini (adiacen) se realizeazataarea la fiecare vrf i alistei de vrfuri adiacente lui (pentru grafuri orientate, este necesar camuchia s plece din i). ntr-un graf cu m muchii, suma lungimilorlistelor de adiaceneste 2m, dacgraful este neorientat, respectiv m,dac graful este orientat. Dac numrul muchiilor n graf este mic,
aceast reprezentare este preferabildin punct de vedere al memorieinecesare. Este posibil sexaminm toi vecinii unui vrf dat, n medie,n mai puin de n operaii. Pe de alt parte, pentru a determina dacdouvrfuri i i j sunt adiacente, trebuie sanalizm lista de adiacena lui i (i, posibil, lista de adiacen a lui j), ceea ce este mai puineficient dect consultarea unei valori logice n matricea de adiacen.
Listele de vecini sunt cele mai recomandate n tratarea algoritmilor dinteoria grafurilor din doumotive principale:1. spatiul folosit este gestionat dinamic, putndu-se memora astfel
grafuri de dimensiuni mari;2. complexitatea optim pentru majoritatea algoritmilor fundamen-tali din teoria grafurilor (parcurgeri, conexitate, muchii i punctecritice, algoritmi de drum minim etc.) este obinutnumai folosindliste de vecini.
Existdoumodaliti de implementare a listelor de vecini.a) Prima dintre ele folosete o matriceT cu 2 linii i 2m coloane i
un vector C cu n elemente care reine pentru fiecare nod indicelecoloanei din T pe care este memorat primul element al listeinodului respectiv (sau 0 dacvrful respectiv nu are vecini). Apoi,pentru o anumitcoloani din T, T(i,1) reine un element din listacurent, iar T(i,2) reine coloana pe care se gsete urmtorulelement din lista respectivsau 0 daclista s-a terminat.
b) Cea de-a doua implementare folosete pentru fiecare nod o listsimplu nlnuit memorat n heap. Pentru fiecare list estesuficient s pstrm o singur santinel (cea de nceput a listei),introducerea vrfurilor fcndu-se mereu la nceputul listei(deoarece ordinea vrfurilor n listnu conteaz).
5/28/2018 15827872 Tehnici de Programare
38/158
Exemplu:
65
1
4
5
6
3
2
8
7
0
0
1
2
3
4
7
5
6
8
2 5
6
6
4
5
3 7
2 8
Parcurgerea grafurilor
Parcurgerea unui graf presupune examinarea n vederea prelucrrii
tuturor vrfurilor acelui graf ntr-o anumit ordine, ordine care spermitprelucrarea optima informaiilor ataate grafului.
a) Parcurgerea DF (parcurgerea n adncime)
Parcurgerea DF (Depth First) presupune ca dintr-un anumit nod v,parcurgerea s fie continuat cu primul vecin al nodului v nevizitatnc. Parcurgerea n adncime a fost formulatcu mult timp n urmca o tehnicde explorare a unui labirint. O persoancare cautcevantr-un labirint i aplicaceasttehnicare avantajul ca urmtorul locn care caut este mereu foarte aproape.
Parcurgerea vrfurilor n adncime seface n ordinea: 1 3 4 5 2 61
4
56
3
2
Cel mai cunoscut mod de imple-mentare a parcurgerii DF se realizeazcu ajutorul unei funcii recursive, darexisti cazuri n care este recomandato implementare nerecursiv.
Implementarea acestei metode se
face folosind o stiv. Aceasta este iniia-
5/28/2018 15827872 Tehnici de Programare
39/158
66
lizatcu un nod oarecare al grafului. La fiecare pas, se ia primul vecinnevizitat al nodului din vrful stivei i se adaugn stivdacnu maiexistse coboarn stiv.
Algoritmul recursiv:procedureDF(G)
forfiecare vVdomarca[v] nevizitatfor fiecare vVdo
if marca[v] = nevizitat then ad(v)
proceduread(v){varful v nu a fost vizitat}
marca[v] vizitatforfiecare virf w adiacent lui v doifmarca[w] = nevizitat then ad(w)
Algoritmul iterativ:
procedure iterad(v)Sstiva vidamarca[v] vizitat
push(v, S)while Snu este vida do
whileexista un varf w adiacent luiftop(S)astfel incat marca[w] = nevizitat do
marca[w] vizitatpush(w, S)
pop(S)
unde funciaftopreturneazultimul vrf inserat n stiv.Parcurgerea n adncime a unui graf nu este unic; ea depinde
att de alegerea vrfului iniial, ct i de ordinea de vizitare avrfurilor adiacente.
Problem: Ct timp este necesar pentru a parcurge un graf cu nvrfuri i m muchii?
Rezolvare:Deoarece fiecare vrf este vizitat exact o dat, avem n apeluri aleprocedurii ad. n procedura ad, cnd vizitm un vrf, testm marcajulfiecrui vecin al su. Dac reprezentm graful prin liste de adiacen,adic prin ataarea la fiecare vrf a listei de vrfuri adiacente lui,
atunci numrul total al acestor testri este m, dacgraful este orientat,
5/28/2018 15827872 Tehnici de Programare
40/158
67
i 2m, dac graful este neorientat. Algoritmul necesit un timp O(n)pentru apelurile procedurii ad i un timp O(m) pentru inspectareamrcilor. Timpul de executare este O(max(m, n)) =O(m+n).
Dacreprezentm graful printr-o matrice de adiacen, se obineun timp de executare de O(n2).
b) Parcurgerea BF (parcurgerea n lime)
Parcurgerea BF (Breath First) presupune faptul cdupvizitarea unuianumit nod v, sunt parcuri toi vecinii nevizitai ai acestuia, apoi toivecinii nevizitai ai acestora din urm, pn la vizitarea tuturor nodu-rilor grafului.
Parcurgerea n lime este folosit de obicei atunci cnd se
exploreazparial anumite grafuri infinite, sau cnd se caut cel maiscurt drum dintre douvrfuri.
Implementarea acestei metode se face folosind o coad. Aceastaeste iniializat cu un nod oarecare al grafului. La fiecare pas, seviziteaznodul aflat n vrful cozii i se adaug n coad toi veciniinevizitai ai nodului respectiv.
Parcurgere_BF(nod start)Coada start
Vizitat(start) adevratct timp coada nu este vid
ic nodul de la nceputul coziiadaugtoti vecinii nevizitati ai luiic n coadVizitat(i) adevrat, unde i este un vecin nevizitat al
nodului ic
Pentru a efectua o parcurgere n laime a unui graf (orientat sauneorientat), aplicm urmtorul principiu: atunci cnd ajungem ntr-un
vrf oarecare v nevizitat, l marcm i vizitm apoi toate vrfurilenevizitate adiacente lui v, apoi toate vrfurile nevizitate adiacentevrfurilor adiacente lui v etc. Spre deosebire de parcurgerea nadncime, parcurgerea n lime nu este n mod natural recursiv.
procedure lat(v)Ccoada vidamarca[v] vizitatinsert-queue(v, C)
5/28/2018 15827872 Tehnici de Programare
41/158
68
while Cnu este vida dou delete-queue(C)for fiecare virf w adiacent lui u do
if marca[w] = nevizitat then marca[w] vizitatinsert-queue(w, C)Pentru compararea celor doumetode apelm procedurile iterad i latdin procedura parcurgere(G)
procedureparcurge(G)for fiecare v Vdo marca[v] nevizitatfor fiecare v Vdo
if marca[v] = nevizitat then {iterad sau lat} (v)
Aplicaia 2.6.1:Algoritmul lui Dijkstra
Fie G = (X,U) un graf orientat, unde X este mulimea vrfurilor i Ueste mulimea muchiilor. Fiecare muchie are o lungime nenegativ.Unul din vrfuri este desemnat ca vrf surs. Problema este sdeterminm lungimea celui mai scurt drum de la surs ctre fiecarevrf din graf. Vom folosi un algoritmgreedy, datorat lui E.W. Dijkstra(1959). Notm cu C mulimea vrfurilor disponibile (candidaii) i cuS mulimea vrfurilor deja selectate. n fiecare moment, S conineacele vrfuri a cror distanminimde la surseste deja cunoscut,n timp ce mulimea C conine toate celelalte vrfuri. La nceput, Sconine doar vrful surs, iar n final S conine toate vrfurile grafului.La fiecare pas, adugam n S acel vrf din C a crui distan de lasurseste cea mai mic.
La fiecare pas al algoritmului, un tablou D conine lungimeacelui mai scurt drum special ctre fiecare vrf al grafului. Dup ceadugm un nou vrf v la S, cel mai scurt drum special ctre v va fi,de asemenea, cel mai scurt dintre toate drumurile ctre v. Cnd
algoritmul se termin, toate vrfurile din graf sunt n S, deci toatedrumurile de la sursctre celelalte vrfuri sunt speciale i valorile dinD reprezintsoluia problemei.
Matricea M dlungimea fiecarei muchii, cu M[i, j] =+, dacmuchia (i, j) nu exist. Soluia se va construi n tabloul D[2 .. n].
Algoritmul este:
S = {0}
for i = 1 to n D[i] = M[1][i]
5/28/2018 15827872 Tehnici de Programare
42/158
69
for i = 1 to n-2caut cel mai mic D[v] pentru fiecare v SS = S {v}
fortoate vrfurile u Sif(D[u] > D[v] + M[v][u]) thenD[u] = D[v] + M[v][u]
Implementare n C:
#include#include#defineFALSE 0#defineTRUE 1
#define MAXN 20intsetupDijkstra(int *nod_p, inta[MAXN][MAXN], int *startnod_p);
voiddoDijkstra(intnod, inta[MAXN][MAXN], intstartnod);
voidtraceinfo(intS[MAXN], intD[MAXN], intnod);
intmain(){intnod, startnod;
inta[MAXN][MAXN];printf("Algoritmul lui Dijkstra\n");if(setupDijkstra(&nod, a, &startnod)) return1;doDijkstra(nod, a, startnod);return0;
}intsetupDijkstra
(int *nod_p, inta[MAXN][MAXN], int *startnod_p){inti, j;
do{printf("Introduceti 0 pentru a specifica graful,sau 1 pentru exemple ");scanf("%d", &i);}while((i < 0) || (i > 1));
if(i == 1){*nod_p = 5;for(i=0; i
5/28/2018 15827872 Tehnici de Programare
43/158
70
printf("A Matrix: a b c d e\n");for (i=0; i
5/28/2018 15827872 Tehnici de Programare
44/158
71
if(urmnod >= nod) return;// printf(" D[%c]=%2d, ", 'a'+urmnod, mic);printf("adauga nodul %c to S\n", 'a'+urmnod);
S[urmnod] = TRUE;for(j=0; j D[urmnod] + a[urmnod][j]){
D[j] = D[urmnod] + a[urmnod][j];
/*printf("D[%c] schimba %2d\n", 'a'+j, D[j]); */}else
/* printf("nu schimba\n"); */}
}traceinfo(S, D, nod);}
}
voidtraceinfo(intS[MAXN], intD[MAXN], intnod){inti;printf(" S = {");for(i=0; i
5/28/2018 15827872 Tehnici de Programare
45/158
72
vom folosi vectorulD care reine distana minimgsitla un momentdat de la s la celelalte noduri. Algoritmul foloseste o coad Q, careeste iniializatcu nodul s. La fiecare pas, algoritmul scoate un nod v
din coad i gsete toate nodurile w a cror distan de la surs laacestea poate fi optimizatprin folosirea nodului v. Dacnodul wnuse afl deja n coad, el este adugat acesteia. Aceti pai se repetpncnd coada devine vid.
Algoritmul utilizeaz tehnica de relaxare, procednd ladescreterea estimrii d[v] a drumului minim de la sursa s la fiecarevrf v V pncnd este obinut costul adevrat (u,v) corespunztorunui drum minim. Algoritmul returneazadevarat daci numai dacnu conine cicluri de cost negativ accesibile din surs.
Algoritmul este:BELLMAN-FORD(G,c,s)1.INIT(G,s)2. pentru i1,|X[G]|-1 executa
3. pentru fiecare muchie (u,v) U4. RELAXEAZA(u,v,c)5. pentru fiecare muchie (u,v) U executa6. daca d[v]>d[u]+c(u,v)7. returneaza FALS
8. returneaza ADEVARATImplementare n C:
#include#include#defineFALSE 0#defineTRUE 1#define MAXN 26#defineINFINIT 999intsetupBellman(int*nod_p, inta[MAXN][MAXN], int *start_p);intdoBellman(intnod, inta[MAXN][MAXN], intstart);voidtraceinfo(intD[MAXN], intnod);intmain(){
intnod, start; inta[MAXN][MAXN];printf("Algoritmul lui Bellman-Ford\n");if(setupBellman(&nod, a, &start)) return1;if(doBellman(nod, a, start)){
printf(" Ciclu negativ\n"); return2;}
return0;}
5/28/2018 15827872 Tehnici de Programare
46/158
73
intsetupBellman(int *nod_p, inta[MAXN][MAXN], int *start_p){
inti, j;
do{printf("Introduceti 0 pentru graf, or 1 pentru exemple ");scanf("%d", &i);
}while((i < 0) || (i > 1));if(i == 1){
*nod_p = 5;for(i=0; i
5/28/2018 15827872 Tehnici de Programare
47/158
74
for(i=0; i
5/28/2018 15827872 Tehnici de Programare
48/158
75
Probleme rezolvate
R2.6.1. Sse afieze componentele conexe folosind parcurgerea DF a
grafului. Graful este reprezentat prin matricea de adiacencititdinfiier TEXT.
Rezolvare: Implementarea Pascal folosind parcurgerea DF recursiv:var a:array[1..100,1..100] of integer;
viz:array[1..100] of integer;f:text;n,i,j:integer;
proceduredf(X:integer);vari:byte;
beginwrite(x, ' ');viz[x]:=1;fori:=1 ton doif(a[x,i]=1) and(viz[i]=0) thendf(i);end;
procedurecitire;begin
assign(f,'matrice.txt');reset(f);
readln(f,n);fori:=1 to n do beginforj:=1 ton doread(f,a[i,j]);readln(f);end;
end;begin
citire;fori:=1 ton doviz[i]:=0;
fori:=1 ton do ifviz[i]=0 then begindf(i);writeln end;end.
Exerciiu:Implementai n lumbajul C aplicaia de mai sus folosind funcia Df(iterativ) de mai jos.
voiddf(int x){inti,k,y,s[10],gasit;
k=1;
5/28/2018 15827872 Tehnici de Programare
49/158
76
s[1]=x;viz[x]=1;printf("%d ",x);while(k>=1) /*cat timp stiva este nevida */ {
y=s[k];gasit=0;
for(i=1;i
5/28/2018 15827872 Tehnici de Programare
50/158
77
whilep
5/28/2018 15827872 Tehnici de Programare
51/158
78
write('componenta tare conexa ',k,':',i,' ');forj:=1 ton do
if(ji) and(a[i,j]0)and(a[j,i]0) then
beginwrite(j,' ');m[j]:=true;end;
inc(k);writeln;end;
end.
Implementare n limbajul C:
#includeintn, a[10][10],viz[10];voidcitire(){
intm,i,j,x,y;printf("n=");scanf("%d",&n); printf("m=");scanf("%d",&m);for(i=1;i
5/28/2018 15827872 Tehnici de Programare
52/158
79
R2.6.4. Dndu-se dou grafuri reprezentate prin matricea de adia-cen sse precizeze daccel de-al doilea graf este graf parial sau
subgraf al primului graf.
Rezolvare:Implementarea Pascal este:usescrt;typemat=array[1..100,1..100] ofinteger;var a,b:mat;
n,m,n1,m1,i,j:integer;procedurecreare;varx,y,i,j:integer;
beginwriteln(' MARTICEA 1');write('Dati numarul de varfuri');readln(n);write('Dati numarul de muchii');readln(m);fori:=1 ton doforj:=1 ton doa[i,j]:=0;fori:=1 tom do begin
write('Dati primul capat al muchiei ',i,' : ');
readln(x);write('Dati al doilea capat al muchiei ',i,' : ');readln(y);a[x,y]:=1; a[y,x]:=1end
end;procedurecreare1;varx,y,i,j:integer;begin
WRITELN(' MATRICEA 2');write('Dati numarul de varfuri');readln(n1);write('Dati numarul de muchii');readln(m1);fori:=1 ton1 doforj:=1 ton1 dob[i,j]:=0;fori:=1 tom1 do begin
write('Dati primul capat al muchiei ',i,' : '); readln(x);write('Dati al doilea capat al muchiei ',i,' : '); readln(y);b[x,y]:=1;b[y,x]:=1;end;
end;
5/28/2018 15827872 Tehnici de Programare
53/158
80
proceduresubgraf;vars:boolean;begin
s:=true;if n1>n thens:=false;fori:=1 ton1 do forj:=1 ton1 doif(a[i,j]=1) and(b[i,j]=0) thens:=false;
ifs=false thenwriteln(' B nu e subgraf al lui A.')elsewriteln(' B e subgraf al lui A.');
end;proceduregraf_p;varg:boolean;begin
g:=true;ifn n1 theng:=false;fori:=1 ton doforj:=1 ton doif(a[i,j]=0) and(b[i,j]=1) theng:=false;
ifg=false thenwriteln(' B nu e graf partial al lui A.')elsewriteln(' B e graf partial al lui A.');
end;begin
clrscr;creare;creare1;
graf_p;subgraf;end.Exerciiu: Sse implementeze aplicaia de mai sus n limbajul C.
R2.6.5.Determinarea drumurilor minime ntre oricare dounoduri.
Rezolvare: Se folosete algoritmul lui ROY-FLOYD. Se pornete dela matricea costurilor C.
pentruk=1,n execut
pentrui=1,n executpentruj=1,n executc[i,j]=min(c[i,j],c[i,k]+c[k,j])
Simultan cu determinarea lungimilor minime ale drumurilor pot fireinute drumurile folosind un tablou d, unde d[i,j] reprezint muli-mea predesesorilor lui j pentru drumul minim de la i la j.
Implementare Pascal:Var c:array[1..100,1..100] of longint; v:array[1..100]of integer;
d:array[1..100,1..100] of set of 1..10;
n,m,i,j,k,nr:integer; x,y:integer;
5/28/2018 15827872 Tehnici de Programare
54/158
81
procedurecitire;varcost,x,y:integer;begin
write('nr. de noduri');readln(n);write('nr. de muchii');readln(m);for i:=1 ton do
forj:=1 ton do ifij thenc[i,j]:=maxint elsec[i,j]:=0;fori:=1 to m do begin
write('Dati capetele arcului si costul ');readln(x,y,cost); c[x,y]:=cost;end;
end;
procedureinitializare;{determina multimea predecesorilor, initializeaza multimea D}beginfori:=1 to n do
forj:=1 ton doif(ij) and(c[i,j]c[i,k]+c[k,j] thenbeginc[i,j]:=c[i,k]+c[k,j]; d[i,j]:=d[k,j] end
else ifc[i,j]=c[i,k]+c[k,j] thend[i,j]:=d[i,j]+d[k,j];
5/28/2018 15827872 Tehnici de Programare
55/158
82
fori:= 1 ton do beginforj:=1 ton dowrite(c[i,j]:4);writeln
end;write('Dati doua noduri'); readln(x,y);writeln('costul minim= ', c[x,y], ' drumurile minime=' );forx:=1 ton do fory:=1 ton do
beginwriteln('drum de la ',x,'la ',y);ifc[x,y]=maxint thenwrite('nu exista')
else beginnr:=1;v[1]:=y;
drum(x,y)endend
end.
Exerciiu: Sse implementeze algoritmul Roy-Floyd n limbajul C.
R2.6.6. Sse verifice dacun graf reprezentat dinamic este conex saucomplet.
Rezolvare:Se folosete un tablou de liste unde bl[i]reprezintlista vecinilor lui i.
Implementare Pascal:
typelista=^nod;nod= recordinf:integer; urm:lista end;
var bl:array[1..100] oflista;f:text;i,n,x:integer;complet:boolean;
procedureadaugare (varp:lista;x:integer);var t,q:lista;begin
new(q);q^.inf:=x;q^.urm:=nil;ifp=nil thenp:=q
else begint:=p;whilet^.urmnil dot:=t^.urm;t^.urm:=q;end;
end;
5/28/2018 15827872 Tehnici de Programare
56/158
83
procedurelistare(p:lista);vart:lista;begin
t:=p;whilet nil do beginwrite(t^.inf,' ');t:=t^.urmend;
writeln;end;proceduredf(i:integer);var q,t,st:lista;
viz:array[1..100] ofinteger;conex,gasit:boolean;j:integer;
beginforj:=1 ton doviz[j]:=0;viz[i]:=1;write(i,' ');new(q);q^.inf:=i;q^.urm:=nil;st:=q;whilestnil dobegin
x:=st^.inf; t:=bl[x]; gasit:=false;whilet nil do begin
ifviz[t^.inf]=0 then beginnew(q); q^.inf:=t^.inf; q^.urm:=nil; viz[t^.inf]:=1;write(t^.inf,' '); q^.urm:=st; gasit:=true; st:=q; break;end;
t:=t^.urm;end;
ifnotgasit then begint:=st; st:=st^.urm; dispose(t) end;end;
conex:=true;
forj:=1 ton do ifviz[j]=0 thenconex:=false;ifconex thenwrite('conex') elsewrite('nu este conex');end;functionnumarare( p:lista):integer;var nr:integer; t:lista;begin
nr:=0;t:=p;whiletnil do beginnr:=nr+1; t:=t^.urm end;numarare:=nr
end;
5/28/2018 15827872 Tehnici de Programare
57/158
84
beginassign(f,'in.txt');reset(f);readln(f,n);
fori:=1 ton do beginwhile noteoln(f) do beginread(f,x);adaugare(bl[i],x)end;
readln(f);end;
writeln;df(1);
complet:=true;fori:=1 ton do ifnumarare(bl[i])n-1 thencomplet:=false;ifcomplet thenwrite('complet') elsewrite ('incomplet');
end.Exerciiu: Sse implementeze aplicaia de mai sus n limbajul c.
R2.6.7.Fiind dat un graf, sse verifice daceste aciclic.Rezolvare:
Un graf este aciclic daceste frcicluri. Presupunem c fiecare nod
face parte dintr-o component conex. Se ia fiecare muchie i dacextremitile sunt n aceeai component conex atunci adugndaceea muchie se formeazciclu; dacnu sunt n aceeai componentconextoate nodurile care sunt n aceeai componentcu extremitateaa doua trec n componenta conexa extremitii 1.
Implementare Pascal:Var f:text;
a:array[1..1000]ofinteger; n:integer; nume:string;procedureciclic;
vari,j,k:integer;beginwriteln('Care este numele fisierului de intrare ?');readln(nume);assign(f,nume); reset(f);readln(f,n);fori:=1 ton doa[i]:=i;whilenotseekeoln(f) do
begin
readln(f,i,j);
5/28/2018 15827872 Tehnici de Programare
58/158
85
ifa[i]=a[j] thenbeginwriteln('Graful din fisierul ',nume,' contine cel putin un ciclu');
close(f); halt;end;fork:=1 ton do ifa[k]=a[j] thena[k]:=a[i];end;writeln('Graful din fisierul ',nume,' nu contine cicluri');close(f);
end;begin
ciclic
end.Implementare C:
#include#include#include#includeFILE*f;intn,a[10];
voidciclic(){inti,j,k;fscanf(f,"%d",&n);for(i=1;i
5/28/2018 15827872 Tehnici de Programare
59/158
86
R2.6.8. Se dun graf i un nod - considerat ca nodul nr. 1; secere sse determine toate nodurile accesibile din acest nod.
Rezolvare:
Implementare Pascal:var
a: array[1..20,1..20] ofinteger; {matricea de adiacenta}c: array[1..20] ofinteger;{vectorul unde pastram nodurile accesibile}n,i,j,k,p:integer; gasit:boolean;
beginwrite('dati numarul de noduri; n=');readln(n);
writeln('dati matricea de adiacenta:');fori:=1 ton doforj:=1 ton doread(a[i,j]);c[1]:=1; k:=1; gasit:=true; i:=1;whilei
5/28/2018 15827872 Tehnici de Programare
60/158
87
fori:=1 ton doforj:=1 ton doa[i,j]:=0;while noteof(f) do begin
readln(f,i,j);
a[i,j]:=1; a[j,i]:=1end;fori:=1 ton-2 do forj:=i+1 ton-1 do
fork:=j+1 ton doif(a[i,j]=1) and(a[j,k]=1) and(a[k,i]=1) thenwriteln(i,' ',j,' ',k);
end.
2.7. Arbori
Fie Gun graf orientat. Geste un arbore cu radacina r, dacexistn
Gun vrf rdin care oricare alt vrf poate fi ajuns printr-un drum unic.Adncimeaunui vrf este lungimea drumului dintre rdcina iacest vrf; nlimea unui vrf este lungimea celui mai lung drumdintre acest vrf i un vrf terminal.nlimeaarboreluieste nalimeardcinii; nivelul unui vrf este nlimea arborelui minus adncimeaacestui vrf.
Reprezentarea unui arbore cu rdcinse poate face prin adrese,ca i n cazul listelor nlnuite. Fiecare vrf va fi memorat n treilocaii diferite, reprezentnd informaia propriu-zisa vrfului (valoa-
rea vrfului), adresa celui mai vrstnic fiu i adresa urmtorului frate.Pstrnd analogia cu listele nlnuite, dac se cunoate de la nceputnumrul maxim de vrfuri, atunci implementarea arborilor cu rdcinase poate face prin tablouri paralele.
Dac fiecare vrf al unui arbore cu rdacin are pn la n fii,arborele respectiv este n-ar.
ntr-un arbore binar, numrul maxim de vrfuri de adncime keste 2k. Un arbore binar de nlime i are cel mult 2i+1-1 vrfuri, iardac are exact 2i+1-1 varfuri, se numeste arbore plin. Vrfurile unui
arbore plin se numeroteazn ordinea adncimii.Un arbore binar cu n vrfuri i de nlime ieste complet, dacse obine din arborele binar plin de nlime i, prin eliminarea, daceste cazul, a vrfurilor numerotate cu n+1, n+2, , 2i+1-1. Acest tip dearbore se poate reprezenta secvenial folosind un tablou T, punndvrfurile de adncime k, de la stnga la dreapta, n poziiile T[2k],T[2k+1], , T[2k+1-1] (cu posibila excepie a nivelului 0, care poate fiincomplet). Un arbore binar este un arbore n care fiecare vrf are celmult doi descendeni, fcndu-se distincie ntre descendentul stng i
descendentul drept al fiecrui vrf.
5/28/2018 15827872 Tehnici de Programare
61/158
Reprezentarea arborilor binariReprezentarea prin paranteze: se ncepe cu rdcina arborelui, iarfiecare vrf care are descendeni este urmat de expresiile ataatesubarborilor care au ca rdcindescendenii vrfului, desprite prinvirgul i cuprinse ntre paranteze. Dac lipsete un descendent sub-expresia corespunztoare este cuvntul vid. Pentru arborele de maisus, reprezentarea este: 6(2(1,(4(3,5)), 8(7, 9(,10)))Reprezentarea standard: n care pentru fiecare vrf i este precizat des-cendentul su stng ST(i) descendentul su drept DR(i) = i informaiaasociatv`rfului INF(i):
static:ST i DR sunt doutablouri ST=(0, 1, 0, 3, 0, 2, 0,7, 0, 0)DR=(0, 4, 0, 5, 0, 8, 0, 9,10,0) rad=6
dinamic:
type arbore=^nod;nod=record
inf:integer;
st,dr:arbore;end;
typedef struct nod{int inf;struct nod *st;
struct nod *dr;}arbore;si se declara arbore *rad;
Reprezentarea cu doi vectori DESC i TATA: n vectorul DESC,avnd valori 1, 1,0 se precizeaz pentru fiecare nod ce fel dedescendent este el pentru printele su iar n vectorul TATA se indicpentru fiecare vrf, nodul printe. Pentru exemplul de mai sus:
TATA=(2,6,4,2,4,0,8,6,8,9) DESC=(-1,-1,-1,1,1,0,-1,1,1,1)
88
5/28/2018 15827872 Tehnici de Programare
62/158
89
Parcurgerea arborilor binari
preordine:se viziteaz rdcina, se traverseaz subarborele stngn preordine, se traverseazsubarborele drept n preordine;
inordine: se traverseaz subarborele stng n inordine, seviziteazrdcina, se traverseazsubarborele drept n inordine;
postordine: se traverseaz subarborele stng n postordine, setraverseaz subarborele drept n postordine, se traverseazrdcina.
Aplicaia 2.7.1.Sse creeze un arbore binar i apoi sse parcurgnpreordine, s se caute un nod n arbore, sse afieze cheile de pe unanumit nivel dat, sse afieze drumurile de la rdcinla frunze i s
se calculeze adncimea arborelui creat.Rezolvare:
Implementare Pascal:programarb_binar;type arbore=^nod;
nod =recordst,dr:arbore; inf:integer end;varp:arbore;k,x,y,max,z:integer;a:array[1..100] ofinteger;{Procedura creare arbore binar}
procedurecreare(varp:arbore);varx:integer;begin
read(x);ifx=0 thenp:=nil
else beginnew(p); p^.inf:=x;write('Dati stanga lui ',x); creare(p^.st);write('Dati dreapta lui ',x); creare(p^.dr);
end;end;{Procedura parcurgere arbore binar - prin preordine}procedurepreordine(p:arbore);beginifpnil then begin
write(p^.inf,' ');preordine(p^.st); preordine(p^.dr);end;
end;
5/28/2018 15827872 Tehnici de Programare
63/158
90
{Cautarea unui nod din arbore}functioncautare(p:arbore; x:integer):boolean;begin
ifp=nil thencautare:=falseelse ifx=p^.inf thencautare:=trueelsecautare:= cautare(p^.st,x) orcautare(p^.dr,x);
end;{Afisarea tuturor cheilor de pe nivelul dat}procedurenivel(p:arbore;k,x:integer);beginifpnil then begin
ifk=x thenwrite(p^.inf,' ');
nivel(p^.st,k+1,x);nivel(p^.dr,k+1,x);end;
end;{Drumurile de la radacina la frunze}proceduredrum_frunze(p:arbore;k:integer);vari:integer;beginif(p^.st=nil)and(p^.dr=nil) then begin
a[k]:=p^.inf;fori:=1 tok dowrite(a[i],' ');writelnend
else ifpnil then begina[k]:=p^.inf;drum_frunze(p^.st,k+1);drum_frunze(p^.dr,k+1);end;
end;{Afisarea numarului maxim de nivele}procedureadancime(p:arbore;k:integer; varmax:integer);beginifpnil then begin
ifk>max thenmax:=k;adancime(p^.st,k+1,max);adancime(p^.dr,k+1,max);end
end;
5/28/2018 15827872 Tehnici de Programare
64/158
91
begincreare(p);preordine(p);
{Pentru procedura cautare}read(x);writeln(cautare(p,x));{Pentru procedura nivel}write('Nivelul= ');read(y);nivel(p,0,y);{Pentru procedura drum_frunze}drum_frunze(p,1);{Pentru procedura adancime}adancime(p,0,max);
writeln('Numarul de nivele este: ',max);end.
Implementare n C++ :
#include #include #include #includetypedef struct nod{
intinf;structnod *st, *dr;}arbore;
arbore *rad;inta[10], max=0;arbore *creare(){intx;arbore *p;coutx;if(x==0) returnNULL;
else{ (p)=(arbore*) malloc(sizeof(arbore)); (p)->inf=x;cout
5/28/2018 15827872 Tehnici de Programare
65/158
92
voidinordine(arbore *p){if(p){
inordine(p->st); printf("%d",p->inf); inordine(p->dr);
}}voidpostordine(arbore *p){if (p){
postordine(p->st); postordine(p->dr); printf("%d",p->inf);}
}intcautare(arbore *p, intx){if(p){
if(p->inf==x) return1;returncautare(p->st,x)||cautare(p->dr,x);}
else return0;}voidnivel(arbore*p, int k,int x){if(p){
if (k==x) printf("%d ",p->inf);nivel(p->st,k+1,x); nivel(p->dr,k+1,x);
}}voiddrum_frunze(arbore*p,int k){inti;
if((p->st)&&(p->dr)) {a[k]=p->inf;for(i=1;iinf;drum_frunze(p->st,k+1); drum_frunze(p->dr,k+1);}
}}voidadancime(arbore *p, intk){if (p) {
if(k>max) max=k; adancime(p->dr,k+1) ;adancime(p->st,k+1);
}}
5/28/2018 15827872 Tehnici de Programare
66/158
93
voidmain(){intx;rad=creare();
preordine(rad);printf("inf cautata:");scanf("%d", &x);if (cautare(rad,x)) printf("exista");elseprintf("nu exista");coutx;cout
5/28/2018 15827872 Tehnici de Programare
67/158
94
procedureinserare(varp:arbore;x:integer);varq:arbore;begin
new(q);q^.inf:=x;q^.st:=nil;q^.dr:=nil;ifp=nil thenp:=qelse ifp^.inf=x thenwrite('Exista')
else ifp^.inf
5/28/2018 15827872 Tehnici de Programare
68/158
95
Implementare C++:#include#include
#includetypedef structnod {intinf; nod *st,*dr;}arbore;arbore *rad;arbore *q;voidadaug(arbore* &p,int x){if(p==NULL){
p=newnod;p->inf=x;p->st=p->dr=NULL;
}else if(p->inf>x) adaug(p->st,x);else if(p->infdr,x);
elsecout dr);}
}
arbore *cauta(arbore*p, int x){if(p==NULL) returnNULL;else if(p->infst;cauta(p,x);}else if(p->inf>x){
q=p;p=p->st; cauta(p,x);}else returnp;
}
5/28/2018 15827872 Tehnici de Programare
69/158
96
voidsterge(arbore *&r,intx){arbore *t,*q1,*p;int a;
t=cauta(r,x);if(t==NULL){coutst){if(t->infinf) q->st=NULL;delete t;}
else if(t->st==NULL&&t->st){if(q->infinf) q->dr=t->st; elseq->st=t->st;delete t;}
else if(t->st==NULL&&t->dr){if(q->inf>t->inf) q->st=t->dr; elseq->dr=t->dr;delete t;}else{
p=t;while (p->st!=NULL){q=p;p=p->st;}}
q1=t;t->inf=p->inf;if(p->dr==p->st){
q->st=NULL;delete p;}
else{q->st=p->dr;delete p;}
while(q1->st&&q1->infst->inf){a=q1->inf;q1->inf=q1->st->inf; q1->st->inf=a;q1=q1->st;}
}
5/28/2018 15827872 Tehnici de Programare
70/158
97
void main(){int x;arbore *rad=0;
creare(rad);inordine(rad);sterge(rad,2);
}
Probleme rezolvate n limbajul Pascal
R2.7.1. Sse scrie un subprogram pentru afiarea numrului cheilornegative i pozitive dintr-un arbore binar.
procedurep3(p:arbore);beginifpnil then begin
p3(p^.st);ifp^.inf=0 thennr2:=nr2+1;p3(p^.dr);end;
end;R2.7.2. S se scrie un subprogram pentru afiarea cheilor imparedintr-un arborele binar.
procedurep2(p:arbore);beginifpnil then begin
ifp^.inf mod2 =1 thenwrite(p^.inf,' ');p2(p^.st); p2(p^.dr)end
end;R2.7.3. Sse scrie un subprogram pentru aflarea produsului cheilor
pozitive dintr-un arborele binar.
functionp4(p:arbore):longint;beginifpnil thenifp^.inf >0 thenp4:=p^.inf*p4(p^.st)*p4(p^.dr)
elsep4:=p4(p^.st)*p4(p^.dr)elsep4:=1
end;
5/28/2018 15827872 Tehnici de Programare
71/158
98
R2.7.4. S se scrie un subprogram pentru aflarea numrului defrunze dintr-un arborele binar .
functionp5(p:arbore):integer;beginifp=nil thenp5:=0 elseif(p^.st=nil) and(p^.dr=nil) thenp5:=1
else p5:=p5(p^.st)+p5(p^.dr)end;
R2.7.5.. Sse scrie un subprogram pentru afiarea nodurilor care auun succesor dintr-un arbore binar.
procedurep6(p:arbore);begin
ifpnil then beginif((p^.st=nil) and(p^.drnil)) or((p^.stnil) and(p^.dr=nil))
thenwrite(p^.inf,' ');p6(p^.st); p6(p^.dr)end
end;
R2.7.6. S se scrie un subprogram pentru aflarea numrului denoduri de pe un nivel dat dintr-un arbore binar.
functionp7(p:arbore;k:integer):integer;beginifpnil thenifk=l thenp7:=1+p7(p^.st,k+1)+p7(p^.dr,k+1)
elsep7:=p7(p^.st,k+1)+p7(p^.dr,k+1)elsep7:=0
end;
Probleme propuse:
1. Se d un graf orientat cu n noduri. S se verifice dac exist unnod avnd gradul interior n-1 i gradul exterior 0.2. Fie G = (X,U) un graf orientat i farcircuite. Sse determine o
renumerotare a vrfurilor sale astfel ncat dac (u,v)U, atuncinumrul de ordine al lui u este mai mic dect numrul de ordine allui v (sortare topologic).
3. Fie G =(X,U) un graf orientat cu n vrfuri. Sse determine un altgraf avnd aceleai vrfuri, aceeai matrice a drumurilor i avndun numr minim de arce (se pot scoate, introduce noi arce).
5/28/2018 15827872 Tehnici de Programare
72/158
99
4. La un turneu particip n juctori, fiecare juctor jucnd pe rndmpotriva celorlali juctori. tiind cnu existjocuri egale, sseconstruiasc o listcare s cuprind toi juctorii astfel ncat doi
juctori i, j sunt alturi dacjuctorul i la nvins pe juctorul j.5. La curtea regelui Artur s-au adunat 2n cavaleri i fiecare din ei areprintre cei prezeni cel mult n-1 dumani. S se arate c Merlin,consilierul lui Artur, poate s-i aeze n aa fel pe cavaleri la omasa rotund nct nici unul dintre ei snu stea alturi de vreunduman.
6. Fie G=(X,U) un graf conex cu n noduri. Sse determine eficientcel mai mic k astfel nct tergnd nodurile etichetate cu 1,2...k, naceastordine s rezulte un graf ale crui componente conexe au
toate cel mult n/2 noduri.7. S se determine, ntr-un graf conex, un ciclu care conine dounoduri date, dar nu conine un al treilea nod.
8. Numim transpusul unui graf G = (X,U), graful care are aceeaimulime de noduri, arcele sale fiind arcele grafului G, dar avndsens opus. Dndu-se G prin matricea de adiacensau prin liste devecini, sse determine n fiecare caz transpusul grafului dat.
9. Find date n persoane n care fiecare persoanse cunoate pe sinei eventual alte persoane. S se formeze grupuri n care fiecare
persoanscunoasctoate celelalte persoane din grup (o persoanaparine unui singur grup). Relaia x cunoate pe y nu este nmod normal nici simetric, nici tranzitiv.
Indicaie: Se asociazproblemei date un graf orientat cu n noduri i seconstruiete matricea de adiacen (a[i,j]=1 daca i cunoaste pe j =i 0dac i nu cunoate pe j). Pentru fiecare persoan neataat la unmoment dat unui grup se va construi grupul din care face parteaceasta. Soluia nu este unic.
10. Sse determine, ntr-un graf turneu, un drum elementar care trece
prin toate vrfurile. Un graf turneu este un graf orientat cuproprietatea c ntre oricare douvrfuri distincte existun arc inumai unul.
Indicaie:Se adaugarcul format din nodurile 1 i 2 ntr-o listliniar.Fiecare din vrfurile urmtoare se adaug la drumul creat anterior fien fa, fie la sfrit, fie intercalat n list.11. Fie G=(X,U) un graf ponderat. Sse calculeze diametrul grafului.
Se numete diametrul unui graf, notat d(G), d(G)=max{l[i]/ iX},unde l[i] este lungimea drumului maxim care are ca extremitate
iniialvrful i.
5/28/2018 15827872 Tehnici de Programare
73/158
100
12. Fie G un graf orientat n care fiecare arc are asociat un cost pozi-tiv. Sse determine un circuit elementar care s treacprin toatevrfurile grafului care saibcost minim.
13. Se considerun grup de n persoane. Fiecare persoana are cel puinn/2 prieteni i cel mult k dumani n grup. Una din persoane are ocarte pe care fiecare dorete so citeasc. Sse determine o mo-dalitate prin care cartea scircule pe la fiecare persoano singurdat, transmiterea ei facndu-se numai ntre doi prieteni, iar nfinal cartea sajungdin nou la proprietarul crii.
14. Pentru un graf dat n numerotare aciclic (orice arc u = (x,y) din Usatisface condiia x
5/28/2018 15827872 Tehnici de Programare
74/158
101
3. Metode pentru rezolvarea problemelor
3.1. MetodaDivide et Impera
3.1.1. Prezentarea metodei
Metoda general de programare cunoscut sub numele de divide etimpera (dezbin i stapnete) const n mprirea repetat a uneiprobleme n subprobleme de acelai tip, dar de dimensiune mai mic,urmat de combinarea soluiilor subproblemelor rezolvate pentru aobine soluia problemei iniiale. Fiecare subproblem se rezolvdirect dac dimensiunea ei este suficient de mic nct s poat firezolvat imediat cu un procedeu specific, altfel este mprit n
subprobleme mai mici folosind acelai procedeu prin care a fostdescompus problema iniial. Procedeul se reia pn cnd, n urmadescompunerilor repetate, se ajunge la probleme care admit rezolvareimediat.
Algoritmul fiind de natur repetitivi deoarece subproblemeleau aceeai form cu cea a problemei iniiale, metoda Divide etimpera poate fi implementatelegant folosind o funcie recursiv.
n continuare este datfuncia generalcare implementeazalgoritmul.
functiondivimp(X: problema)if(X este suficient de mica) then y rezolv(X)
else{descompune problema x n subproblemele X1, X2,, Xkfori 1 tok doyidivimp(Xi)
/* combiny1, y2, , ykpentru a obine y soluia problemei X */y combin(y1, y2, , yk)
returny}Uneori recursivitatea se poate nlocui cu un ciclu iterativ. Versiuneaiterativ poate fi mai rapid i folosete mai puin memoriecomparativ cu varianta recursiv care utilizeaz o stiv pentrumemorarea apelurilor.3.1.2. Probleme rezolvate
R3.1.1.[Cel mai mare divizor comun]Fie n numere naturale nenulex1, x2,,xn. Sse calculeze cmmdc pentru numere date.
5/28/2018 15827872 Tehnici de Programare
75/158
102
Rezolvare:programdivizor_comun;var x:array[1..25] of integer; n, i:integer;
functionDivizor(a,b:integer):integer;beginwhileab doifa>b thena:=a-b elseb:=b-a;Divizor := aend;
functioncmmdc(lo,hi:integer):integer;varm:integer;begin
if(hi-lo
5/28/2018 15827872 Tehnici de Programare
76/158
103
var n,i,pos:integer;ch:char;
begin
write('n = ');readln(n);writeln('Introduceti numerele');fori:=1 ton do beginwrite('x[',i,'] = '); readln(x[i]) end;repeat
writeln;write('Numarul cautat = ');readln(nr);pos := cauta(1,n);ifpos 0 then
writeln(nr,' se afla in sir la pozitia ', pos)elsewriteln(nr,' nu se afla in sir!');write('Continuati (y/n) ?[y] ');ch:=UpCase(readkey);
untilch = 'N';end.R3.1.3. [Sortare rapid]Fie n N* i numerele x1, x2,,xn. Sse scrieo procedurrecursivde sortare (quicksort) n ordine cresctoare anumerelor date.
Rezolvare:#includevoidQSort (int *table, int left,int right){
intleftp,rightp,aux;unsignedtype = 1;leftp =left;rightp=right;do{
if( table[leftp]>table[rightp] ){
type ^= 1;aux = table[leftp];table[leftp] = table[rightp];table[rightp] = aux;}
elsetype ? rightp--: leftp++;}while(leftp < rightp);if( leftp-left > 1) QSort(table,left,leftp-1);if( right-rightp >1) QSort(table,rightp+1,right);
}
5/28/2018 15827872 Tehnici de Programare
77/158
104
voidmain(){intn,i;intx[100];
printf(n = ); scanf(%d,&d);for(i=0;i
5/28/2018 15827872 Tehnici de Programare
78/158
105
voidMSort(inttabel[],inttemp[], intlo, inthi){intmid, k, t_lo, t_hi;if(lo >= hi) return;
mid = (lo+hi) / 2;MSort(tabel,temp, lo, mid);MSort(tabel,temp, mid+1, hi);t_lo = lo;t_hi = mid+1;for(k = lo; k hi || tabel[t_lo] < tabel[t_hi]) && (t_lo
5/28/2018 15827872 Tehnici de Programare
79/158
106
4. Se d o plac de tabl cu lungimea x i limea y avnd n guridate prin coordonatele lor ntregi. Se cere sse decupeze o bucatdreptunghiularde arie maximi frguri tiind csunt permise
numai tieturi orizontale i verticale.5. Se consider un vector de lungime n. Se numete plierea
vectorului operaia de suprapunere a unei jumti (donatoare)peste cealalt jumtate (receptoare). Dacn este impar elementuldin mijloc se elimin. Elementele rezultate dup pliere vor aveanumeroatarea jumtii receptoare. Plierea se poate repeta pncnd se obine un singur element (final). Scriei un program cares determine toate elementele finale posibile i s afiezesuccesiunile de plieri corespunztoare. Rezolvai aceiai probleminnd cont cla pliere fiecare element receptor se dubleazi dinacesta se scade elementul donator corespunztor.
6. Rezolvai problema turnurilor din Hanoi folosint dou tije demanevr. Comparai numrul de mutri efectuate.
7. Fie P(x) un polinom de grag n cu coficieni reali. S se evaluezepolinomul n punctul x0folosind metoda Divide et Imera.
8. Scriei o procedurDivide et Impera pentru inversarea unui irde caractere.
9. Se d un dreptunghi prin dimensiunile sale numere naturale.Dreptunghiul trebuie descompus n ptrate cu laturi numerenaturale, paralele cu laturile dreptunghiului iniial. Se cerenumrul minim de ptrate n care se poate descompunedreptunghiul.
10. Se dau un ptrat i un cerc. Se cere sse calculeze aria lor comuncu precizie de o zecimal. Coordonatele se citesc de la tastaturisunt numere reale. Aria se va afia pe ecran.
11. Un arbore cartezian al unui vector este un arbore binar definitrecursiv astfel: rdcina arborelui este elementul cel mai mic dinvector; subarborele stng este arborele cartezian al subvectoruluistng (fade poziia elementului din rdcin); subarborele drepteste arborele cartezian al subvectorului drept. Se dun vector dedimensiune n. Sse afieze arborele su cartezian.
5/28/2018 15827872 Tehnici de Programare
80/158
107
3.2. Metoda programrii dinamice
3.2.1. Principii fundamentale ale programrii dinamice
Programarea dinamic, ca i metoda divide et impera, rezolvproblemele "combinnd" soluiile subproblemelor. Un algoritm bazatpe programare dinamicrezolvfiecare subproblemo singurdati,apoi, memoreaz soluia ntr-un tablou, prin aceasta evitndrecalcularea soluiei dac subproblema mai apare din nou isubprobemele care apar n descompunere nu sunt independente.
Metoda programrii dinamice se aplic problemelor deoptimizare. n problemele de optim metoda const n determinareasoluiei pe baza unui ir de decizii d1, d2, d3....dn, unde di transform
problema din starea si-1n starea si.Paii pentru rezolvarea unei probleme folosind programareadinamic:
1. Caracterizarea structurii unei soluii optime;2. Definirea recursiva valorii unei soluii optime;3. Calculul valorii unei soluii optime4. Construirea unei soluii optime din informaia calculat.
Principii fundamentale ale programrii dinamice:1. Dac d1, d2, ... dn este un ir optim de decizii care duc un
sistem din starea iniial n starea final, atunci pentru orice i(1in) d1, d2, ... di este un ir optim de decizii.2. Dac d1, d2, ... dn este un ir optim de decizii care duc un
sistem din starea iniial n starea final, atunci pentru orice i(1in) di, di+1, ... dn este un ir optim de decizii.
3. Dacd1, d2, ... , di, di+1... dneste un ir optim de decizii careduc un sistem din starea iniialn starea final, atunci pentruorice i (1in) d1, d2,... , di i di, di+1, ... dn sunt douirurioptime de decizii.
3.2.2. Probleme rezolvate
R3.2.1. [Subir cresctor maximal] Se consider un ir de n numerentregi. Sse determine cel mai lung subir cresctor din acesta.
Exemplu: n=87 1 8 2 11 4 12 3
Subirul cresctor maximal: 7 8 11 12 cu lungimea 4
Rezolvare:Se construiete tabloul L reprezentnd lungimea maxima
unui subir maximal care l conine ca prim element pe a[i] astfel
5/28/2018 15827872 Tehnici de Programare
81/158
108
L[n]=1 i L[i]=1+max{L[j]/ j>i i a[j]>a[i]} pentru i de la n-1 la 1(metoda nainte - deoarece soluia unei subprobleme se afl pe bazasubproblemelor din urm).
Implementare Pascal:var i,j,n,poz,max:integer;
l,a:array[1..30] of integer;begin
write('n=');read(n);fori:=1 ton do begin write('a[',i,']='); read(a[i]) end;fori:=1 ton dol[i]:=0;l[n]:=1;fori:=n-1 downto1 do
beginmax:=0;forj:=1+i ton do
if(a[j]>a[i]) and(maxa[poz]) and(l[i]=max-1) then beginpoz:=i;write(a[poz],' ');max:=max-1end;
i:=i+1end
end.
Implementare C:
#includevoidmain(){
intn,i,j,poz,max,a[100],l[100];printf("n=");scanf("%d",&n);
for(i=1;i
5/28/2018 15827872 Tehnici de Programare
82/158
109
for(i=1;i0;i--){
max=0;for(j=i+1;j1){if((a[i]>a[poz]) &&(l[i]==max-1)) {poz=i;printf("%d ",a[poz]);max=max-1;}
i++;}
}
Exerciiu: S se rezolve aceast problem folosind varianta napoide programare dinamic (soluia unei subprobleme se afl pe bazasubproblemelor dinainte).
Indicaie: Tabloul L se construiete astfe L[1]=1 i L[i]=1+max{L[j]/j
5/28/2018 15827872 Tehnici de Programare
83/158
110
fori:=1 ton doread(a[i]);fori:=n downto1 dobegin
max:=0;
forj:=i+2 ton do if(maxmax then begin
max:=l[i];poz:=iend;
writeln('suma maxima este: ',l[1]);max:=l[1];poz:=1;write('sirul: ');repeat
write(a[poz],' '); i:=poz+2;while(i
5/28/2018 15827872 Tehnici de Programare
84/158
111
while((i
5/28/2018 15827872 Tehnici de Programare
85/158
112
a[n,n]=1;a[n,k]=a[n-k,0]pentru n2k;a[n,k]=a[n-k,i]pentru i de la 1 la k.
Implementare C:#includevoidmain(){
intn,i,k,j,p,a[100][100];printf("n=");scanf("%d",&n);a[1][0]=1;a[1][1]=1;for( i=2;i
5/28/2018 15827872 Tehnici de Programare
86/158
113
ifl[i-1,j]>l[i,j-1] thenl[i,j]:=l[i-1,j]+a[i,j]elsel[i,j]:=l[i,j-1]+a[i,j];
writeln(l[n,m]); max:=l[n,m];p:=n;q:=m; write(a[n,m],' ');
while(p1) and(q1) do beginifl[p-1,q] = l[p,q]-a[p,q] thenp:=p-1 elseq:=q-1;write(a[p,q],' ');end;
write(a[1,1]);end.
Exerciiu: Sse implementeze aplicaia de mai sus n C.
3.2.3. Probleme propuse
1. [Triunghi] Se considerun triunghi de numere. Sse calculeze ceamai mare dintre sumele numerelor ce apar pe drumurile ce pleacdinvrf i ajung la bazi sse reconstituie drumul de summaxim. npunctul (i,j) se poat