Sunteți pe pagina 1din 165

Structuri de date i algoritmi

_______________________________________________________________________________
CUPRINS
BAZELE ALGORITMILOR
Introducere
Descrierea Algoritmilor
-algoritm, program, programare
-scheme logice
-limbajul Pseudocod
-calculul efectuat de un algoritm
-rafinare in pasi succesivi
-probleme propuse
-test
Subalgoritmi
-conceptul de subalgoritm
-apelul unui subalgoritm
-elaborarea algoritmului
-proiectarea ascendenta si descendenta
-proiectarea modulara
-apel recursiv
-programare structurata
-probleme propuse
-test de verificare
Limbajul Pascal
-mediul de programare Turbo Pascal
-programe pascal simple
-subprograme
-tipuri de date
-probleme propuse
-test de verificare
STRUCTURI DE DATE
Introducere
Lista simplu inlantuita
Teorie generala
-definitia componentelor listei
-metoda statica
-metoda dinamica
-operatii specifice listei
Test de verificare
Lista dublu inlantuita
Teorie generala
-definitia componentelor listei
________________________________________________________________________________
1
Structuri de date i algoritmi
_______________________________________________________________________________
-metoda statica
-metoda dinamica
-operatii specifice listei
Test de verificare
Stiva
Teorie generala
-definitia componentelor stivei
-metoda statica
-metoda dinamica
-operatii specifice stivei
Simularea stivei
Probleme propuse
Test de verificare
Probleme rezolvate
Coada
Teorie generala
-referitor la coada
-alocarea secventiala
alocarea dinamica
Simularea functionarii cozii
Probleme propuse
Probleme rezolvate
Arborele Binar
Teorie generala
-generalitati
-definitia elementelor arborelui
-implementarea in pascal
-operatii specifice
Simularea operatii
Test de verif
Probleme rezolvata
Graful
Teorie generala
Exemple
COMPLEXITATEA ALGORITMILOR
-etapele rezolvarii unei probleme
-notiune de algoritm si de program
-modelul abstract al masinii Turing
-teza Turing-Church
-analiza , proiectarea si implementarea algoritmilor
-operatia de baza cheia studiului complexitatii
-clase de algoritmi
-eficienata algoritmi
________________________________________________________________________________
2
Structuri de date i algoritmi
_______________________________________________________________________________
-functii de complexitate
-apartenenta la o clasa de complexitate
-limita mimimala sau efort minimal
-algoritm optimal
-dificultatea problemelor
-complexitatea de timp
-probleme rezonabile si probleme nerezonabile\
-probleme de decizie si de optimizare
-clasa problemelor NP
-reductia polinamiala a problemelor
-echivalarea problemelor prin reductie polinopmiala
-teorema lui Cook
-clasa probleme NP
-marea intrebare a complexitatii algoritmilor
-algoritmi aproxiamtivi
-probleme insolvabile algoritmic
-complexiatea algoritmilor , calculatorul si viitorul
-test de verificare
TEHNICI DE CAUTARE
Cautare secventiala
Teorie generala
-descrierea generala a metodei
-descrierea algoritmului in pseudocod
-implementarea algoritmului in Pascal
-implementarea algoritmului in C
-performanta metodei de cautare
Probleme rezolvate
Probleme propuse
Simularea metodei de cautare
Cautare binara
Teorie generala
-descrierea generala a metodei
-descrierea algoritmului de cautare in Pseudocod
-implementarea algoritmului in Pascal
-implementarea algoritmului in C
-performanata metodei de cautare binara
Probleme rezolvate
Probleme propuse
Simularea metodei de cautare binara
Test de verificare
Arbori
________________________________________________________________________________
3
Structuri de date i algoritmi
_______________________________________________________________________________
Arbore binar balansat in inaltime
-introducere
-descriere generala
-descrierea algoritmului in Pseudocod
-implementarea algoritmului in Pascal
-implementarea algoritmului in C
-performanata arbore binar balansat in inaltime
-simularea cautarii in arborele balansat in inaltime
-test de verificare
Arbore 2-3
-descriere generala
-descrierea algoritmului de cautare in Pseudocod
-implementarea alg in Pascal
-performanata arborelui 2-3
-simularea arborelui 2-3 in algoritmul de cautare
test de verificare
Arbore balansat in greutate
-descrierea generala a arborelui
-descrierea algoritmului de cautare in Pseudocod
-implementarera algoritmului in Pascal
-performanta arborelui balansat in greutate
-simularea arborelui balansat in greutate in algoritmul cautarii
-test de verificare
Probleme rezolvate
Probleme propuse
Tablele Hasing
Introducere
Functia Hash
-generalitati a functiilor hash
-metoda Impartirii
-metoda Patrat Mediu
-metoda Indoirii
-metoda Digit Analysis
-metoda dependenta de lungimea cheii
-metoda codarii algebrice
-metoda Hashing Multiplicativ
Performanta functiei hash
Simularea metodei Impartirii
Test de verificare
Tehnici de rezolvare a coleziunilor
Introducere
Probarea liniara
-descrierea generala a metodei
________________________________________________________________________________
4
Structuri de date i algoritmi
_______________________________________________________________________________
-descrierea lagorotmului de cautare inserare in Pseudocod
-implementarea algoritmului in Pascal
-implementarea algoritmului in C
-performanta metodei
Probarea aleatoare
-descrierea generala a metodei
-descrierea algoritmului de cautare inserare in Pseuducod
-implementarea algoritmului in Pascal
Hashing multiplicativ
-descrierea generala a metodei
-descrierea algoritmului de cautare inserare in Pseuducod
-implementarea algoritmului in Pascal
-implementarea algoritmului in C
-performanta metodei
Inlantuire separata (Separate Chaining)
-descrierea generala a metodei
-descrierea algoritmului de cautare inserare in Pseuducod
-implementarea algoritmului in C
-performanta metodei
Buckets
-descrierea generala a metodei
-descrierea algoritmului de cautare inserare in Pseuducod
-implementarea algoritmului in C
Probleme propuse
Simularea tehnicii Probarii aleatoare
Test de verificare
TEHNICI DE SORTARE
Istoric
Prezentare generala
BubleSort
-descrierea generala metodei
-implementarea algoritmului in Pascal si C
-complexitatea algoritmului
-probleme rezolvate
-probleme propuse
-simulare
-test de verificare
SelectionSort
-descrierea generala metodei
-implementarea algoritmului in Pascal si C
-complexitatea algoritmului
________________________________________________________________________________
5
Structuri de date i algoritmi
_______________________________________________________________________________
-probleme rezolvate
-probleme propuse
-simulare
-test de verificare
InsertSort
-descrierea generala metodei
-implementarea algoritmului in Pascal si C
-complexitatea algoritmului
-probleme rezolvate
-probleme propuse
-simulare
-test de verificare
ShellSort
-descrierea generala metodei
-implementarea algoritmului in Pascal si C
-complexitatea algoritmului
-probleme rezolvate
-probleme propuse
-simulare
-test de verificare
QuickSort
-descrierea generala metodei
-imbunatatiri
-probleme rezolvate
-probleme propuse
-simulare
-test de verificare
MergeSort
-descrierea generala metodei
-imbunatatiri
-probleme rezolvate
-probleme propuse
-simulare
-test de verificare
HeapSort
-descrierea generala metodei
-probleme rezolvate
-probleme propuse
-simulare
-test de verificare
________________________________________________________________________________
6
Structuri de date i algoritmi
_______________________________________________________________________________
RadixSort
-descrierea generala metodei
-probleme rezolvate
-probleme propuse
-simulare
-test de verificare

TEHNICI DE PROGRAMARE
Backtracking
Greedy
Programarea dinamica
Branch&Bound
Test de verificare
Exemple
Introducere

________________________________________________________________________________
7
Structuri de date i algoritmi
_______________________________________________________________________________
Progresele tehnologice n domeniul informaticii au condus la creterea puterii de calcul i a
memoriei calculatoarelor electronice, la ieftinirea acestor calculatoare, permind abordarea unor
probleme extrem de complexe, din toate sferele activitii umane. Calculatorul a devenit un
instrument indispensabil pentru viaa omului modern. Penetrarea Internetului i a accesului la
resursele informatice mondiale, lrgirea considerabil a spectrului de aplicaii a contribuit i
contribuie la impunerea calculatorului ca instrument de lucru vital n activitatea omului. n
consecin, cerina de noi programe n toate domeniile activitii umane a crescut mereu.
De aceea, se impune tot mai pregnant creterea importanei metodologilor de realizare a
produselor program, necesitatea unei instruiri corespunztoare a noilor generaii de specialiti i de
utilizatori ai calculatoarelor. n formarea specialitilor n informatic este important dobndirea
unor cunotine i deprinderi de a realiza produse program de o complexitate variat, care s
satisfac cerinele beneficiarului. Pentru aceasta este necesar respectarea unei discipline de lucru i
cunoaterea unei metodologii adecvate de proiectare i realizare a acestor produse software. n
trecutul nu prea ndeprtat, n activitatea de instruire a specialitilor n informatic s-a pus un mai
mare accent pe nvarea unor limbaje de programare i pe programarea propriu-zis, acordndu-se
o pondere mai mic analizei i proiectrii programelor. Specializarea n informatic nu nseamn
doar cunoaterea limbajelor de programare, ci n primul rnd nsuirea metodelor moderne de
analiz i proiectare a aplicaiilor soft.
Scopul acestei cri este de a contribui la nvarea programrii ca o disciplin unitar avnd
o fundaie tiinific solid, necesar programatorilor. Pentru aceasta este nevoie s ncercm s
definim mai clar noiunea de programare.
Conform cu Sedgewitz [1990], programarea poate fi privit ca o activitate general de a
extinde sau a de a modifica funcionalitile unui sistem. Este o activitate general deoarece ea
poate fi efectuat att de specialiti (programatori) ct i de nespecialiti (setarea unui telefon
celular sau a unei alarme de acces ntr-o ncpere). Din acest punct de vedere activitatea de
programare const din dou elemente fundamentale: o component tehnologic i o component
tiinific. Partea tiinific include elemente printre care se regsesc structurile de date i algoritmii
necesari descrierii operaiilor de manipulare a acestor structuri de date. Aceast abordare ne permite
o independena a acestor structuri de date fa de limbajele de programare i fa de tehnologiile de
proiectare utilizate in activitatea de programare.
Programele sunt fcute pentru a rezolva probleme din viaa de zi cu zi. Informaia prelucrat
de un program este stocat cu ajutorul structurilor de date. Aceste structuri de date grupeaz ntr-o
form eficient datele. O structur de date corect definit poate simplifica operaia care prelucreaz
acele date sau o poate complica. De aceea structurile de date au o importan major n activitatea
de proiectare si programare.
Programele prelucreaz informaii. Informaiile sunt organizate sub form de structuri de
calcul. Modul n care reprezentm structurile de date afecteaz claritatea, conciziunea, viteza de
rulare i capacitatea de stocare a programului. Dezvoltarea unui program complex este dificil dac
programatorul nu posed cunotine n domeniul structurilor de date, algoritmicii i a tehnicilor de
programare.
Dac nu se cunoate o soluie pentru rezolvarea unei probleme nu exist o soluie magic de
a scrie un program care s rezolve acea problema. Un proverb afirm c dac nu tii cum s ajungi
ntr-un anumit loc atunci nu are importan cum ajungi n acel loc. Mai mult chiar Murphi afirm c
________________________________________________________________________________
8
Structuri de date i algoritmi
_______________________________________________________________________________
orice problem complex are o soluie simpl eronat. De aceea, nainte de a implementa un
program ntr-un anumit limbaj de programare, este necesar nelegerea problemei, descrierea pas
cu pas a soluiei, cu alte cuvinte este necesar a descrie problema prin intermediul unui algoritm.
Din pcate nu exist un algoritm care s aleag algoritmul care rezolv orice problem. Ceea
ce exist sunt o serie de tehnici de dezvoltare a algoritmilor, numite n general tehnici de
programare.
Scopul principal al lucrrii de fa este familiarizarea celor care doresc s o nvee, cu
activitatea de programare. Vom vedea n ce const aceast activitate i vom remarca accentul pus pe
gndirea omului, pe proiectarea algoritmilor i corectitudinea lor, calculatorul fiind doar unealta
care execut ceea ce "dicteaz" programatorul. Pentru a putea dicta calculatorului avem nevoie de
un limbaj neles de ambele pri; limbajul ales n acest scop este limbajul Pascal. De asemenea,
vom prezenta metodele de programare cunoscute n prezent i discutate n literatura de specialitate.
Vom nva s analizm algoritmii, dar vom fi mai puin preocupai de msurarea complexitii unui
program, accentul fiind pus pe modul n care el poate fi obinut. Noiunile i conceptele prezentate
sunt nsoite de exemple simple, n care s-au folosit: limbajul Pseudocod n descrierea algoritmilor,
un limbaj de specificare informal n descrierea tipurilor abstracte de date i limbajul Pascal pentru
codificare.
I. BAZELE ALGORITMILOR
I.1. DESCRIEREA ALGORITMILOR
I.1.1. Algoritm, program, programare
Ce este un algoritm? O definiie matematic, riguroas, este greu de dat, chiar imposibil fr
a introduce i alte noiuni (Giumale [2004]). Vom ncerca n continuare o descriere a ceea ce se
nelege prin algoritm.
Vom constata c un algoritm este un text finit, o secven finit de propoziii ale unui limbaj.
Din cauz c este inventat special n acest scop, un astfel de limbaj este numit limbaj de descriere a
algoritmilor. Fiecare propoziie a limbajului precizeaz o anumit regul de calcul, aa cum se va
observa atunci cnd vom prezenta limbajul Pseudocod.
Algoritmii au urmtoarele caracteristici: generalitate, finitudine i unicitate (Livovschi [1980])
n descrierea algoritmilor se folosesc mai multe limbaje de descriere, dintre care cele mai des
folosite sunt:
- limbajul schemelor logice;
________________________________________________________________________________
9
Structuri de date i algoritmi
_______________________________________________________________________________
- limbajul Pseudocod.

I.1.2. Scheme logice
Schema logic este un mijloc de descriere a algoritmilor prin reprezentare grafic. Regulile
de calcul ale algoritmului sunt descrise prin blocuri (figuri geometrice) reprezentnd operaiile
(paii) algoritmului, iar ordinea lor de aplicare (succesiunea operaiilor) este indicat prin sgei.
Fiecrui tip de operaie i este consacrat o figur geometric (un bloc tip) n interiorul creia se va
nscrie operaia din pasul respectiv (Livovschi [1980)..
Prin execuia unui algoritm descris printr-o schem logic se nelege efectuarea tuturor
operaiilor precizate prin blocurile schemei logice, n ordinea indicat de sgei.
n descrierea unui algoritm, deci i ntr-o schem logic, intervin variabile care marcheaz
att datele cunoscute iniial, ct i rezultatele dorite, precum i alte rezultate intermediare necesare
n rezolvarea problemei. ntruct variabila joac un rol central n programare este bine s definim
acest concept.
Variabila definete o mrime care i poate schimba valoarea n timp. Ea are un nume i o
valoare. Este posibil ca variabila nc s nu aib asignat o valoare, situaie n care vom spune c ea
este neiniializat.
Valorile pe care le poate lua variabila aparin unei mulimi D pe care o vom numi domeniul
variabilei. Variabila este folosit cu un anumit scop, ea noteaz o anumit mrime, cu o anumit
semnificaie. n concluzie o variabil este cunoscut prin (nume, domeniul D, valoare,
semnificaie), unde valoarea aparine mulimii D {nedefinit}.
Pentru claritatea textului unui algoritm este important s se cunoasc semnificaia fiecrei
variabile, s fie menionat expres aceast semnificaie. n nici un caz nu se recomand s se
foloseasc acelai nume pentru variabile cu semnificaii diferite, caz care provoc confuzii i chiar
erori grave. Vom enuna acestea sub forma unor reguli cu care e bine s ne obinuim i s le
respectm n activitatea de programare.
I.1.3. Limbajul PSEUDOCOD
Limbajul Pseudocod este un limbaj folosit n scopul proiectrii algoritmilor i este format
din propoziii asemntoare propoziiilor limbii romne, care corespund structurilor de calcul
folosite n construirea algoritmilor. Acesta va fi limbajul folosit de noi n proiectarea algoritmilor i
va fi definit n cele ce urmeaz.
innd seama c realizarea unui algoritm pentru rezolvarea unei probleme nu este
ntotdeauna o sarcin simpl, c n acest scop sunt folosite anumite metode pe care le vom descrie
n capitolele urmtoare, n etapele intermediare pentru obinerea algoritmului vom folosi propoziii
curente din limba romn (Frentiu, Groze [1986]).
Acestea sunt considerate elemente nefinisate din algoritm, asupra crora trebuie s se revin
i le vom numi propoziii nestandard. Deci limbajul Pseudocod are dou tipuri de propoziii:
propoziii standard, care vor fi prezentate fiecare cu sintaxa i semnificaia (semantica) ei i
________________________________________________________________________________
10
Structuri de date i algoritmi
_______________________________________________________________________________
propoziii nestandard. Aa cum se va arta mai trziu, propoziiile nestandard sunt texte care descriu
pri ale algoritmului nc incomplet elaborate, nefinisate, asupra crora urmeaz s se revin. Ele
se recunosc prin faptul c ncep ntotdeauna cu semnul '@' i se termin cu punctul obinuit
(caracterul '.').
Pe lng aceste propoziii standard i nestandard, n textul algoritmului vom mai introduce
propoziii explicative, numite comentarii. Pentru a le distinge de celelalte propoziii, comentariile
vor fi nchise ntre acolade. Rolul lor va fi explicat puin mai trziu.
Prin execuia unui algoritm descris n Pseudocod se nelege efectuarea operaiilor precizate
de propoziiile algoritmului, n ordinea citirii lor (de sus n jos i de la stnga spre dreapta).
Propoziiile standard ale limbajului Pseudocod folosite n aceast lucrare, corespund
structurilor de calcul prezentate n Figura 1.1 i vor fi prezentate n continuare.
n Figura I.1, prin A, B s-au notat subscheme logice, adic secvene de oricte structuri
construite conform celor trei reguli menionate n continuare.
Structura secvenial (Figura I.1.a) este redat prin concatenarea propoziiilor, simple sau
compuse, ale limbajului Pseudocod, care vor fi executate n ordinea ntlnirii lor n text.
Propoziiile simple din limbajul Pseudocod sunt CITETE, TIPARETE, FIE i apelul de
subprogram. Propoziiile compuse corespund structurilor alternative i repetitive.
Structura alternativ din Figura I.1.b este redat n Pseudocod prin propoziia DAC,
prezentat n seciunea 2.3.2, iar structura repetitiv din Figura I.1.c este redat n Pseudocod prin
propoziia CTTIMP, prezentat n seciunea 2.3.3.
Bhm i Jacopini [1966] au demonstrat c orice algoritm poate fi descris folosind numai
aceste trei structuri de calcul.
Propoziiile DATE i REZULTATE sunt folosite n faza de specificare a problemelor, adic
enunarea riguroas a acestora.

Figura 1.1. Structuri elementare de calcul.
________________________________________________________________________________
11
Structuri de date i algoritmi
_______________________________________________________________________________
Fiecare propoziie standard ncepe cu un cuvnt cheie, aa cum se va vedea n cele ce
urmeaz. Pentru a deosebi aceste cuvinte de celelalte denumiri, construite de programator, n acest
capitol vom scrie cuvintele cheie cu litere mari. Menionm c propoziiile simple se termin cu
caracterul ';' n timp ce propoziiile compuse, deci cele n interiorul crora se afl alte propoziii, au
un marcaj de sfrit propriu. De asemenea, menionm c propoziiile limbajului Pseudocod vor fi
luate n seam n ordinea ntlnirii lor n text, asemenea oricrui text al limbii romne.
Propoziia DATE se folosete pentru precizarea datelor iniiale, deci a datelor considerate
cunoscute n problem (numite i date de intrare) i are sintaxa:
DATE list ;
unde list conine toate numele variabilelor a cror valoare iniial este cunoscut.
n general, prin list se nelege o succesiune de elemente de acelai fel desprite prin
virgul. Deci n propoziia DATE, n dreapta acestui cuvnt se vor scrie acele variabile care
marcheaz mrimile cunoscute n problem.
Pentru precizarea rezultatelor dorite se folosete propoziia standard:
REZULTATE list;
n construcia "list" ce urmeaz dup cuvntul REZULTATE fiind trecute numele variabilelor
care marcheaz (conin) rezultatele cerute n problem.
Acum putem preciza mai exact ce nelegem prin cunoaterea complet a problemei de
rezolvat. Evident, o problem este cunoscut atunci cnd se tie care sunt datele de intrare ce
definesc problema dat i rezultatele ce trebuiesc obinute.
Deci pentru cunoaterea unei probleme este necesar precizarea variabilelor care marcheaz
datele considerate cunoscute n problem, care va fi reflectat printr-o propoziie DATE i
cunoaterea exact a rezultatelor problemei, care se va reflecta prin propoziia REZULTATE.
Variabilele prezente n aceste propoziii au anumite semnificaii, presupuse cunoscute.
Cunoaterea acestora, scrierea lor explicit, formeaz ceea ce vom numi n continuare specificarea
problemei. Specificarea unei probleme este o activitate foarte important dar nu i simpl.
De exemplu, pentru rezolvarea ecuaiei de gradul al doilea, specificarea problemei, poate
fi:
DATE a,b,c; { Coeficienii ecuaiei }
REZULTATE x1,x2; { Rdcinile ecuaiei }
Aceast specificaie este ns incomplet. Nu ntotdeauna ecuaia are rdcini reale. n cazul
________________________________________________________________________________
12
Structuri de date i algoritmi
_______________________________________________________________________________
n care rdcinile sunt complexe putem nota prin x1, x2 partea real, respectiv partea imaginar a
rdcinilor. Sau pur i simplu, nu ne intereseaz valoarea rdcinilor n acest caz, ci doar faptul c
ecuaia nu are rdcini reale.
Cu alte cuvinte avem nevoie de un mesaj care s ne indice aceast situaie, sau de un
indicator, fie el numit ind. Acest indicator va lua valoarea 1 dac rdcinile sunt reale i valoarea 0
n caz contrar. Deci specificaia mai complet a problemei este:

DATE a,b,c; { Coeficienii ecuaiei }
REZULTATE ind, {ind = 1 pt. rdcini reale, 0 pt complexe}
x1,x2; {Rdcinile ecuaiei, n cazul ind = 1, respectiv}
{partea real i cea imaginar n cazul ind = 0}

Evident c specificarea problemei este o etap important pentru gsirea unei metode de
rezolvare i apoi n proiectarea algoritmului corespunztor. Nu se poate rezolva o problem dac
aceasta nu este bine cunoscut, adic nu avem scris specificarea problemei.
Cunoate complet problema este prima regul ce trebuie respectat pentru a obine ct mai
repede un algoritm corect pentru rezolvarea ei.
I.1.3.1. Algoritmi liniari
Propoziiile CITETE i TIPRETE sunt folosite pentru iniializarea variabilelor de
intrare cu datele cunoscute n problem, respectiv pentru tiprirea (aflarea) rezultatelor obinute. n
etapa de programare propriu-zis acestor propoziii le corespund ntr-un limbaj de programare
instruciuni de intrare-ieire.
Propoziia CITETE se folosete pentru precizarea datelor iniiale, deci a datelor
considerate cunoscute n problem (numite i date de intrare) i are sintaxa:
CITETE list ;
unde list conine toate numele variabilelor a cror valoare iniial este cunoscut.
Deci n propoziia CITETE, n dreapta acestui cuvnt se vor scrie acele variabile care apar
n propoziia DATE n specificarea problemei. Se subnelege c aceste variabile sunt iniializate cu
valorile cunoscute corespunztoare.
Pentru aflarea rezultatelor dorite, pe care calculatorul o va face prin tiprirea lor pe hrtie
sau afiarea pe ecran, se folosete propoziia standard:
TIPRETE list ;
________________________________________________________________________________
13
Structuri de date i algoritmi
_______________________________________________________________________________
n construcia list ce urmeaz dup cuvntul TIPRETE fiind trecute numele variabilelor a cror
valori dorim s le aflm. Ele sunt de obicei rezultatele cerute n problem, specificate i n
propoziia REZULTATE.
Blocului de atribuire dintr-o schem logic i corespunde n Pseudocod propoziia standard:
[FIE] var := expresie ;
Aceast propoziie este folosit pentru a indica un calcul algebric, al expresiei care urmeaz
dup simbolul de atribuire ":=" i de atribuire a rezultatului obinut variabilei var. Expresia din
dreapta semnului de atribuire poate fi orice expresie algebric simpl, cunoscut din manualele de
matematic din liceu i construit cu cele patru operaii: adunare, scdere, nmulire i mprire
(notate prin caracterele +, -, *, respectiv /).
Prin scrierea cuvntului FIE ntre paranteze drepte se indic posibilitatea omiterii acestui
cuvnt din propoziie. El s-a folosit cu gndul ca fiecare propoziie s nceap cu un cuvnt al limbii
romne care s reprezinte numele propoziiei. De cele mai multe ori vom omite acest cuvnt. Atunci
cnd vom scrie succesiv mai multe propoziii de atribuire vom folosi cuvntul FIE numai n prima
propoziie, omindu-l n celelalte.
Din cele de mai sus rezult c o variabil poate fi iniializat att prin atribuire (deci dac
este variabila din stnga semnului de atribuire :=) ct i prin citire (cnd face parte din lista
propoziiei CITETE). O greeal frecvent pe care o fac nceptorii este folosirea variabilelor
neiniializate. Evident c o expresie n care apar variabile care nu au valori nu poate fi calculat, ea
nu este definit. Deci nu folosii variabile neiniializate.
Pentru a marca nceputul descrierii unui algoritm vom folosi propoziia:

ALGORITMUL nume ESTE:
De asemenea, prin propoziia:
SFALGORITM
vom marca sfritul unui algoritm.
Algoritmii care pot fi descrii folosind numai propoziiile prezentate mai sus se numesc
algoritmi liniari.
Ca exemplu de algoritm liniar prezentm un algoritm ce determin viteza v cu care a mers
un autovehicul ce a parcurs distana D n timpul T.
Exemplul I.1.
ALGORITMUL VITEZA ESTE: { Algoritmul 1: Calculeaz viteza }
________________________________________________________________________________
14
Structuri de date i algoritmi
_______________________________________________________________________________
{ D = Distana (spaiul) }
{ T = Timpul; V = Viteza }
CITETE D,T; { v:= spaiu/timp }
FIE V:=D/T;
TIPRETE V
SFALGORITM
I.1.3.2. Algoritmi cu ramificaii
Foarte muli algoritmi execut anumite calcule n funcie de satisfacerea unor condiii.
Aceste calcule sunt redate de structura alternativ prezentat n Figura I.1.b, creia i corespunde
propoziia Pseudocod:
DAC cond
ATUNCI A
ALTFEL B
SFDAC
sau varianta redus a ei:
DAC cond
ATUNCI A
SFDAC
folosit n cazul n care grupul de propoziii B este vid.
Aceste propoziii redau n Pseudocod structura alternativ de calcul. n primul rnd este
necesar verificarea condiiei scrise dup cuvntul DAC. n cazul c aceast condiie este
adevrat se va executa grupul de propoziii A. n cazul n care aceast condiie este fals se va
executa grupul de propoziii B, dac este prezent ramura ALTFEL. Indiferent care dintre
secvenele A sau B a fost executat, se va continua cu propoziia urmtoare propoziiei DAC, ce
urmeaz dup marcatorul de sfrit SFDAC.
O generalizare a structurii alternative realizat de propoziia DAC este structura selectiv:
SELECTEAZ i DINTRE
v1: A1;
v2: A2;
. . .
________________________________________________________________________________
15
Structuri de date i algoritmi
_______________________________________________________________________________
vn: An
SFSELECTEAZ
structur echivalent cu urmtorul text Pseudocod:
DAC i = v1
ATUNCI A1
ALTFEL
DAC i = v2
ATUNCI A2
ALTFEL
. . .
DAC i = vn
ATUNCI An
SFDAC
...
SFDAC
SFDAC
Cu propoziiile prezentate pn acum putem descrie un numr nsemnat de algoritmi.
Acetia se numesc algoritmi cu ramificaii.
De exemplu, vom descrie un algoritm pentru rezolvarea ecuaiei de gradul al doilea. Am
prezentat n I.1.3 aceast problem i am precizat semnificaia variabilelor respective. Pe lng
aceste variabile, pentru rezolvarea problemei mai avem nevoie de dou variabile auxiliare:
delta - pentru discriminantul ecuaiei;
r - pentru valoarea radicalului folosit n calculul rdcinilor.
Exemplul I.2.
ALGORITMUL ECGRDOI ESTE: { Algoritmul 2: Rezolvarea }
{ ecuaiei de gradul doi }
CITETE a,b,c; { a,b,c = coeficienii ecuaiei }
FIE delta:= b*b-4*a*c;
DAC delta < 0
________________________________________________________________________________
16
Structuri de date i algoritmi
_______________________________________________________________________________
ATUNCI ind:= 0; {Cazul rdcini complexe }
@r:=radical din (-delta);
x1:=-b/(a+a);
x2:= r/(a+a);
ALTFEL ind:=1; {cazul rdcini reale }
@r:=radical din delta;
x1:=(-b-r)/(a+a);
x2:=(-b+r)/(a+a);
SFDAC
TIPRETE ind, x1,x2;
SFALGORITM

I.1.3.3 Algoritmi ciclici
n rezolvarea multor probleme trebuie s efectum aceleai calcule de mai multe ori, sau s
repetm calcule asemntoare. De exemplu, pentru a calcula suma a dou matrice va trebui s
adunm un element al primei matrice cu elementul de pe aceeai poziie din a doua matrice, aceast
adunare repetndu-se pentru fiecare poziie n parte. Alte calcule trebuiesc repetate n funcie de
satisfacerea unor condiii.
n acest scop n limbajul Pseudocod exist trei propoziii standard: CTTIMP, REPET i
PENTRU. Propoziia CTTIMP are sintaxa:

CTTIMP cond EXECUT A SFCT
i cere execuia repetat a grupului de propoziii A, n funcie de condiia "cond". Mai exact, se
evalueaz condiia "cond"; dac aceasta este adevrat se execut grupul A i se revine la evaluarea
condiiei. Dac ea este fals execuia propoziiei se termin i se continu cu propoziia care
urmeaz dup SFCT.
Dac de prima dat condiia este fals grupul A nu se va executa niciodat, altfel se va
repeta execuia grupului de propoziii A pn cnd condiia va deveni fals. Din cauz c nainte de
execuia grupului A are loc verificarea condiiei, aceast structur se mai numete structur
repetitiv condiionat anterior. Ea reprezint structura repetitiv prezentat n Figura I.1.c.
Ca exemplu de algoritm n care se folosete aceast structur ciclic s rezolvm algoritmul
lui Euclid pentru calculul celui mai mare divizor comun a dou numere.
________________________________________________________________________________
17
Structuri de date i algoritmi
_______________________________________________________________________________
Exemplul I.3.
ALGORITMUL Euclid ESTE: {Algoritmul 3: Cel mai mare divizor comun}
CITETE n1,n2; {Cele dou numere a cror divizor se cere}
FIE d:=n1; i:=n2;
CTTIMP i 0 EXECUT
r:=d modulo i; d:=i; i:=r
SFCT
TIPRETE d; { d= cel mai mare divizor comun}
SFALGORITM {al numerelor n1 i n2 }
n descrierea multor algoritmi se ntlnete structura repetitiv condiionat posterior:
REPET A PNCND cond SFREP
structur echivalent cu:

A
CTTIMP not (cond) EXECUT A SFCT
Deci ea cere execuia necondiionat a lui A i apoi verificarea condiiei "cond". Va avea
loc repetarea execuiei lui A pn cnd condiia devine adevrat. Deoarece condiia se verific
dup prima execuie a grupului A aceast structur este numit structura repetitiv condiionat
posterior, prima execuie a blocului A fiind necondiionat.
Ca exemplu de algoritm n care se folosete aceast propoziie vom scrie un algoritm pentru
aproximarea numrului e cu o precizie dat de numrul eps pozitiv, folosindu-ne de dezvoltarea n
serie:
e = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! + ...
Specificaia problemei n Pseudocod este:
DATE eps ; { eps>0 }
REZULTATE ve; { aproximarea seriei cu o eroare < eps }
{ deci r=e-ve<eps }
Pentru rezolvarea problemei trebuie s tim c restul rn din scrierea
________________________________________________________________________________
18
Structuri de date i algoritmi
_______________________________________________________________________________
e = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! + ...
= sn + rn
este mai mic dect ultimul termen adunat la sn, deci rn<tn, unde tn=1/n!. Variabilele auxiliare
folosite n descrierea algoritmului sunt:
n - precizeaz ultima fracie adunat;
t - este valoarea acestei fracii.
Exemplul I.4.

ALGORITMUL NRE ESTE: { Algoritmul 4:Calculul lui e cu precizia eps }
CITETE eps; { eps > 0 }
FIE ve:=2.5; t:=0.5; n:=2;
REPET
n:=n+1
t:=t/n;
ve:=ve+t;
PNCND t < eps SFREP
TIPRETE ve;
SFALGORITM
O alt propoziie care cere execuia repetat a unei secvene A este propoziia
PENTRU c:=li; lf [;p] EXECUT A SFPENTRU
Ea definete o structura repetitiv predefinit, cu un numr determinat de execuii ale
grupului de propoziii A i este echivalent cu secvena:
c:=li ; final:=lf ;
REPET
A
c:=c+p
PNCND (c>final i p>0) sau (c<final i p<0) SFREP

Se observ c, n sintaxa propoziiei PENTRU, pasul p este nchis ntre paranteze drepte.
Prin aceasta indicm faptul c el este opional, putnd s lipseasc. n cazul n care nu este prezent,
valoarea lui implicit este 1.
________________________________________________________________________________
19
Structuri de date i algoritmi
_______________________________________________________________________________
Semnificaia propoziiei PENTRU este clar. Ea cere repetarea grupului de propoziii A
pentru toate valorile contorului c cuprinse ntre valorile expresiilor li i lf (calculate o singur dat
nainte de nceperea ciclului), cu pasul p. Se subnelege c nu trebuie s modificm valorile
contorului n nici o propoziie din grupul A. De multe ori aceste expresii sunt variabile simple, iar
unii programatori modific n A valorile acestor variabile, nclcnd semnificaia propoziiei
PENTRU. Deci,
Obs: Nu recalcula limitele i nu modifica variabila de ciclare (contorul) n interiorul unei structuri
repetitive PENTRU.
S observm, de asemenea, c prima execuie a grupului A este obligatorie, abia dup
modificarea contorului verificndu-se condiia de continuare a execuiei lui A.
Ca exemplu, s descriem un algoritm care gsete minimul i maximul componentelor unui
vector de numere reale.
Vom nota prin X acest vector, deci X = (x
1
, x
2
, ... , x
n
).
Specificaia problemei este urmtoarea:
DATE n,(x[i] ,i=1,n);
REZULTATE valmin,valmax;
iar semnificaia acestor variabile se nelege din cele scrise mai sus. Pentru rezolvarea problemei
vom examina pe rnd cele n componente. Pentru a parcurge cele n componente avem nevoie de un
contor care s precizeze poziia la care am ajuns. Fie i acest contor. Uor se ajunge la urmtorul
algoritm:
Exemplul I.5.

ALGORITMUL MINMAX ESTE: { Algoritmul 5: Calculul }
{ valorii minime i maxime }
CITETE n,( x[i],i=1,n);
FIE valmin:=x[1]; valmax:=x[1];
PENTRU i:=2;n EXECUT
DAC x[i]<valmin
ATUNCI valmin:=x[i ];
SFDAC
DAC x[i]>valmax
ATUNCI valmax:=x[i];
SFDAC
________________________________________________________________________________
20
Structuri de date i algoritmi
_______________________________________________________________________________
SFPENTRU
TIPRETE valmin,valmax;
SFALGORITM

Un rol important n claritatea textului unui algoritm l au denumirile alese pentru variabile.
Ele trebuie s reflecte semnificaia variabilelor respective. Deci alege denumiri sugestive pentru
variabile, care s reflecte semnificaia lor. Putem formula astfel regula de mai jos:
Obs:. Alege denumiri sugestive pentru variabile! n exemplul de mai sus denumirile valmin i
valmax spun cititorului ce s-a notat prin aceste variabile.
I.1.4 Calculul efectuat de un algoritm
Fie X
1
, X
2
, ..., X
n
, variabilele ce apar n algoritmul A. n orice moment al execuiei
algoritmului, fiecare variabil are o anumit valoare, sau este nc neiniializat.
Vom numi stare a algoritmului A cu variabilele menionate vectorul s = ( s
1
,s
2
,...,s
n
) format
din valorile curente ale celor n variabile ale algoritmului.
Este posibil ca variabila X
j
s fie nc neiniializat, deci s nu aib valoare curent, caz n
care valoarea s
j
este nedefinit, lucru notat n continuare prin semnul ntrebrii '?'.
Prin executarea unei anumite instruciuni unele variabile i schimb valoarea, deci
algoritmul i schimb starea.
Se numete calcul efectuat de algoritmul A o secven de stri s
0
, s
1
, s
2
, ..., s
m
unde s
0
este
starea iniial cu toate variabilele neiniializate, iar s
m
este starea n care se ajunge dup execuia
ultimei propoziii din algoritm.
Exemplul I.6
Algoritmul Nrdivizori calculeaz numrul de divizori proprii ai unui numr dat X1.
P1 CITESTE X1;
P2 FIE X2:=1;
P3 FIE X3:=0;
P4 CTTIMP X1 X2 EXECUT
P5 X2:=X2+1;
P6 DAC X1 modulo X2 = 0
ATUNCI X3:=X3+1
________________________________________________________________________________
21
Structuri de date i algoritmi
_______________________________________________________________________________
SFDAC
SFCT
P7 TIPRETE X1,X3
Presupunnd c X1 = 6, atunci strile prin care trece acest algoritm, deci calculul efectuat
de el, este redat mai jos.
s0 = ( ?, ?, ?)
P1(s0) = s1 = ( 6, ?, ?)
P2(s1) = s2 = ( 6, 1, ?)
P3(s2) = s3 = ( 6, 1, 0)
P5(s3) = s4 = ( 6, 2, 0)
P6(s4) = s5 = ( 6, 2, 1)
P5(s5) = s6 = ( 6, 3, 1)
P6(s6) = s7 = ( 6, 3, 2)
P5(s7) = s8 = ( 6, 4, 2)
P6(s8) = s9 = ( 6, 4, 2)
P5(s9) = s10= ( 6, 5, 2)
P6(s10)= s11= ( 6, 5, 2)
P6(s11)= s12= ( 6, 5, 2)
P5(s12)= s13= ( 6, 6, 2)
P7(s13)= s14= ( 6, 6, 2)
Execuia (calculul) se va ncheia cu tiprirea valorilor 6 i 2 a celor dou variabile din
propoziia P7. Se poate observa c cele dou valori tiprite reprezint, prima (X1), numrul citit, iar
a doua (X3), rezultatul obinut. Rezultatul X3 reprezint numrul divizorilor proprii ai lui X1.

I.1.5 Rafinare n pai succesivi
Adeseori, algoritmul de rezolvare a unei probleme este rezultatul unui proces complex, n
care se iau mai multe decizii. Observaia este adevrat mai ales n cazul problemelor complicate,
dar i pentru probleme mai simple din procesul de nvmnt. Este vorba de un proces de detaliere
pas cu pas a specificaiei problemei, proces denumit i proiectare descendent, sau rafinare n pai
succesivi. Algoritmul apare n mai multe versiuni succesive, fiecare versiune fiind o detaliere a
versiunii precedente.
n versiunile iniiale apar propoziii nestandard, clare pentru cititor, dar neprecizate prin
propoziii standard. Urmeaz ca n versiunile urmtoare s se revin asupra lor. Algoritmul apare
________________________________________________________________________________
22
Structuri de date i algoritmi
_______________________________________________________________________________
astfel n versiuni succesive, tot mai complet de la o versiune la alta.
Ca exemplu de algoritm obinut prin rafinare succesiv vom proiecta un algoritm care s
rezolve urmtoarea problem:
Exemplul I.7
Se dau numerele ntregi X = (x1, x2, ..., xn). Se cere s se rein ntr-un vector Y toate
componentele distincte ale vectorului X (deci Y are numai componente distincte).
Specificarea problemei:
DATE n, (x[i], i=1,n);
REZULTATE (y[j], j=1,k); {X=Y, unde X este mulimea ce}
{conine toate numerele xi, iar Y = mulimea}
{ce conine pe y[j], j=1,k i y[l]<>y[j] pentru lj}
Variabilele intermediare folosite i semnificaia lor, precum i metoda folosit vor fi
rezultatul rafinrilor succesive i vor fi nelese din versiunilor respective.
Exemplul I.8
ALGORITMUL DISTINCT ESTE: { Versiunea 1 }
CITETE n, (x[i], i=1,n);
FIE y[1]:=x[1]; k:=1;
@Examineaz celelalte numere i dac trebuie adaug-le n Y.
TIPRETE (y[j], j=1,k);
SFALGORITM
Pentru a parcurge celelalte numere avem nevoie de un contor, fie el i, i de folosirea
propoziiei PENTRU. Ajungem la varianta:
Exemplul I.9
ALGORITMUL DISTINCT ESTE: { Versiunea 2 }
CITETE n, (x[i], i=1,n);
FIE y[1]:=x[1]; k:=1;
PENTRU i:=2;n EXECUT
@Verific dac xi aparine mulimii Y.
@Dac nu aparine atunci adaug pe xi la Y.
SFPENTRU
TIPRETE (y[j], j=1,k);
SFALGORITM
________________________________________________________________________________
23
Structuri de date i algoritmi
_______________________________________________________________________________
Decizia ce trebuie luat este cum s verificm apartenena unui elementul x
i
la mulimea Y
format din k elemente. Pentru aceasta calculm indicatorul r, egal cu 0 dac rspunsul este negativ
i egal cu 1 n caz contrar. Aceasta se poate face cu secvena de propoziii:
FIE r:=0; j:=1;
CTTIMP (r=0) i (j<=k) EXECUT
DAC x[i]=y[j]
ATUNCI r:=1
ALTFEL j:=j+1
SFDAC
SFCT
Ajungem la versiunea final a algoritmului dorit:
Exemplul I.10
ALGORITMUL DISTINCT ESTE: { Versiunea 3 }
CITETE n, (x[i], i=1,n);
FIE y[1]:=x[1]; k:=1;
PENTRU i:=2;n EXECUT
FIE r:=0; j:=1;
CTTIMP (r=0) i (j<=k) EXECUT
DAC x[i]=y[j]
ATUNCI r:=1;
ALTFEL j:=j+1;
SFDAC
SFCT
DAC r=0
ATUNCI k:=k+1; y[k]:=x[i];
SFDAC
________________________________________________________________________________
24
Structuri de date i algoritmi
_______________________________________________________________________________
SFPENTRU
TIPRETE (y[j], j=1,k);
SFALGORITM
Rezult ca o consecin, o alt regul important n proiectarea algoritmului:
Obs: Amn pe mai trziu detaliile nesemnificative; concentreaz-i atenia la deciziile importante
ale momentului.
I.1.6. Probleme propuse
S se scrie algoritmi pentru rezolvarea urmtoarelor probleme:
1. Se d numrul natural n. S se determine primele n numere prime.
2. Se d nN. S se determine primele n triplete de numere pitagorice. (Tripletul (i,j,k) constituie
numere pitagorice dac i<j<k i i
2
+j
2
= k
2
).
3. Tripletul (z,l,a) reprezint o dat curent zi, lun, an. Determinai a cta zi din an este aceast
dat.
4. Se cunoate data curent (zc,lc,ac) i ziua de natere a unei persoane (zn,ln,an). Determinai
vrsta n zile a acestei persoane.
5. Cunoscnd n ce zi din sptmn a fost 1 ianuarie, determinai ce zi din sptmn va fi n ziua
precizat prin tripletul (z,l,a).
I.2. SUBALGORITMI
I.2.1. Conceptul de subalgoritm
Orice problem poate apare ca o subproblem S a unei probleme mai complexe C.
Algoritmul de rezolvare a problemei S devine n acest caz o parte din algoritmul de rezolvare a
problemei C, parte numit subalgoritm.
Pentru a defini un subalgoritm vom folosi propoziia standard:
SUBALGORITMUL nume(lpf) ESTE:
unde nume este numele subalgoritmului definit, iar lpf este lista parametrilor formali. Acetia sunt
formai din variabilele care marcheaz datele de intrare (cele presupuse cunoscute) i variabilele
care marcheaz datele de ieire (rezultatele obinute de subalgoritm).
________________________________________________________________________________
25
Structuri de date i algoritmi
_______________________________________________________________________________
Aceast propoziie este urmat de textul efectiv al subalgoritmului, text care precizeaz
calculele necesare rezolvrii subproblemei corespunztoare. Descrierea se va ncheia cu cuvntul
SFSUBALGORITM sau SF-nume.
Exemplul I.11
S considerm ca exemplu un subalgoritm cu numele MAXIM, care determin maximul
dintre componentele vectorului X = (x
1
, x
2
, ..., x
n
).
Datele cunoscute pentru acest subalgoritm sunt vectorul X i numrul n al componentelor
vectorului X. Ca rezultat vom obine maximul cerut, pe care-l vom nota cu max. n concluzie
specificarea subproblemei este:
DATE n, X
REZULTATE max
Deci lista parametrilor formali conine trei variabile, n, X i max. Pentru a gsi maximul
parcurgem toate componentele vectorului X, reinnd n variabila max valoarea cea mai mare
ntlnit. Evident, trebuie s ncepem cu max = x1. Subalgoritmul este prezentat n continuare.
SUBALGORITMUL maxim(n,X,max) ESTE: {Calculeaz valoarea maxim}
{dintre cele n componente ale lui X}
FIE max:=x[1];
PENTRU i:=2;n EXECUT
DAC x[i]>max
ATUNCI max:=x[i];
SFDAC
SFPENTRU
SF-maxim

Una dintre greelile frecvente ale nceptorilor const n introducerea n corpul
subalgoritmului a unor instruciuni de citire a datelor presupuse cunoscute, sau de tiprire a
rezultatelor obinute. Acest lucru denot o nenelegere a conceptului de subalgoritm i a rolului
subalgoritmilor n programare. Subalgoritmul rezolv o subproblem - care e o parte dintr-o
problema complex de rezolvat.
De obicei, datele presupuse cunoscute pentru subproblem, nu sunt datele iniiale cunoscute
n problema iniial; ele sunt rezultatul unor calcule efectuate nainte de apelul subalgoritmului. n
general, ele nu sunt cunoscute de programator, fiind rezultatul unor calcule fcute de algoritm.
Analog, rezultatele obinute de subalgoritm sunt adesea doar valori intermediare, necesare n
continuare, fr a fi ns obligatoriu i rezultate ale problemei iniiale. De aceea nu este necesar s
le tiprim; este sarcina algoritmului apelant s trateze rezultatele obinute de subalgoritm cum crede
de cuviin.
Obs. Evit s citeti i s tipreti ntr-un subalgoritm.
Excepie de la aceast regul o fac subalgoritmii dedicai citirilor unor date, sau tipririlor
unor rezultate. n acest caz, citirea, respectiv tiprirea unor date este cerut expres n enunul
________________________________________________________________________________
26
Structuri de date i algoritmi
_______________________________________________________________________________
subproblemelor corespunztoare. Mai mult, un subalgoritm este scris pentru a rezolva subproblema
corespunztoare indiferent de locul, timpul sau complexitatea problemei n care este folosit. De
aceea, trebuie s concepem subalgoritmii cu gndul la refolosirea lor.
Obs. Concepe un subalgoritm indiferent de contextul n care va fi folosit.
S considerm n cele ce urmeaz, urmtorul exemplu. n cadrul multor algoritmi este
necesar calculul valorilor unei funcii n diferite puncte. Este necesar s definim funcia printr-un
subalgoritm de tip funcie.
Pentru definirea unui subalgoritm de tip funcie se folosete un antet care precizeaz numele
funciei i variabilele de care depinde ea. Subalgoritmul are forma:
FUNCIA nume(lpf) ESTE: {Antetul funciei}
ext {corpul funciei}
SF-nume {marca de sfrit}
n corpul funciei trebuie s existe cel puin o instruciune de atribuire n care numele
funciei apare n membrul stng, deci prin care funcia primete o valoare.

Exemplul I.12
S considerm funcia numar : R {2,3,4,5}, definit matematic astfel:

n Pseudocod descrierea este urmtoarea:
FUNCIA numar(x) ESTE:
DAC x<0.2
ATUNCI numar:=2
ALTFEL
DAC x<0.5
ATUNCI numar:=3
ALTFEL
DAC x<0.9
ATUNCI numar:=4
ALTFEL numar:=5
SFDAC
________________________________________________________________________________
27
Structuri de date i algoritmi
_______________________________________________________________________________
SFDAC
SFDAC
SF-numar
Am vzut c definiia unei funcii const dintr-un antet i dintr-un bloc care va defini
aciunile prin care se calculeaz valoarea funciei. n antet se precizeaz numele funciei i lista
parametrilor formali.
n concluzie, exist dou categorii de subalgoritmi: de tip funcie i subalgoritmi propriu-
zii, crora li se mai spune i proceduri. Importana lor va fi subliniat prin toate exemplele care
urmeaz n acest curs. n ncheiere menionm c subprogramele de tip funcie se folosesc n scopul
definirii funciilor, aa cum sunt cunoscute ele din matematic, n timp ce subalgoritmii de tip
procedur se refer la rezolvarea unor probleme ce apar ca subprobleme, fiind algoritmi de sine
stttori.

I.2.2. Apelul unui subalgoritm
Am vzut c un subalgoritm este dedicat rezolvrii unei subprobleme S care apare ntr-o
problem mai complex C. Algoritmul corespunztor problemei C va folosi toate operaiile
necesare rezolvrii problemei S, deci va folosi ca parte ntregul subalgoritm conceput pentru
rezolvarea subproblemei S. Spunem c el va apela acest subalgoritm.
n Pseudocod apelul unei funcii se face scriind ntr-o expresie numele funciei urmat de lista
parametrilor actuali. Trebuie s existe o coresponden biunivoc ntre parametrii actuali i cei
formali folosii n definiia funciei. Dei denumirile variabilelor din cele dou liste pot s difere,
rolul variabilelor care se corespund este acelai. Mai exact, parametrul formal i parametrul actual
corespunztor trebuie s se refere la aceeai entitate, trebuie s aib aceeai semnificaie, s
reprezinte aceeai structur de date. Putem considera c n timpul execuiei algoritmului cei doi
parametri devin identici.
Folosirea unui subalgoritm n cadrul unui algoritm se face apelnd acest subalgoritm prin
propoziia standard:
CHEAM nume(lpa);
unde nume este numele subalgoritmului apelat, iar lpa este lista parametrilor actuali. Aceast list
conine toate datele de intrare (cele cunoscute n subproblema corespunztoare) i toate rezultatele
obinute n subalgoritm. i n acest caz ntre lista parametrilor formali din definiia subalgoritmului
i lista parametrilor actuali din propoziia de apel trebuie s existe o coresponden biunivoc, ca i
n cazul funciilor.
Ca o prim verificare a respectrii acestei corespondene, subliniem c numrul parametrilor
actuali trebuie s coincid cu numrul parametrilor formali.
Ca exemplu de apelare a funciilor, prezentm n continuare un algoritm pentru a calcula a
cta zi din anul curent este ziua curent (zi, luna, an). El folosete un subalgoritm de tip funcie
pentru a obine numrul zilelor lunii cu numrul de ordine i i un altul pentru a verifica dac un an
________________________________________________________________________________
28
Structuri de date i algoritmi
_______________________________________________________________________________
este bisect sau nu. Aceste dou funcii sunt:
- NRZILE(i) furnizeaz numrul zilelor existente n luna i a unui an nebisect;
- BISECT(an) adevrat dac anul dintre paranteze este bisect.
Exemplul I.13
ALGORITMUL NUMR_ZILE ESTE: {A cta zi dintr-un an?}
CITETE zi, luna, an; {introducei data curent}
FIE nr:=zi; {nr va fi numrul care reprezint a cta zi }
{din an este data curent}
DAC luna>1 ATUNCI
PENTRU i:=1, Luna-1 EXECUT
nr:=nr+NRZILE(i)
SFPENTRU
SFDAC
DAC luna>2 ATUNCI
DAC BISECT(an) ATUNCI
nr:=nr+1
SFDAC
SFDAC
TIPRETE nr;
SFALGORITM

S observm c n proiectarea acestui algoritm nu este necesar s cunoatem detaliat
subalgoritmii folosii, ci doar specificarea acestor subalgoritmi, numele lor i lista parametrilor
formali. La acest nivel accentul trebuie s cad pe proiectarea algoritmului apelant, urmnd s se
revin ulterior la proiectarea subalgoritmilor apelai, conform specificaiei acestora. n cazul de fa
este necesar descrierea funciilor NRZILE(i) i BISECT(an). Lsm aceast descriere ca exerciiu
pentru cititor.
Exemplul I.14
Un alt exemplu de apelare a unei proceduri este algoritmul care efectueaz suma a dou
polinoame.
Un polinom P(X) este determinat prin gradul su, m, i prin vectorul coeficienilor P = (p
0
,
p
1
, ..., p
m
) (prin p
i
s-a notat coeficientul lui X
i
).
Procedura SUMAPOL(m,P,n,Q,r,S) trebuie s efectueze suma S(X) = P(X)+Q(X), unde P
este un polinom de gradul m, iar Q este un polinom de gradul n, date. Suma lor, S, va fi un polinom
de gradul r calculat de subalgoritm. Pentru efectuarea acestui calcul este util folosirea unui alt
subalgoritm care adun la suma S(X) un alt polinom, T(X), de grad mai mic sau egal dect gradul
polinomului S(X). Un astfel de subalgoritm se prezint n continuare.
SUBALGORITMUL SUMAPOL1(n,T,r,S) ESTE: { n r}
________________________________________________________________________________
29
Structuri de date i algoritmi
_______________________________________________________________________________
{S(X):=S(X)+T(X)}
PENTRU i:=0;n EXECUT
s[i] := s[i] +t[i];
SFPENTRU
SF-SUMAPOL1
Subalgoritmul SUMAPOL apeleaz acest subalgoritm, aa cum se poate vedea n
continuare.
SUBALGORITMUL SUMAPOL(m,P,n,Q,r,S) ESTE: {S(X):=P(X)+Q(X)}
DAC m<n
ATUNCI r:=n; S:=Q;
CHEAM SUMAPOL1(m,P,r,S)
ALTFEL r:=m; S:=P;
CHEAM SUMAPOL1(n,Q,r,S)
SFDAC
SF-SUMAPOL

S observm c n textul acestui subalgoritm am extins semnificaia propoziiei de atribuire,
permind atribuirea S:=Q. Acest lucru este normal ntruct S corespunde unui polinom, iar Q este
un polinom cunoscut; prin atribuire S primete o valoare iniial, cea dat de polinomul Q.
Subliniem c atribuirea v := u va fi corect n cazul n care variabilele u i v reprezint
aceleai obiecte matematice, deci au aceeai semnificaie.

I.2.3. Elaborarea algoritmilor. Propoziii nestandard
Prin elaborarea (proiectarea) unui algoritm nelegem ntreaga activitate depus de la enunarea
problemei pn la realizarea algoritmului corespunztor rezolvrii acestei probleme.
n elaborarea unui algoritm deosebim urmtoarele activiti importante (Andonie i Grbacea
[1995]):
specificarea problemei;
descrierea metodei alese pentru rezolvarea problemei;
proiectarea propriu-zis. Ea const n descompunerea problemei n subprobleme, obinerea
algoritmului principal i a tuturor subalgoritmilor apelai, conform metodelor prezentate n
seciunile urmtoare. Ea se termin cu descrierea algoritmului principal i a subalgoritmilor
menionai, dar i cu precizarea denumirilor i semnificaiilor variabilelor folosite;
verificarea algoritmului obinut.
Astfel, s considerm urmtorul exemplu, calculul radicalului de ordinul 2 din x.

a. n partea de specificare a problemei vom meniona:
Se d un numr real notat prin x, care trebuie s fie nenegativ. Se cere s gsim un alt numr
________________________________________________________________________________
30
Structuri de date i algoritmi
_______________________________________________________________________________
pozitiv r astfel nct x = r.
Vom folosi un algoritm de aproximare a lui r. Deci specificarea fcut nu este complet,
neputnd gsi un algoritm care s rezolve direct problema n forma enunat. Vom modifica aceast
specificare, cernd s se calculeze r aproximativ, cu o eroare ce nu depete un numr real pozitiv
eps prestabilit. Ajungem astfel la urmtoarea specificare:
DATE eps,x; { eps, R x , eps>0 i x 0 }
REZULTATE r; {
x r
< eps }
b. Urmeaz s precizm metoda de rezolvare a problemei. Se tie c exist mai multe metode de
calcul al radicalului. Menionm urmtoarele dou posibiliti:
- ca limit a unui ir convergent la r (definit printr-o relaie de recuren);
- prin aproximarea soluiei ecuaiei x = r.
Alegem pentru exemplificare metoda a doua, deci l vom calcula pe r rezolvnd ecuaia x
= r.
Pentru rezolvarea ecuaiei generale f (x) = 0 exist mai multe metode. Alegem pentru
rezolvare metoda coardei i a tangentei.
Aceast metod const n micorarea repetat a intervalului [a,b] care conine rdcina r
cutat, la intervalul [a',b'], aa cum se poate vedea n Figura 1.2. Variabilele folosite n descrierea
algoritmului sunt:
a i b, reprezentnd capetele intervalului n care se afl rdcina;
r mijlocul intervalului (a,b) n momentul n care b-a < eps, deci valoarea cutat.


Figura 1.2.: Grafic pentru metoda coardei i a tangentei.
Algoritmul propriu-zis (secvena de propoziii care obine rezultatele dorite pornind de la
________________________________________________________________________________
31
Structuri de date i algoritmi
_______________________________________________________________________________
datele iniiale) este descris n continuare:

Exemplul I.15
{Algoritmul 3.3: Metoda coardei i a tangentei}
@Iniializeaz pe a i b.
REPET
@Atribuie lui a abscisa punctului de intersecie a axei OX cu coarda ce unete punctele
(a,f(a)) i (b,f(b)).
@Atribuie lui b abscisa punctului de intersecie a axei OX cu tangenta n punctul (b,f(b))
dus la graficul funciei f(t) = t - x .
PNCND b-a<eps SFREP
FIE r:=(a+b)/2;
n textul de mai sus apar trei propoziii nestandard care sugereaz ns foarte bine ce aciuni
trebuiesc ntreprinse. Prima stabilete intervalul iniial n care se afl rdcina, care depinde de
mrimea lui x: (x,1) cnd x este mai mic dect 1 sau (1,x) n caz contrar. Deci ea se va transcrie n
propoziia standard:
DAC x<1
ATUNCI a:=x; b:=1;
ALTFEL a:=1; b:=x;
SFDAC
Celelalte dou propoziii nestandard se vor transcrie n propoziiile standard:
FIE a := E1; b := E2 ;
unde E1 este expresia care reprezint abscisa punctului de intersecie a axei OX cu coarda ce
unete punctele (a,f(a)) i (b,f(b)), iar E2 este expresia care reprezint abscisa punctului de
intersecie a axei OX cu tangenta n punctul (b,f(b)) dus la graficul funciei f(t) = t - x.
Se ajunge la urmtoarea variant final:
Exemplul I.16

ALGORITMUL EXTRAGRADICAL ESTE: { Radical }
{ r := radical din x }
CITESTE eps,x; { eps, R x , eps>0 i x 0 }
DAC x<1
ATUNCI a:=x; b:=1; { Iniializeaz }
ALTFEL a:=1; b:=x; { pe a i b }
SFDAC
________________________________________________________________________________
32
Structuri de date i algoritmi
_______________________________________________________________________________
REPET
a := E1; {abscisa punctului de intersecie a axei OX cu}
{coarda ce unete punctele (a,f(a)) i (b,f(b))}
b := E2; {abscisa punctului de intersecie a axei OX cu tangenta}
{ n punctul (b,f(b)) dus la graficul funciei f(t) = t2-x }
PNCND b-a<eps SFREP
FIE r:=(a+b)/2;
TIPRETE r; { r-rad(x)<eps }
SF-EXTRAGRADICAL

I.2.4. Proiectarea ascendent i proiectarea descendent
Exist dou metode generale de proiectare a algoritmilor, a cror denumire provine din
modul de abordare a rezolvrii problemelor: metoda descendent i metoda ascendent. Proiectarea
descendent (top-down) pornete de la problema de rezolvat, pe care o descompune n pri
rezolvabile separat. De obicei aceste pri sunt subprobleme independente, care la rndul lor pot fi
descompuse n subprobleme. La prima descompunere accentul trebuie pus pe algoritmul (modulul)
principal nu asupra subproblemelor. La acest nivel nu ne intereseaz amnunte legate de rezolvarea
subproblemelor, presupunem c le tim rezolva, eventual c avem deja subalgoritmii pentru
rezolvarea lor. Urmeaz s considerm pe rnd, fiecare subproblem n parte i s proiectm (n
acelai mod) un subalgoritm pentru rezolvarea ei. n final, se va descrie subalgoritmul de rezolvare
al fiecrei subprobleme, dar i interaciunile dintre aceti subalgoritmi i ordinea n care ei sunt
folosii.
Noiunea de modul va fi definit n seciunea urmtoare. Deocamdat nelegem prin modul
orice subalgoritm sau algoritmul principal. Legtura dintre module se prezint cel mai bine sub
forma unei diagrame numit arbore de programare (Blaga P. et al. [1978]). Fiecrui modul i
corespunde n arborele de programare un nod, ai crui descendeni sunt toate modulele apelate
direct. Nodul corespunztor algoritmului principal este chiar nodul rdcin.
Astfel, n arborele de programare din Figura.1.3 exist un algoritm principal (modulul
PRINC), care apeleaz trei subalgoritmi (modulele CITDATE, CALCULE i TIPREZ). La rndul
su, modulul CALCULE apeleaz trei subalgoritmi (modulele M1, M2 i M3).


________________________________________________________________________________
33
Structuri de date i algoritmi
_______________________________________________________________________________
Figura1.3. Arbore de programare.
Din arborele de programare nu reiese ns de cte ori se apeleaz un subalgoritm, sau dac
doi subalgoritmi se exclud unul pe cellalt. Este posibil nlocuirea arborelui de programare cu o
diagram de structur construit pe concepia NESTED-LOGIC. n construirea unei astfel de
diagrame se folosesc structurile din Figura.1.4, bazate pe urmtoarele reguli (Livovschi L. [1980]):
a) Operaia de trecere de la un nivel superior la unul inferior se interpreteaz prin expresia
"CONST DIN" (fig.a);
b) Operaia de trecere de la un bloc la altul de pe acelai nivel se interpreteaz cu expresia
"URMAT DE" (fig.a);
c) Caracterul 'o' prezent n bloc n colul din dreapta sus este descendentul unui bloc de tip
selectiv (fig.b);
d) Caracterul '*' prezent n bloc n colul din dreapta sus identific un bloc repetitiv i se
interpreteaz cu expresia "MAI MULTE" (fig.c).


Figura. 1.4. Diagrame de structur construit pe concepia NESTED-LOGIC.

Teorema de structur NESTED-LOGIC afirm c oricare ar fi schema logic S exist o
schem S' de structur NESTED-LOGIC echivalent cu S (deci care rezolv aceeai problem).
Ca exemplu de proiectare descendent, descriem n continuare un algoritm pentru
rezolvarea unui sistem liniar de n ecuaii cu n necunoscute:
A*X = B
La primul nivel de descompunere deosebim trei activiti distincte:
- citirea datelor problemei;
- rezolvarea sistemului menionat;
- tiprirea rezultatelor.
Pentru rezolvarea sistemului vom proiecta un subalgoritm, ntruct aceast problem poate
apare adesea ca subproblem i dorim s refolosim subalgoritmul obinut. Pentru rezolvarea
________________________________________________________________________________
34
Structuri de date i algoritmi
_______________________________________________________________________________
sistemului identificm dou subprobleme independente:
- reducerea sistemului, prin metoda lui Gauss, la un sistem triunghiular echivalent;
- rezolvarea sistemului triunghiular obinut.
Mai mult, subproblema reducerii sistemului conine ca subprobleme determinarea ecuaiei
n care rmne xi i care este folosit la reducerea acestei necunoscute din celelalte ecuaii,
schimbarea a dou ecuaii ntre ele, deci interschimbarea a dou linii din matricea extins i
eliminarea propriu-zis. Subalgoritmul PIVOT, corespunztor primei subprobleme, determin care
dintre ecuaiile de rang i, i+1, ..., n are coeficientul lui xi maxim n valoare absolut, caz n care
erorile introduse din cauza aproximrilor n calcule cu numere reale sunt minime. Subalgoritmii
INTERSCHIMB i ELIMIN corespund celorlalte dou subprobleme. Arborele de programare
corespunztor se d n Figura.1.5.
Exemplul I.17
Algoritmul REZSISTEM este:
Cheam CITSISTEM(n, A, B)
Cheam SISTEM(n, A, B, kod)
Dac kod = 1 atunci Cheam TIPSOL(n, B)
altfel Tiprete "Sistemul nu este compatibil determinat."
sfdac
sf-RezSistem


Figura 1.5. Arborele de programare pentru rezolvarea sistemului
Subalgoritmul SISTEM pentru rezolvarea unui sistem liniar de n ecuaii cu n necunoscute
este prezentat n continuare.
________________________________________________________________________________
35
Structuri de date i algoritmi
_______________________________________________________________________________
Subalgoritmul SISTEM(n,A,B,kod) este: {Rezolv sistemul AX=B, de n ecuaii cu n
necunoscute}
{A este matricea sistemului, B vectorul termenilor liberi i}
{Soluia se depune n vectorul B, iar A se distruge}
{kod = 1 pentru sistem compatibil, altfel kod = 0 }
Cheam REDUTRI(n,A,B,kod); {Reduce sistemul la un sistem triunghiular echivalent}
Dac kod = 1 atunci {kod = 1 cnd sistemul e compatibil}
Cheam REZOLV(n,A,B,kod); {Rezolv sistemul triunghiular}
sfdac {Soluia se depune n vectorul B}
sf-SISTEM

Subalgoritmul REDUTRI(n,A,B,kod) este: {Reduce sistemul liniar A.X=B, de n ecuaii cu
n necunoscute la un sistem triunghiular echivalent}
{ A'.X = B', matricea A' avnd sub diagonal numai zerouri}
{A este matricea sistemului iar B - vectorul termenilor liberi}
{kod = 0 pentru sistem nedeterminat sau incompatibil}
Fie kod:=1; {Ipoteza sistem determinat}
i:=1;
Cttimp (i<n) i (kod=1) execut {Se reduce necunoscuta x
i
din ecuaiile i+1,...,n}
Cheam PIVOT(n,A,i,j); {j = numrul ecuaiein care se pstreaz necu-}
Dac a[i,j]=0 {noscuta x[j]}
atunci kod:=0 altfel
Dac j>i
atunci Cheam INTERSCHIMB(i,j,n,A,B)
sfdac
Cheam ELIMIN(n,A,B,i);
sfdac
Fie i:=i+1;
sfct
sf-REDUTRI

Subalgoritmul REZOLV(n,A,B,ind) este: {Rezolva sistemul triunghiular A.X=B}
{deci matricea A are sub diagonala}
________________________________________________________________________________
36
Structuri de date i algoritmi
_______________________________________________________________________________
{numai zerouri. ind=1 pt.sistem determinat}
{in care caz solutia se pune in vectorul B}
{si ind=0 dac e nedeterminat sau incompatibil}
Fie r1:=b[n]; ind:=1;
Dac a[n,n]=0
atunci ind:=0
altfel b[n]:=r1/a[n,n]
sfdac
Fie i:=n-1;
Cttimp (ind=1) i (i>=1) execut
Dac a[i,i]=0
atunci ind:=0
altfel
r1:=b[i];
Pentru k:=i+1,n execut
r:=a[i,k]*b[k]; r1:=r1-r;
sfpentru
b[i]:= r1/a[i,i]
sfdac
Fie i:=I-1
sfct
sf-REZOLV

Subalgoritmul PIVOT(n,A,i,j) este: {j primete o valoare >=i pentru care}
Fie j:=i; { a[j,i] e maxim n valoare absolut}
Pentru l:=i+1, n execut
Dac a[l,i] > a[j,i]
atunci j:=l
sfdac
sfpentru
sf-PIVOT

Subalgoritmul INTERSCHIMB(i,j,n,A,B) este: {Schimb ntre ele liniile i i j din matricea
A}
________________________________________________________________________________
37
Structuri de date i algoritmi
_______________________________________________________________________________
{ de ordinul n i termenii liberi corespunztori}
Pentru l:=1; n execut
r:=a[i,l]; a[i,l]:=a[j,l]; a[j,l]:=r
sfpentru
Fie r:=b[i]; b[i]:=b[j]; b[j]:=r
sf-INTERSCHIMB;

Subalgoritmul ELIMIN(n,A,B,i) este: {Elimin necunoscuta x[i] din ecuaiile i+1,...,n}
Fie r:=a[i,i]; { x[i] din ecuaiile n ipoteza a[i,i] 0}
Pentru k:=i,n execut {Imparte ecuaia nr i cu r}
Fie a[i,k]:=a[i,k]/r
sfpentru
Fie b[i] := b[i]/r
Pentru j:=i+1,n execut {Elimin necunoscuta}
Fie r:=a[j,i]; {x[i] din ecuaia nr.j}
Pentru k:=1,n execut
a[j,k]:=a[j,k]-r*a[i,k];
sfpentru
Fie b[j]:=b[j]-r*b[i]
sfpentru
sf-ELIMIN

n multe cri metoda top-down este ntlnit i sub denumirea stepwise-refinement, adic
rafinare n pai succesivi. Este vorba de un proces de detaliere pas cu pas a specificaiei, denumit
proiectare descendent. Algoritmul apare n diferite versiuni succesive, fiecare fiind o detaliere a
versiunii precedente. n aceste versiuni succesive apar multe enunuri nestandard ce urmeaz a fi
precizate treptat prin propoziii standard. Se recomand ca ele s rmn comentarii n versiunea
final. Algoritmul apare n versiuni succesive, tot mai complet de la o versiune la alta. n versiunea
final n algoritm apar numai propoziii standard. Un exemplu de rafinare succesiv a fost dat n
seciunea 1.5.
Diferena ntre metoda top-down i metoda rafinrii succesive este neesenial, scopul
urmrit fiind acelai: concentrarea ateniei asupra prilor importante ale momentului i amnarea
detaliilor pentru mai trziu. Dac ar fi necesar s le deosebim am spune c metoda top-down se
refer la nivelul macro iar metoda rafinrii succesive la nivel micro. La nivel macro se dorete
descompunerea unei probleme complexe n subprobleme. La nivel micro se dorete obinerea unui
modul n versiune final. ntr-o versiune intermediar pot fi prezente numai prile importante ale
acestuia, urmnd s se revin asupra detaliilor n versiunile urmtoare, dup ce aspectele importante
________________________________________________________________________________
38
Structuri de date i algoritmi
_______________________________________________________________________________
au fost rezolvate.
Avantajele proiectrii top-down (cunoscut i sub denumirea "Divide et impera") sunt
multiple. Avantajul principal const n faptul c ea permite programatorului s reduc
complexitatea problemei, subproblemele n care a fost descompus fiind mai simple, i s amne
detaliile pentru mai trziu. n momentul n care descompunem problema n subprobleme nu ne
gndim cum se vor rezolva subproblemele ci care sunt ele i conexiunile dintre ele.
Proiectarea descendent permite lucrul n echipe mari. Prin descompunerea problemei n
mai multe subprobleme, fiecare subproblem poate fi dat spre rezolvare unei subechipe. Fiecare
subechip nu cunoate dect subproblema pe care trebuie s o rezolve.
Metoda "Divide et Impera" poate fi folosit nu numai la mprirea problemei n
subprobleme ci i la mprirea datelor n grupe mai mici de date. n acest caz ea este cunoscut sub
numele de metoda divizrii metod prezentat n seciunea 8.1. Un astfel de procedeu este folosit de
subalgoritmul Quicksort, care va fi prezentat n seciunea 7.2.

Metoda ascendent (bottom-up) pornete de la propoziiile limbajului i de la subalgoritmi
existeni, pe care i asambleaz n ali subalgoritmi pentru a ajunge n final la algoritmul dorit. Cu
alte cuvinte, n cazul metodei ascendente va fi scris mai nti subalgoritmul apelat i apoi cel care
apeleaz. Ca rezultat al proiectrii ascendente se ajunge la o mulime de subalgoritmi care se
apeleaz ntre ei. Este important s se cunoasc care subalgoritm apeleaz pe care, lucru redat
printr-o diagram de structur, ca i n cazul programrii descendente.
Aceast metod are marele dezavantaj c erorile de integrare vor fi detectate trziu, abia n
faza de integrare. Se poate ajunge abia acum la concluzia c unii subalgoritmi, dei coreci, nu sunt
utili.
De cele mai multe ori nu se practic o proiectare ascendent sau descendent pur ci o
combinare a lor, o proiectare mixt.

I.2.5. Proiectarea modular
Prin proiectare (programare) modular nelegem metoda de proiectare (programare) a unui
algoritm pentru rezolvarea unei probleme prin folosirea modulelor.
Dar ce este un modul? Modulul este considerat (Frentiu M. et al. [1986]) o unitate
structural de sine stttoare, fie program, fie subprogram, fie o unitate de program. Un modul
poate conine sau poate fi coninut ntr-alt modul. Un modul poate fi format din mai multe
submodule. Astfel, n Pseudocod fiecare subalgoritm i algoritmul principal sunt considerate
module. n limbajele de programare cu structur de bloc, de exemplu n Turbo Pascal UNIT-urile
pot fi considerate module. La compilarea separat un grup de subprograme compilate deodat
constituie un modul, dar acest modul poate fi considerat ca o mulime de submodule din care este
compus.
Este ns important ca fiecare modul s-i aib rolul su bine precizat, s realizeze o funcie
n cadrul ntregului program. El apare n mod natural n descompunerea top-down.
________________________________________________________________________________
39
Structuri de date i algoritmi
_______________________________________________________________________________
Indiferent c privim modulul ca un singur subalgoritm, un grup de subalgoritmi, sau un
algoritm de sine stttor ce apeleaz ali subalgoritmi, considerm modulele relativ independente,
dar cu posibiliti de comunicare ntre ele. Astfel, un modul nu trebuie s fie influenat de maniera
n care se lucreaz n interiorul altui modul. Orice modificare ulterioar n structura unui program,
dac funcia pe care o realizeaz un modul M nc este necesar, acest modul trebuie s fie util i
folosit n continuare fr modificri.
Rezult c programarea modular se bazeaz pe descompunerea problemei n subprobleme
i proiectarea i programarea separat a subalgoritmilor corespunztori. De altfel, considerm c
ntr-o programare serioas nu se poate ajunge la implementare fr a avea n prealabil algoritmii
descrii ntr-un limbaj de descriere (la noi Pseudocod). Deci programarea modular se refer n
primul rnd la proiectarea modular a algoritmilor i apoi la traducerea lor n limbajul de
programare ales, innd seama de specificul acestui limbaj. Programarea modular este strns legat
de programarea ascendent i de programarea descendent, ambele presupunnd folosirea
subalgoritmilor pentru toate subproblemele ntlnite.
Avantajele programrii modulare sunt multiple. Menionm n cele ce urmeaz cteva
dintre ele:
Descompunerea unei probleme complexe n subprobleme este un mijloc convenabil
i eficient de a reduce complexitatea (Principiul Divide et impera acioneaz i n
programare). Este evident c probabilitatea apariiei erorilor n conceperea unui
program crete cu mrimea programului, lucru confirmat i de experiena practic.
De asemenea, rezolvnd o problem mai simpl, testarea unui modul se poate face
mult mai uor dect testarea ntregului algoritm.
Apoi, faptul c trebuiesc proiectate mai multe subprograme pentru subproblemele
ntlnite, permite munca mai multor programatori. S-a ajuns astfel la munca n
echip, modalitate prin care se ajunge la scurtarea termenului de realizare a
produsului program.
Modulele se pot refolosi ori de cte ori avem nevoie de ele. Astfel, s-a ajuns la
compilarea separat a subprogramelor i la pstrarea subprogramelor obinute n
biblioteci de subprograme, de unde ele se pot refolosi la nevoie. Sunt cunoscute
astzi multe astfel de biblioteci de subprograme. Reutilizabilitatea acestor
subprograme este o proprietate foarte important n activitatea de programare. Ea
duce la mrirea productivitii n programare, dar i la creterea siguranei n
realizarea unui produs corect.
Uneori, n timpul proiectrii algoritmului sau a implementrii lui, se ajunge la
concluzia c proiectarea a fost incomplet sau c unele module sunt ineficiente. i n
aceast situaie programarea modular este avantajoas, ea permind nlocuirea
modulului n cauz cu altul mai performant.

Una din activitile importante n realizarea unui program este verificarea corectitudinii
acestuia. Experiena a artat c modulele se pot verifica cu att mai uor cu ct sunt mai mici.
Abilitatea omului de a nelege i analiza corectitudinea unui subalgoritm este mult mai mare pentru
texte scurte. n unele cri chiar se recomand a nu se folosi subalgoritmi mai mari dect 50 de
________________________________________________________________________________
40
Structuri de date i algoritmi
_______________________________________________________________________________
propoziii. Sigur c o astfel de limit nu exist, dar se recomand descompunerea unui subalgoritm
n ali subalgoritmi oricnd acest lucru este posibil n mod natural, deci aceti noi subalgoritmi
rezolv subprobleme de sine stttoare, sau realizeaz funcii bine definite.
Ca exemplu de proiectare modular ne propunem s dm un algoritm pentru rezolvarea
urmtoarei probleme:
Exemplul I.18
S se verifice dac mulimea finit K, pe care s-au definit dou operaii, este corp n raport
cu aceste operaii.
n vederea proiectrii unui algoritm pentru rezolvarea ei avem nevoie de specificarea
problemei. S observm mai nti c nu a fost precizat exact natura elementelor mulimii K = { k
1
,
k
2
, ..., k
n
}.
Trebuie s specificm modul de definire al unei operaii O peste mulimea K. Evident,
pentru a definii o operaie pe mulimea finit K, trebuie ca pentru oricare dou elemente k
i
, k
j
K
s cunoatem O(k[i], k[j]) = k[s] K.
Deci O ar fi o matrice ptratic de ordinul n cu elemente din K. Cum natura acestor
elemente nu este precizat, convenim s reinem doar indicii acestor elemente, cu alte cuvinte s
lucrm cu mulimea K' = { 1, 2, ... , n }.
Ea este precizat prin numrul n. n acest caz definirea operaiei O va fi simpl,
exprimndu-se printr-o matrice ptrat de ordinul n cu elemente din K'. Deci specificarea problemei
este:
DATE n, O1, O2; {O1, O2 = operaii peste K'}
REZULTATE kod {kod = 0 pentru corp, altfel kod > 0}
{Prin valoarea lui kod se poate reine care}
{proprietate din definiia corpului nu a fost ndeplinit}
Trecnd la proiectarea algoritmului, s observm c la citirea datelor se ntlnesc dou
operaii, deci se repet aceleai operaii de dou ori. Tiprirea rezultatului este mult mai simpl: se
tiprete valoarea lui kod. Decidem s folosim un subalgoritm CITOP(n,O) pentru citirea unei
operaii, subalgoritm care va fi apelat n modulul principal de dou ori: prima dat pentru citirea lui
O1, apoi pentru citirea lui O2.
naintea acestor apeluri n modulul principal se va citi valoarea lui n. Apoi se va apela
subalgoritmul CORP(n,O1,O2,kod) pentru verificarea propriu zis. Ea const din trei verificri:
a - este mulimea grup n raport cu operaia O1 ?
b - scznd elementul neutru pentru O1, este noua mulime grup n raport cu O2;
c - este O2 distributiv fa de O1?
________________________________________________________________________________
41
Structuri de date i algoritmi
_______________________________________________________________________________
Putem realiza verificrile a i b cu acelai subalgoritm GRUP(p,n,O,e,kod) care verific
axiomele grupului, reinnd rezultatul n kod, iar n e elementul neutru. Aceasta este posibil dac
elementul neutru pentru O1 este 1, cele dou apeluri fcndu-se prima cu p=1, a doua cu p=2 (deci
elementul neutru pentru O1 este eliminat la a doua verificare). n cazul n care elementul neutru
pentru operaia O1 este e1 vom inter-schimba numerotarea celor dou elemente, deci 1 va deveni
element neutru !
Pentru verificarea axiomelor grupului se folosesc patru module: COMUTATIV, NEUTRU,
INVERS i ASOCIATIV. Ele corespund subalgoritmilor:
COMUTATIV(n,O,kod) verific dac operaia O e comutativ;
NEUTRU(n,O,e) gsete elementul neutru e pentru O (sau e=-1);
INVERS(n,O,e,kod) verific existena inverselor;
ASOCIATIV(n,O,kod) verific dac O este asociativ.
Se ajunge la arborele de programare din Figura.1.6.


Figura 1.6. Arborele de programare pentru verificarea axiomelor corpului.
Ca un al doilea exemplu de definire i folosire a subalgoritmilor, s considerm urmtoarea
problem:
Se dau trei mulimi de numere:
A = { a
1
, a
2
, ... , a
m
}
B = { b
1
, b
2
, ... , b
n
}
C = { c
1
, c
2
, ... , c
p
}
Se cere s se tipreasc n ordine cresctoare elementele fiecrei mulimi, precum i a
mulimilor A B, B C, C A.
n rezolvarea acestei probleme se ntlnesc urmtoarele subprobleme:
________________________________________________________________________________
42
Structuri de date i algoritmi
_______________________________________________________________________________
S1: S se citeasc elementele unei mulimi;
S2: S se efectueze reuniunea a dou mulimi;
S3: S se tipreasc elementele unei mulimi;
S4: S se ordoneze cresctor elementele unei mulimi.
Presupunnd c pentru rezolvarea acestor subprobleme am conceput subalgoritmii:

CITMUL(m,A);
REUNIUNE(m,A,n,B,k,R);
TIPMUL(m,A);
ORDON(m,A);
care sunt specificai mai jos (la locul definirii lor) prin comentarii, algoritmul de rezolvare a
problemei de mai sus este dat n continuare. ntruct operaiile respective se folosesc de mai multe
ori (de 3 ori), am definit un subalgoritm TIPORDON(m,A) care ordoneaz mai nti elementele
mulimii A i apoi le tiprete.
ALGORITMUL OPER-MULTIMI ESTE: { Algoritmul 3.6: Subalgoritmi }
CHEAM CITMUL(m,A);
CHEAM CITMUL(n,B);
CHEAM CITMUL(p,C);
CHEAM TIPORDON(m,A);
CHEAM TIPORDON(n,B);
CHEAM TIPORDON(p,C);
CHEAM REUNIUNE(m,A,n,B,k,R);
CHEAM TIPORDON(k,R);
CHEAM REUNIUNE(n,B,p,C,k,R);
CHEAM TIPORDON(k,R);
CHEAM REUNIUNE(p,C,m,A,k,R);
CHEAM TIPORDON(k,R);
SFALGORITM

Subalgoritmii apelai mai sus sunt definii n continuare.
SUBALGORITMUL CITMUL(n,M) ESTE: {Citete n i M}
CITETE n; {n=nr. elementelor mulimii}
________________________________________________________________________________
43
Structuri de date i algoritmi
_______________________________________________________________________________
CITETE (m[i],i=1,n); {M=mulimea cu elementele m
1
,m
2
,...,m
n
}
SF-CITMUL

SUBALGORITMUL ORDON(n,M) ESTE: {Ordoneaz cresctor cele n}
REPET {elemente ale mulimii M}
FIE ind:=0; {Cazul M este ordonat}
PENTRU i:=1;n-1 EXECUT
DAC m[i]>m[i]+1 ATUNCI {schimb ordinea celor}
FIE t := m[i]; {dou elemente}
m[i]:= m[i]+1; m[i]+1:=t;
ind:=1; {Cazul M nu era ordonat}
SFDAC
SFPENTRU
PNCND ind=0 SFREP
SF-ORDON

SUBALGORITMUL REUNIUNE(m,A,n,B,k,R) ESTE: { R := A U B }
{ k = numrul elementelor mulimii R }
FIE k:=m; R := A;
PENTRU j:=1,n EXECUT
FIE ind:=0; {Ipoteza b
j
nu e in A}
PENTRU i:=1;m EXECUT
DAC b[j]=a[i] ATUNCI
ind:=1 {b
j
este in A}
SFDAC
SFPENTRU
DAC ind=0 ATUNCI
k:=k+1; r[k]:=b[j];
SFDAC
SFPENTRU
SF-REUNIUNE

SUBALGORITMUL TIPMUL(n,M) ESTE: { Tiprete cele n elemente }
PENTRU i:=1;n EXECUT { ale mulimii M }
________________________________________________________________________________
44
Structuri de date i algoritmi
_______________________________________________________________________________
TIPRETE mi
SFPENTRU
SF-TIPMUL

SUBALGORITMUL TIPORDON(n,M) ESTE: { Ordoneaz i tiprete }
CHEAM ORDON(n,M); { elementele mulimii M }
CHEAM TIPMUL(n,M);
SF-TIPORDON

Tot ca exemplu de folosire a subalgoritmilor, vom scrie un algoritm pentru rezolvarea
urmtoarei probleme:
Exemplul I.19
Dirigintele unei clase de elevi dorete s obin un clasament al elevilor n funcie de media
general. n plus, pentru fiecare disciplin n parte dorete lista primilor ase elevi.

n rezolvarea acestei probleme este necesar gsirea ordinii n care trebuiesc tiprii elevii n
funcie de un anumit rezultat: nota la disciplina "j", sau media general. Am identificat prin urmare
dou subprobleme independente, referitoare la:
(1) aflarea ordinii n care trebuie tiprite n numere pentru a le obine ordonate;
(2) tiprirea elevilor clasei ntr-o anumit ordine.

Prima subproblem se poate specifica astfel:
Dndu-se numerele x
1
, x
2
, ... , x
n
, gsii ordinea o
1
, o
2
, ..., o
n
, n care aceste numere devin
ordonate descresctor, adic
x[o
1
] x[o
2
] ... x[o
n
] .
Pentru rezolvarea ei vom da un subalgoritm ORDINE n care intervin trei parametri
formali:
- n, numrul valorilor existente;
- X, vectorul acestor valori;
- O, vectorul indicilor care dau ordinea dorit.
Primii doi parametri marcheaz datele presupuse cunoscute, iar al treilea, rezultatele
calculate de subalgoritm.

SUBALGORITMUL ORDINE(n,X,O) ESTE: {n, numrul valorilor existente; X, vectorul
acestor }
________________________________________________________________________________
45
Structuri de date i algoritmi
_______________________________________________________________________________
{ valor; O, vectorul indicilor care dau ordinea dorit }
PENTRU i:=1; n EXECUT
O[i] :=i ;
SFPENTRU
REPET ind:=0;
PENTRU i:=1;n-1 EXECUT
DAC x[O[i]] < x[O[i+1]] ATUNCI
FIE ind:=1; t:=O[i+1] ;
O[i+1] :=O[i]; O[i] :=t;
SFDAC
SFPENTRU
PANCND ind=0 SFREP
SF-ORDINE

A doua subproblem se poate specifica astfel:
Dndu-se ordinea o
1
,o
2
, ..., o
n
, a elevilor clasei, numele i mediile acestora, s se tipreasc
numele i mediile primilor k elevi n ordinea specificat.
Subalgoritmul TIPAR, dat n continuare, rezolv aceast problem.
SUBALGORITMUL TIPAR(k, NUME, O) ESTE:
PENTRU i:=1;k EXECUT
@Tiprete datele elevului de rang oi.
SFPENTRU
SF-TIPAR

Variabilele folosite pentru problema dat sunt urmtoarele:
- n reprezint numrul elevilor clasei;
- m este numrul disciplinelor la care elevii primesc note;
- NUME este vectorul care reine numele elevilor: NUMEi este numele elevului cu numrul
de ordine i;
- NOTE este matricea notelor elevilor, avnd n linii i m coloane;
NOTE[i,j] este nota elevului cu numele NUME[i] la disciplina cu numrul de ordine j;
NOTE[j] este coloana a j-a a matricei NOTE i reprezint notele elevilor la disciplina j;
- MEDII este vectorul mediilor generale.
________________________________________________________________________________
46
Structuri de date i algoritmi
_______________________________________________________________________________

Algoritmul este:
ALGORITMUL CLASAMENT ESTE: { Algoritmul 3.7: Ordonare }
CITETE m, {numrul disciplinelor i}
n, {al elevilor}
NUME[i], i=1,n, {numele elevilor}
NOTE[i,j], j=1,m, i=1,n; {notele elevilor}
PENTRU i:=1;n EXECUT { calculeaz media general}
FIE S:=0; {a elevului i}
PENTRU j:=1;m EXECUT
S:=S+NOTE[i,j];
SFPENTRU
FIE MEDII[i]:=S/m
SFPENTRU
CHEAM ORDINE(n,MEDII,O);
CHEAM TIPAR(n,NUME,O)
PENTRU j:=1;m EXECUT
CHEAM ORDINE(n,NOTE.j,O);
CHEAM TIPAR(n,NUME,O);
SFPENTRU
SF-ALGORITM

ntr-un algoritm, parametrii formali i actuali pot fi funcii sau proceduri. n continuare este
prezentat un astfel de exemplu, n care se calculeaz radicalii de ordinul doi i trei din constanta mm
rezolvnd ecuaiile:
x
2
- mm = 0, notat g(x) = 0,
respectiv
x
3
- mm = 0, notat h(x) = 0.

Pentru rezolvarea unei ecuaii se pot folosi mai multe metode. n program am ales dou:
metoda njumtirii i metoda coardei. Metoda coardei este descris amnunit n seciunea
urmtoare. Metoda njumtirii const n njumtirea intervalului [a,b] care conine rdcina i
reinerea aceluia n care se afl rdcina, subinterval care va fi noua valoare a lui [a,b]. Calculul se
ncheie n momentul n care lungimea intervalului [a,b] este mai mic dect , care ne d eroarea cu
________________________________________________________________________________
47
Structuri de date i algoritmi
_______________________________________________________________________________
care dorim s aflm rdcina.
ntruct metoda coardei folosete i prima derivat, am notat prin f1, respectiv g1 derivatele
funciilor f i g. Prin c i t s-au notat cele dou extremiti ale intervalului care conine rdcina, t
fiind extremitatea n care se duce tangenta.
SUBALGORITMUL coarda(c,t,r,f,f1) ESTE: {Se rezolv ecuaia f(x)=0 prin metoda
coardei}
{c,t sunt extremitile intervalului care conine}
{rdcina, iar f1este derivata lui f }
{r este rdcina care se calculeaz}
REPET
c:=c-f(c)*(t-c)/(f(t)-f(c));
t:=t-f(t)/f1(t);
PNCND
c t
< 0.00001;
FIE r:=(c+t)/2
SF-coarda

SUBALGORITMUL juma(a,b, r, f,f1) ESTE: {Se rezolv prin metoda njumtirii}
{ecuaia f(x)=0, care are o rdcin n [a,b]}
{r= rdcina obinut, iar f1 este derivata lui f}
REPET
r:=(a+b)/2;
DAC f(a)*f(r) <0 ATUNCI
b:=r
ALTFEL
a:=r
SFDAC
PNCND
a b
< 0.00001 SFREPET
SF-juma

SUBALGORITMUL Rezec(a,b, r, f,f1, met) ESTE:
CHEAM met(a,b,r,f,f1);
SF-Rezec

ALGORITMUL pffunctii ESTE: {Algoritmul 3.8}
________________________________________________________________________________
48
Structuri de date i algoritmi
_______________________________________________________________________________
TIPRETE 'njumtire Coarda ' ;
CHEAM Rezec(1,2,rj,g,g1,juma);
CHEAM Rezec(1,2,rc,g,g1,coarda);
TIPRETE rj,rc ;
CHEAM Rezec(1,2,rj,h,h1,juma);
CHEAM Rezec(1,2,rc,h,h1,coarda);
TIPRETE rj,rc ;
SFALGORITM

Prin proiectare (programare) modular nelegem metoda de proiectare (programare) a
unui algoritm pentru rezolvarea unei probleme prin folosirea modulelor.
Dar ce este un modul? Modulul este considerat [Schach90, Freniu94] o unitate structural
de sine stttoare, fie program, fie subprogram, fie o unitate de program. Un modul poate conine
sau poate fi coninut ntr-alt modul. Un modul poate fi format din mai multe submodule. Astfel, n
Pseudocod fiecare subalgoritm i algoritmul principal sunt considerate module. n limbajele de
programare cu structur de bloc (de exemplu n Turbo Pascal, prezentat n capitolul trei) UNIT-urile
pot fi considerate module. La compilarea separat un grup de subprograme compilate deodat
constituie un modul, dar acest modul poate fi considerat ca o mulime de submodule din care este
compus.
Este ns important ca fiecare modul s-i aib rolul su bine precizat, s realizeze o funcie
n cadrul ntregului program. El apare n mod natural n descompunerea top-down.
Indiferent c privim modulul ca un singur subalgoritm, un grup de subalgoritmi, sau un
algoritm de sine stttor ce apeleaz ali subalgoritmi, considerm modulele relativ independente,
dar cu posibiliti de comunicare ntre ele. Astfel, un modul nu trebuie s fie influenat de maniera
n care se lucreaz n interiorul altui modul. Orice modificare ulterioar n structura unui program,
dac funcia pe care o realizeaz un modul M nc este necesar, acest modul trebuie s fie util i
folosit n continuare fr modificri.
Rezult c programarea modular se bazeaz pe descompunerea problemei n subprobleme
i proiectarea i programarea separat a subalgoritmilor corespunztori. De altfel, considerm c
ntr-o programare serioas nu se poate ajunge la implementare fr a avea n prealabil algoritmii
descrii ntr-un limbaj de descriere (la noi Pseudocod). Deci programarea modular se refer n
primul rnd la proiectarea modular a algoritmilor i apoi la traducerea lor n limbajul de
programare ales, innd seama de specificul acestui limbaj. Programarea modular este strns legat
de programarea ascendent i de programarea descendent, ambele presupunnd folosirea
subalgoritmilor pentru toate subproblemele ntlnite.
I.2.5. Apel recursiv
n exemplele anterioare se observ c apelul unui subprogram se face dup ce el a fost
definit. Este ns posibil ca un subalgoritm s se apeleze pe el nsui. ntr-un astfel de caz spunem
________________________________________________________________________________
49
Structuri de date i algoritmi
_______________________________________________________________________________
c apelul este recursiv, iar subalgoritmul respectiv este definit recursiv.
Ca exemplu, definim n continuare o funcie care calculeaz recursiv valoarea n!. Se va
folosi formula:
( )

'

>

0 , 1
0 , ! 1
!
n
n n n
n
Recursivitatea const n faptul c n definiia funciei Factorial n argumentul n se folosete
aceeai funcie Factorial dar de argument n-1. Deci funcia Factorial se apeleaz pe ea nsi. Este
important ca numrul apelurilor s fie finit, deci ca procedeul de calcul descris s se termine.
FUNCTIA Factorial(n) ESTE:
DAC n=0 ATUNCI
Factorial:=1
ALTFEL
Factorial:= n*Factorial(n-1)
SFDAC
SF-Factorial;
I.2.6. Programarea structurat
Programarea structurat este un stil de programare aprut n urma experienei primilor ani de
activitate. Ea cere respectarea unei discipline de programare i folosirea riguroas a ctorva structuri
de calcul. Ca rezultat se va ajunge la un algoritm uor de urmrit, clar i corect.
Termenul programare, folosit n titlul acestei seciuni i consacrat n literatura de
specialitate, este folosit aici n sens larg i nu este identic cu cel de programare propriu-zis. Este
vorba de ntreaga activitate depus pentru obinerea unui program, deci att proiectarea algoritmului
ct i traducerea acestuia n limbajul de programare ales.
Bhm i Jacopini [1966] au demonstrat c orice algoritm poate fi compus din numai trei
structuri de calcul:
- structura secvenial;
- structura alternativ;
- structura repetitiv.
I.3. Probleme propuse
I. Descriei n Pseudocod subalgoritmi care calculeaz urmtoarele funcii:
1. Pentru nN funcia Prim(n) calculeaz al n-lea numr prim.
2. Pentru z,l,aN dai, 1z31, 1l12, 1900<a, funcia NRZI(z,l,a) spune a cta zi din anul a este
data (z,l,a);
3. Pentru nN funcia UrmatorPrim(n) d numrul prim imediat superior lui n.
________________________________________________________________________________
50
Structuri de date i algoritmi
_______________________________________________________________________________
4. Pentru polinomul P de gradul n cu coeficieni reali dat i xR funcia VALPOL(x,n,P) d
valoarea polinomului P n punctul x.
5. Pentru k,nN, 0kn, funcia C(n,k) calculeaz numrul combinrilor de n obiecte luate cte k.
6. Pentru vectorii X i Y cu n componente, funcia E(n,X,Y) d valoarea 0 dac X=Y, respectiv i
dac i este cel mai mic indice pentru care x
i
< y
i
.
7. Cunoscnd mulimile A i B funcia INCLUS(A,B) verific dac mulimea A este inclus n
mulimea B;
8. Fie f o funcie de forma f : {1, 2, ..., m} {1, 2, ..., n}.
Definim T(f) egal cu 1 dac f este o funcie injectiv, egal cu 2 dac f este surjectiv, egal cu 3 dac
f este bijectiv, i 0 n caz contrar. Se d funcia f prin perechile de elemente (x,f(x)) care definesc
graficul su. S se calculeze T(f).
9. Se d o relaie binar R prin graficul su. S se calculeze E(R) prin definiie egal cu 0 dac R
este o relaie de recuren i egal cu 1 n caz contrar.
10. irul Fibonacci este definit astfel: f
0
=f
1
=1 i f
n
=f
n-1
+f
n-2
, pentru n >1. Pentru nN dat calculai
F(n)=f
n
.
11. Pentru nN dat calculai j(n), unde j este funcia lui Euler, deci j(n) este numrul numerelor
mai mici dect n i relativ prime cu n.
12. Pentru nN dat calculai P(n), unde P(n) este 0 dac numrul n este perfect i 1 n caz contrar
(un numr n este perfect dac este egal cu suma divizorilor si mai mici dect el nsui. Exemplu:
6=1+2+3)
II. Scriei subalgoritmi pentru rezolvarea urmtoarelor probleme:
1. Cunoscnd mulimile A i B calculai C = A B;
2. Cunoscnd mulimile A i B calculai C = A B;
3. Dndu-se vectorul X cu n componente, tergei toate componentele care se repet;
4. Dndu-se vectorul X cu n componente numere ntregi ordonate cresctor i aZ inserai pe a n
X astfel nct X s rmn ordonat cresctor;
5. Dndu-se dou polinoame calculai suma lor;
6. Dndu-se dou polinoame calculai produsul lor;
________________________________________________________________________________
51
Structuri de date i algoritmi
_______________________________________________________________________________
7. Dndu-se dou matrice calculai suma lor;
8. Dndu-se dou matrice ptrate de ordinul n calculai produsul lor;
9. Dndu-se dou numere A i B prin reprezentrile lor n baza p gsii suma lor A+B prin
reprezentarea ei n baza p;
10. Dndu-se numerele reale x
1
, x
2
,... ,x
n
, determinai secvena de termeni consecutivi care are
suma maxim.
11. Se dau p,qN i numrul A prin reprezentarea sa n baza p. Determinai reprezentarea sa n
baza q.
12. Se d nN, n2. S se formeze matricea ptrat A de ordinul n ale crei coloane scrise una
dup alta constituie primii n
2
termeni ai irului
1,2,3,4,5,6,7,8,9,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9,2,0, ... obinut din scrierea cifrelor
semnificative ale numerelor naturale.
III. Proiectai prin metoda top-down algoritmi pentru rezolvarea urmtoarelor probleme:
1. Se d un ir de numere naturale x
1
, x
2
, ..., x
n
. Spunem c dou numere naturale sunt prietene dac
scrierea unui numr (n baza 10) este obinut prin scrierea cifrelor celuilalt n ordine invers (de
exemplu 3678 i 8763). S se gseasc toate perechile de numere consecutive prietene din irul dat
i frecvenele cifrelor n scrierea numerelor date.
2. Se d un ir de numere naturale x
1
, x
2
, ..., x
n
. S se gseasc toate subirurile de elemente
consecutive de lungime maxima formate din numere prime i toate numerele prime distincte
ntlnite.
3. Se d o matrice ptrat A de ordinul n i numrul natural m>0. Se cere s se tipreasc matricele
A, A
2
, ..., A
m
i suma lor.
4. Se d polinomul P cu coeficieni ntregi, fie prin monoamele sale, fie prin grad i coeficieni. S
se scrie un algoritm care determin rdcinile raionale ale polinomului P.
5. Se dau numerele naturale n
1
i n
2
. Determinai mulimea numerelor prime aflate ntre n
1
i n
2
i
mulimea perechilor de gemeni (numerele prime p i q se numesc gemeni dac q-p=2).
6. Fiind date mai multe polinoame cu coeficieni reali s se determine suma lor i polinomul de
grad maxim. Un polinom se d fie prin monoamele sale, fie prin grad i coeficieni.
7. Se citesc mai multe iruri de numere naturale. Pentru fiecare ir citit, tiprii cea mai lung scar
(secvena de termeni consecutivi strict cresctori) i depunei aceast scar ntr-un ir (rezultat) R.
La sfrit tiprii cea mai lung scar din R. Citirea unui ir se termin la ntlnirea unui numr
negativ, iar citirea se oprete la ir de lungime 0 (deci fr nici un termen).
________________________________________________________________________________
52
Structuri de date i algoritmi
_______________________________________________________________________________
8. Se dau mai multe mulimi de numere ntregi pozitive. S se determine reuniunea i intersecia
acestor mulimi.
9. Se dau mai multe mulimi de numere naturale. Fie I(M) numrul mulimilor diferite de M si care
conin pe M. S se determine mulimea pentru care I(M) este maxim.
10. O matrice rar A este o matrice n care majoritatea termenilor sunt nuli. O astfel de matrice se
poate reprezenta prin tripletele (linie, coloan, valoare) corespunztoare valorilor nenule ale
matricei; deci A[linie,coloan] = valoare. Dndu-se mai multe matrice rare determinai suma lor.
11. Se dau mai multe numere naturale prin reprezentrile lor n baza p. Gsii suma lor i maximul
acestor numere (reprezentate n baza p i toate operaiile se fac n baza p).
12. Se dau mai multe matrice cu coeficieni ntregi. Se cere suma matricelor care au determinantul
nenul, matricele care au determinantul nul i matricea care are determinantul maxim.

Complexitatea algoritmilor
Etapele rezolvrii unei probleme
Este cunoscut faptul c rezolvarea unei probleme presupune n principal trei etape:
I. Analiza problemei
II. Proiectarea soluiei
III. Implementarea i testarea soluiei n practic.
n funcie de gradul de generalitate a analizei efectuate, n a doua etap se ntlnesc dou
situaii: proiectarea unei soluii particulare, valabil doar pentru acea problem, i proiectarea unei
soluii generale, valabil pentru orice instaniere a acelei probleme, soluia generalizat.
n timp ce soluia particular este valabil doar pentru o instan a problemei, soluia
general este independent de parametrii problemei i ofer o metod general de rezolvare a
problemei.
Astfel, soluionarea imediat a ecuaiei x
3
+1=0 este particular fa de soluionarea ecuaiei
generalizate ax
3
+bx
2
+c=0.
Noiunea de algoritm i cea de program
Atunci cnd metoda general de rezolvare a unei probleme este prezentat precis, pe pai ce se
efectueaz ntr-o ordine bine precizat i care conduc n timp finit la soluia oricrei instanieri a
problemei, vorbim de algoritmul de rezolvare a problemei.
De exemplu, algoritmul de determinare a unei soluii reale a ecuaiei polinomiale P(x) = 0,
cu o aproximare dat, prin metoda tangentei.
________________________________________________________________________________
53
Structuri de date i algoritmi
_______________________________________________________________________________
Avantajul major al proiectrii unui algoritm de soluionare a problemei este dat de faptul c
efortul de rezolvare poate fi transferat unei maini automate (calculator) sub forma programului
executabil ce implementeaz algoritmul general de soluionare.
Implementarea algoritmului general de soluionare a problemei ntr-un program pe
calculator permite o important economie prin faptul c efortul major de analiz i proiectare a
soluiei a fost efectuat o singur dat iar rezolvarea problemei se reduce la efortul foarte redus de
executare (rulare) a programului cu ajutorul calculatorului pentru fiecare instan diferit a
problemei.
Modelul abstract al Mainii Turing
Primul model teoretic riguros de main automat de calcul este Modelul mainii abstracte
Turing (1936). Acest model teoretic a stat la baza apariiei efective a primei maini electronice de
calcul, denumit mai trziu computer (calculator) dup denumirea operatorului uman
(tehnicianului) care era angajat s fac toate calculele inginereti sau contabile ale unui proiect sau
ale unei firme.
Teza Turing-Church
Rezult c, n ultim instan, puterea de rezolvare a unui calculator se reduce la puterea de
calcul a mainii Turing. Iar puterea de calcul a acestei maini abstracte riguroase este exprimat sub
forma Tezei Turing-Church: O main Turing poate face tot ceea ce poate face un computer uman
nzestrat cu creion, oricte foi de hrtie i reguli precise ( mecanice sau automate ) de calcul.
Exist, pe lng aceast formulare iniial a lui Turing, o serie de alte formulri echivalente
ale acestei teze unanim acceptate de teoreticienii ce au pus bazele teoriei informatice i a tiinei
calculatoarelor (computer science). S observm c aceast tez (propoziie acceptat fr
demonstraie ca avnd valoarea logic de adevrat) stabilete o echivalen perfect ntre puterea de
calcul a unui computer uman i puterea de calcul a unui computer main.
Echivalarea subneles (tacit) a noiunii teoretice vagi de algoritm cu noiunea matematic
riguroas de Main Turing a nsemnat acceptarea unanim a Tezei Turing-Church de ctre
iniiatorii informaticii. n consecin, studiul eficienei unui algoritm n soluionarea unei probleme
revine n studiul eficienei n funcionare a mainii Turing i implicit a eficienei n funcionare a
programului ce implementeaz acel algoritm de rezolvare.
Aceasta este consecina faptului c, n accepiunea original, algoritmul de soluionare a unei
probleme este destinat unui computer uman, dar puterea de calcul a acestuia este aceeai cu puterea
de calcul a unei maini Turing = computer main care este pus n micare printr-un program
executabil.

Analiza, Proiectarea i Implementarea algoritmilor i Complexitatea algoritmilor
Relund ideea iniial, n rezolvarea automat a unei probleme (adic rezolvarea cu ajutorul
calculatorului a oricrei instane diferite problemei) se trece prin cele trei etape: Analiza teoretic a
problemei, Proiectarea algoritmului de soluionare i Implementarea algoritmului ntr-un program
executabil pe calculator.
n timp ce n prima etap analiza problemei - rezultatul cheie, pe care se concentreaz
preponderent efortul de analiz, este demonstrarea corectitudinii soluiei, n a doua etap
proiectarea algoritmului de soluionare - cuvntul cheie este eficiena de rezolvare. Studiul cu un
pronunat caracter teoretic coninut n aceast a doua etap i propune s prevad eficiena n
funcionare (necesarul de timp i spaiu calculator) a programului executabil ce va implementa
algoritmul, eventual prin compararea teoretic a algoritmilor de soluionare diferii.
________________________________________________________________________________
54
Structuri de date i algoritmi
_______________________________________________________________________________
De exemplu, n cazul problemei sortrii unui ir de n chei prin comparaii se poate estima
teoretic comparativ c algoritmul de sortare QuickSort este printre cele mai eficiente soluii.
Disciplina informaticii care se ocup cu studiul teoretic al eficienei algoritmilor este numit
Complexitatea algoritmilor.
Operaia de baz, cheia studiului complexitii
La baza studierii complexitii unui algoritm st detectarea n descrierea algoritmului a
operaiei sau a operaiilor de baz, acea operaie (acele operaii) aflat (aflate) n cel mai interior
corp de ciclu repetitiv i a crei (a cror) contorizare permite estimarea n avans, nainte de lansarea
n execuie, a timpului de execuie a programului executabil corespunztor.
n majoritatea cazurilor exist o legtur foarte strns ntre operaia de baz (cea mai
repetat operaie) i operaia care este dedus n etapa de analiz a problemei ca fiind operaia
inevitabil pentru rezolvarea problemei.
De exemplu, n cazul problemei sortrii unui ir de n chei prin comparaii este limpede c
operaia de comparare a mrimii cheilor este operaia inevitabil i de asemenea ea va fi i
operaia de baz a crei contorizare va permite estimarea, nainte de execuie, a duratei de
funcionare a programului ce implementeaz algoritmul de sortare respectiv.

Clase de algoritmi
n aceast situaie, toi algoritmii diferii care soluioneaz aceeai problem i care se
bazeaz pe aceeai operaie de baz (inevitabil) formeaz clasa algoritmilor de soluionare a
problemei. De obicei numele clasei va fi dat chiar de numele acelei operaii de baz ce este
coninut de fiecare algoritm al clasei n mod inevitabil.
De exemplu, n cazul problemei sortrii unui ir de n chei prin comparaii, algoritmii diferii
ce soluioneaz problema sunt grupai n clasa algoritmilor de sortare prin comparaii, spre
deosebire de clasa algoritmilor de sortare prin distribuire ce soluioneaz aceeai problem
bazndu-se ns pe alt operaie de baz: distribuirea cheilor de sortat.
Operaia de baz a algoritmilor dintr-o clas de algoritmi poate fi comparat cu o vergea
vertical pe care sunt nirai toi algoritmii clasei. Ea este cea care permite studiul comparativ a
eficienei algoritmilor din acea clas (ea fiind o veritabil coloan vertebral a clasei respective).
Eficiena algoritmilor
Compararea eficienei a doi algoritmi diferii ce soluioneaz aceeai problem se face prin
determinarea teoretic a numrului de repetiii a operaiei de baz n fiecare algoritm i
compararea celor dou valori. n final rezultatul comparrii va permite estimarea comparativ a
duratei de funcionare a programelor i alegerea celui mai bun.
Compararea eficienei a doi algoritmi, din punct de vedere practic, se face prin compararea
timpilor medii de execuie a celor dou programe ce i implementeaz. Aceast metod pragmatic
are dezavantajul c necesit rularea programelor care, n anumite situaii, poate dura un timp
surprinztor de mare.
Funciile de complexitate
Numrul de repetiii al operaiei de baz se exprim matematic printr-o funcie de
complexitate individual asociat algoritmului, funcie ce depinde n mod inevitabil de dimensiunea
(mrimea) vectorului datelor de intrare.
________________________________________________________________________________
55
Structuri de date i algoritmi
_______________________________________________________________________________
De exemplu, n cazul algoritmului de determinare a maximului dintr-un ir de n elemente
prin comparaii, este evident c numrul de comparaii efectuat de orice algoritm de maxim va fi o
funcie de n. Iat descrierea n Pseudocod a algoritmului:
Citete n, a
1
, a
2
,, a
n
; Dup cum se observ vectorul de intrare (irul a) are dimensiunea n.
Max := a
1
;
Pentru i := 2 pn la n execut Este evident c operaia de baz comparaia < se execut de
Dac Max < a
i
atunci Max := a
i
; n-1 ori, adic pentru valorile contorului i cuprinse ntre 2 i n.
Scrie Max; Deci, funcia care descrie numrul operaiilor de baz este: f(n)=n-1
n studiul complexitii algoritmilor, pentru a permite realizarea comparailor necesare
pentru clasificarea algoritmului din punct de vedere al eficienei, dimensiunea vectorului de intrare
este mpins spre infinit.
Compararea complexitii algoritmilor dintr-o clas de algoritmi cere n mod inevitabil
gruparea funciilor de complexitate n clase de funcii de complexitate i studiul comportamentului
asimptotic al acestora (cnd n dimensiunea vectorului de intrare tinde ctre infinit).
Apartenena la o clas de complexitate
n acest fel, complexitatea unui algoritm se poate exprima prin precizarea clasei de
apartenen a funciei de complexitate a respectivului algoritm. Notaiile clasice care exprim felul
apartenenei funciei de complexitate f(n) a unui algoritm la diverse clase de funcii sunt , i .
n aceast introducere snt prezentate noiuni de baz folosite n capitolele urmtoare ale
lucrrii. O atenie special este acordat structurilor de tip graf, care intervin foarte frecvent n
elaborarea algoritmilor geometrici.
Definiia 1.1. Un algoritm este un set de instruciuni care trebuie executate pentru a se obine un
rspuns la o problem dat.
Un algoritm are urmtoarele proprieti (Knuth [1976], Burdescu [1998]):
finitudine: trebuie s se termine ntotdeauna dup un numr finit de pai (instruciuni);
determinism: fiecare pas trebuie s fie exact precizat, n mod riguros i neambiguu;
generalitate: trebuie s rezolve problema pentru orice date de intrare din domeniul
precizat;
efectivitate: fiecare instruciune trebuie s fie exact i de durat finit.
Ultima proprietate trebuie nuanat, avnd n vedere faptul c memoria oricrui calculator
este limitat. Nu ntotdeauna operaiile aritmetice se efectueaz exact, n unele cazuri obinndu-se
o aproximare a rezultatelor. Exist i soluii propuse pentru respectarea acestei proprieti, care
presupun implementarea software a operaiilor elementare cu numere ntregi (Fortune. et al.
[1993]), dar acestea duc la scderea vitezei de prelucrare. De aceea, abordri recente iau n
considerare modelul bazat pe aritmetica n virgul mobil, implementat pe toate calculatoarele
actuale (Shewchuk [1997]).
Avnd un algoritm care rezolv o problem dat, urmeaz s determinm resursele acestuia
(Livovschi i Georgescu, [1986]). Concret, de ct memorie i timp avem nevoie ca s obinem
soluia problemei? n acest scop facem urmtoarele simplificri: fiecare operaie elementar a
algoritmului se execut ntr-o unitate de timp, informaiile despre un obiect elementar se
memoreaz ntr-o locaie de memorie.
________________________________________________________________________________
56
Structuri de date i algoritmi
_______________________________________________________________________________
Fie f : N N o funcie care indic relaia dintre numrul de valori (date de intrare)
prelucrate de un algoritm, i numrul de operaii elementare efectuate de acesta pentru obinerea
rezultatelor. Funcia f poate avea o expresie analitic destul de complicat, de aceea considerm
nc o funcie g : N N cu o expresie analitic simplificat.
Definiia 1.2. Funcia f are ordinul de mrime cel mult g(n), notaie: f O(g(n)), dac i numai
dac exist valori c> 0 i n
0
N astfel nct pentru orice n> n
0
s avem f(n) c g(n).
O(g) { h : N N |

c> 0, n
0
N a. .

n> n
0
, h(n) c g(n) }.
(1.1)
Definiia 1.3. Funcia f are ordinul de mrime cel puin g(n), notaie: f(g(n)), dac i numai
dac exist valori c> 0 i n
0
N astfel nct pentru orice n> n
0
s avem f(n) c g(n).
(g) { h : N N |

c> 0, n
0
N a. .

n> n
0
, h(n) c g(n) }.
(1.2)
Definiia 1.4. Funcia f are ordinul de mrime g(n), notaie: f(g(n)), dac i numai dac exist
valori c
1
, c
2
> 0 i n
0
N astfel nct pentru orice n> n
0
s avem c
1
g(n) f(n) c
2
g(n).
(g) { h : N N |

c
1
, c
2
> 0, n
0
N a. .

n> n
0
, c
1
g(n) h(n) c
2
g(n) }. (1.3)
Prezentm dou rezultate remarcabile care vor fi folosite foarte frecvent pe parcursul lucrrii
Knuth [1976]:
(1) Se d un ir de n valori dintr-un domeniu pe care este definit o relaie de ordine total.
Cel mai eficient algoritm de ordonare a irului dat, care se bazeaz pe comparaii, are complexitate
de ordin (n log n).
(2) Se d un ir de n valori ordonate. Cutarea unei valori (localizarea poziiei acesteia sau
obinerea unui rspuns negativ) n irul dat necesit un timp de ordin O(log n).
O categorie special de probleme, numite NP-complete, se caracterizeaz prin urmtoarele:
nu se cunosc algoritmi eficieni (de complexitate polinomial), se cunosc n schimb
algoritmi de complexitate exponenial pentru rezolvarea acestora;
problem NP-complet este polinomial transformabil ntr-o alt problem tot NP-
complet: dac se rezolv o problem A, soluia unei alte probleme B se poate obine
printr-o transformare n timp polinomial din soluia problemei A.
Cea mai general problem NP-complet este problema satisfiabilitii: fiind dat o expresie
logic n forma normal conjunctiv cu n variabile, s se determine dac pot fi atribuite valori
logice variabilelor astfel nct expresia s fie adevrat Cook [1970].
Complexitatea medie. Considerm un algoritm care proceseaz n valori date la intrare.
Pentru o anumit configuraie a valorilor, probabilitatea configuraiei fiind p
i
, sunt necesare f
i
(n)
operaii. Complexitatea medie a algoritmului este o sum ponderat:
( )

i
i i
n f p
.
Exemplul 1.1. Algoritmul Quick-sort necesit un timp de ordin O(n log n) n majoritatea cazurilor
pentru a ordona un ir de n valori. Exist ns cteva configuraii (foarte puine) care au nevoie de
un timp de ordin O(n
2
) pentru a fi procesate. Complexitatea medie a acestui algoritm este de ordin
O(n log n) Knuth [1976]:
________________________________________________________________________________
57
Structuri de date i algoritmi
_______________________________________________________________________________
ntr-un mod similar se poate defini noiunea de complexitate pentru necesarul de memorie.
Aceasta arat ct memorie este necesar pentru rezultatele intermediare i cele de ieire.
Definiiile date mai sus asigur o estimare a eficienei unui algoritm independent de o
implementare practic a acestuia folosind un anumit limbaj de programare, urmrindu-se
ascunderea factorului multiplicativ. Totui acest factor nu poate fi ntotdeauna ignorat, deoarece
exist probleme care admit mai muli algoritmi cu acelai ordin de complexitate, i atunci trebuie s
se efectueze o rafinare a studiului complexitii. Rezultate recente arat c aceast constant poate
influena eficiena unor implementri, de aceea abordrile clasice ale acestui subiect trebuie privite
cu rezerve.
Unele probleme de optimizare se rezolv cu ajutorul unor algoritmi de complexitate mare,
exemplu: probleme NP-complete sau de complexitate O(n
d
). n asemenea situaii ne mulumim cu
soluii aproximative obinute cu ajutorul unor algoritmi euristici, mult mai eficieni i de cele mai
multe ori mai simpli.
O categorie special, frecvent ntlnit mai ales n probleme de geometrie, este aceea a
algoritmilor incrementali. Un algoritm din aceast categorie proceseaz valorile de intrare una cte
una, la fiecare pas obinndu-se o soluie parial pentru datele deja procesate.
Dac algoritmul de determinare a maximului din n chei prin comparaii efectueaz un
numr liniar de comparaii (adic proporional cu n) atunci se spune c el este un algoritm (n)
(adic are funcia de complexitate din (n) = mulimea funciilor lineare de forma c n), iar dac
efectueaz cel puin, respectiv cel mult, tot attea comparaii (adic proporional cu n) se spune c
algoritmul este (n), respectiv (n).
Clasele de funcii de complexitate, i implicit clasele de complexitate a algoritmilor, cele
mai des ntlnite, n ordine cresctoare a complexitii sunt: (ln n) - clasa algoritmilor cu
complexitate logaritmic (timpul de execuie va fi egal cu c ln n), (n) - liniar (timpul de
execuie va fi egal cu c n), (n ln n) - liniar-logaritmic (timpul de execuie va fi egal cu c n ln
n), (P(n)) - polinomial (timpul de execuie va fi egal cu c P(n)), (e
x
) - exponenial (timpul de
execuie va fi egal cu c Exp(n)) sau (n!) - factorial (timpul de execuie va fi egal cu c n!). Peste
tot c este o constant de proporionalitate care depinde de calculatorul pe care se ruleaz
programele.
Iat cte un exemplu de algoritm din literatura de specialitate, corespunztor fiecrei clase:
algoritmul de cutare binar BinarynSearch - (log n), algoritmul de determinare a maximului
Max - (n), algoritmul de sortare prin comparaii QuickSort - (n log n), algoritmul comun de
nmulire a matricelor - (n
3
), algoritmul de colorare optim cu k culori a unui graf cu n noduri prin
ncercri repetate - (k
n
), respectiv, algoritmul de generare a permutrilor - (n!), toi algoritmii
avnd vectorul de intrare cu n elemente (de dimensiune n).
Limita inferioar sau efortul minimal
Atunci cnd ntr-o clas de algoritmi, toi bazai pe aceeai operaie de baz, se poate stabili
o limit inferioar a numrului de operaii de baz inevitabile ce trebuiesc efectuate pentru
soluionarea problemei, putem vorbi despre efortul minimal de rezolvare i despre algoritmul
optimal de rezolvare a problemei respective.
Algoritm optimal
Algoritmul optimal este acel algoritm care efectueaz cel mai mic numr de operaii de baz
dintre toi algoritmii clasei sale, cunoscui sau neinventai nc (o clas de algoritmi prin criteriul
________________________________________________________________________________
58
Structuri de date i algoritmi
_______________________________________________________________________________
su de apartenen - prezena operaiei de baz inevitabile - include obligatoriu n acea clas toi
algoritmii ce rezolv problema bazndu-se pe operaia respectiv, chiar i algoritmii nedescoperii
nc !).
De exemplu, n clasa algoritmilor de sortare prin comparaii se nelege c este aparintor
orice algoritm de sortare bazat pe comparaii cunoscut sau necunoscut nc. n plus, limita
inferioar a numrului de comparaii necesar pentru sortarea listei de n elemente (efortul minimal)
prin comparaii este demonstrat riguros ca fiind log
2
n! dar un algoritm optimal care s efectueze
exact attea operaii de baz (comparaii) nu se cunoate.
n clasa algoritmilor de determinare a maximului prin comparaii, algoritmul clasic de
determinare a maximului este un algoritm optimal ntruct el efectueaz un numr minimal de
comparaii inevitabile: n-1.
Complexitatea algoritmilor i dificultatea problemelor
Din perspectiva rezolvrii problemelor cu ajutorul calculatorului putem studia i compara
dificultatea problemelor studiind i comparnd complexitatea algoritmilor optimali de soluionare a
acestora.
Astfel, problema sortrii prin comparaii cere un efort minimal liniar-logaritmic. Ea nu este
totui o problem de efort liniar-logaritmic ( (n log n)) ntruct ea poate fi soluionat cu efort
liniar ( (n) operaii) atunci cnd cheile de sortare pot fi distribuite folosind un algoritm de sortare
prin distribuire.
Complexitatea de timp
Msurarea n practic a duratei de execuie (adic a complexitii de timp) a implementrii
algoritmilor a condus la urmtoarea concluzie categoric: singurii algoritmi ce soluioneaz n mod
eficient o problem oarecare sunt acei algoritmi care au complexitatea polinomial (sau mai mic
dect exponenial). O astfel de soluie se numete soluie rezonabil, fa de cealalt situaie cu
soluie nerezonabil avnd o complexitate de timp exponenial sau factorial (total ineficient ca
durat de execuie).
De exemplu, dac pentru colorarea unui graf cu n vrfuri cu doar trei culori, se ncearc
toate cele 3
n
variante de colorare (printr-un algoritm de tip backtracking), timpul necesar unui
program pentru epuizarea tuturor cazurilor, n cazul n care n=100, este direct proporional cu
uriaa valoare de 3
100
= 387420489
10
ceea ce face acel program cu totul inutilizabil (chiar dac am
presupune c o instruciune s-ar executa ntr-o pico-secund = 10
-12
s).

Probleme rezonabile i probleme nerezonabile. Clasa problemelor P-polinomiale
Dup efortul de rezolvare necesar, reductibil n ultim instan la durat de execuie a
programului, problemele se pot mpri n probleme rezonabile i nerezonabile. innd cont de cele
de mai sus, problemele rezonabile sunt problemele de dificultate polinomial i ele sunt grupate n
clasa problemelor P (Clasa problemelor Polinomiale). Pentru fiecare problem din aceast clas se
cunoate un algoritm de soluionare cu complexitate polinomial, adic programul ce
implementeaz acest algoritm are o durat de execuie proporional cu o funcie polinomial de n,
unde n este dimensiunea datelor de intrare.
Exist cu siguran probleme ce nu fac parte din aceast clas P: de exemplu, problema
generrii tuturor celor n! permutri ale unui ir de n elemente distincte, care are inevitabil
dificultatea (durata de execuie) factorial n!.
________________________________________________________________________________
59
Structuri de date i algoritmi
_______________________________________________________________________________
Probleme de decizie i probleme de optimizare
n ncercarea de a studia i clasifica dificultatea problemelor ne-polinomiale (nerezonabile ca
durat de rezolvare cu ajutorul calculatorului) ele au fost grupate n dou categorii: probleme n
varianta de decizie, n care se cere doar s se decid prin DA sau NU dac exist pentru problema
respectiv o soluie bine-precizat, i probleme n varianta de optimizare, n care se cere
determinarea soluiei optime pentru problema respectiv.
De exemplu, problema colorrii grafului n varianta de decizie cere s se decid dac un graf
poate fi colorat cu k culori, unde k este precizat dinainte. Aceeai problem, n varianta de
optimizare, cere s se determine - numrul minim de culori necesar (numrul cromatic) pentru
colorarea unui graf (astfel nct oricare dou vrfuri adiacente s fie colorate diferit), fiind
evident un numr ce nu poate fi precizat dinainte.

Clasa problemelor NP (non - deterministic polinomiale)
Exist o clas larg de probleme de decizie cu extrem de numeroase aplicaii practice numit
clasa problemelor NP (non-deterministic polinomiale). Aceast clas include pe lng toate
problemele de decizie din P i o mulime foarte mare de probleme de decizie (toate inspirate din
practic) crora nu li se cunoate o soluie polinomial.
Pentru a putea explica de ce sunt numite NP (non-deterministice), este necesar s revenim la
echivalarea unanim acceptat de teoreticienii informaticii ntre noiunea de algoritm i noiunea de
main Turing. Astfel, pentru fiecare din problemele NP se cunoate o soluie sub forma unei
maini Turing nedeterministice(!) (care la o tranziie de stare poate trece dintr-o stare ntr-una din
oricare alte k stri posibile, fr a se putea preciza exact n care) care se oprete furniznd soluia
dup un numr polinomial de pai.
n termenii algoritmici, aceeai non-determinarea este exprimat astfel: o problem NP este o
problem ce are un algoritm de soluionare care decide n timp polinomial dac o soluie propus
(prin "ghicire" sau "inventare" ) este sau nu valid.
n aceti termeni, nedeterminarea const mai exact n faptul c sub-algoritmul de ghicire
sau inventare de soluii, din cauz c nu poate parcurge ntreg spaiul soluiilor posibile pentru c
nu ar mai rmne un algoritm polinomial, nu ofer nici o garanie c gsete sau c se apropie
mcar n vreun fel de soluia problemei prin simpl ghicire.
Reducia polinomial a problemelor
n intenia de a compara dificultatea problemelor de decizie ntre ele s-a sesizat c dac
exist un algoritm de transformare T a datelor de intrare D ale unei probleme de decizie P astfel
nct noile date de intrare D=T(D) s se potriveasc ca date de intrare unei probleme de decizie P,
ce are ca soluie un algoritm de soluionare cunoscut A, atunci un algoritm de soluionare A a
problemei P se obine imediat prin compunerea algoritmului A cu transformarea T astfel nct A=
A T.
Dac complexitatea algoritmului de transformare T este rezonabil (polinomial) atunci
nseamn c complexitatea algoritmului A obinut prin compunere este tot att de rezonabil cu cea
a algoritmului A care este cunoscut (adic, dac A are complexitate polinomial i A va avea tot o
complexitatea polinomial obinut prin compunerea celor dou funcii de complexitate polinomiale
corespunztoare lui A i T). n acest caz, cnd algoritmul T de transformare a intrrii unei probleme
________________________________________________________________________________
60
Structuri de date i algoritmi
_______________________________________________________________________________
n intrarea alteia este de complexitate polinomial, atunci ntreag aceast metod ce transform
soluionarea problemei P n soluionarea problemei P cunoscut deja, se numete reducie
polinomial iar cele dou probleme se spune c se reduc una la cealalt: P P.
De exemplu, se poate arta c Problema Orarului (unui institut de nvmnt) este
reductibil la Problema Colorrii Grafului prin faptul c sub-algoritmul de transformare a orelor de
predare/zile/clase/profesori n nodurile unui graf este liniar iar aezarea orelor pe orar este
echivalent cu colorarea grafului obinut prin aceast transformare liniar.

Echivalena problemelor prin reducie polinomial
Atunci cnd dou probleme P i P se reduc polinomial reciproc una la cealalt, adic P
P i P P, se spune c cele dou probleme sunt echivalente.
Desigur, innd cont de cele zise mai sus, se poate arta c Problema Orarului i Problema
Colorrii Grafului sunt echivalente.

Teorema lui Cook. Probleme NP-Complete
Bazndu-se pe Teza Turing-Church i folosind cteva elemente de calcul logic
propoziional, n 1971 Cook a demonstrat o teorem fundamental pentru domeniul complexitii
algoritmilor. Teorema lui Cook afirm c: Toate problemele NP sunt reductibile polinomial la
Problema FNC, deci problema FNC este o problem NP-complet.
Problema FNC (Problema Formei Normale Conjuctive) cere s se decid dac este posibil s existe
o alegere de valori logice Adevrat sau Fals pentru n variabile logice x
1
, x
2
, , x
n
ce apar ntr-o
form normal conjunctiv (format dintr-un ir de clauze conjugate, fiecare clauz fiind obinut
doar prin compunerea sau logic a variabilelor x
i
sau negaiei lor 1 x
i
) astfel nct valoarea logic
a propoziiei logice finale s fie Adevrat.
De exemplu, fie x, y, z cele trei variabile logice, o form normal conjuctiv posibil cu trei
clauze conjugate este: ( x y ) ( x 1 y 1 z) ( 1 x z ) ce admite ca soluie x=Adevrat,
y=Adevrat sau Fals i z=Adevrat.

Clasa problemelor NP-Complete
Dup descoperirea i demonstrarea existenei primei probleme NP-complete a urmat
demonstrarea NP-completitudinii, prin echivalarea cu problema FNC, a unei serii ntregi de
probleme clasice din informatic i cunoscute ca fiind probleme extrem de dificil de soluionat
eficient n timp: Problema Colorrii Grafului, Problema Partiionrii Sumei, Problema Comis-
Voiajorului, Problema Rucsacului, Problema Planificrii Sarcinilor cu Penalizri, etc.
S-a obinut astfel clasa problemelor NP-complete ce au neobinuita proprietate c prin
soluionarea n timp polinomial doar a uneia dintre ele se va obine automat n consecin soluia
polinomial pentru toate celelalte.
Din pcate, pentru nici una din sutele de probleme NP-complete inventariate pn acum nu
se cunoate o soluie polinomial (rezonabil n timp de execuie). ns nu s-a putut demonstra c
vreuna dintre ele nu poate admite o soluie polinomial.

Marea ntrebare a Complexitii algoritmilor
________________________________________________________________________________
61
Structuri de date i algoritmi
_______________________________________________________________________________
Aceasta este Marea ntrebare a complexitii algoritmilor dar i a informaticii: P=NP ? Snt
problemele NP reductibile la cele din P ? Pot exista soluii polinomiale pentru problemele NP ?
Rspunsul la Marea ntrebare este de importan capital pentru majoritatea domeniilor
practice n care calculatorul are un rol tot mai important (strategic, am putea zice): reele de
transport i reele de comunicaii, astronautic i aeronautic, domeniile militare i a serviciilor de
informaii, proiectarea automat, urmrirea automat i controlul proceselor industriale, etc. Un
rspuns afirmativ, P=NP, ar avea ca i consecin imediat posibilitatea introducerii calculatorului
n deplin siguran n poziiile de decizie i control automat a proceselor cheie a fiecruia din
domeniile amintite, datorit capacitii algoritmilor implementai de a lua decizii optime n timp real
(rezonabil) n orice situaie.
Atunci, actualul nume: Era informatizrii, prematur acordat perioadei ultimilor ani, s-ar
potrivii cu adevrat ntru-totul, iar noiunile de pilot automat sau robot ar face parte din viaa
cotidian a fiecruia. Merit aici s atragem atenia asupra puterii extraordinare pe care o vor
dobndi n acea situaie cei ce supervizeaz i programeaz calculatoarele aflate n puncte strategice
de decizie, putere ce fr exagerare ar putea fi numit planetar, i de aceea considerm c:
din pcate ansele de a afla cu toii despre existena rspunsului afirmativ la Marea ntrebare,
nainte ca consecinele strategice ale acestuia s fi fost deja puse n practic la scar planetar,
sunt minime.
Pentru a rspunde ns negativ la Marea ntrebare este suficient s se demonstreze riguros c
una din problemele NP-complete are o complexitate exponenial, deci cu siguran nu admite o
soluie cu timp de execuie polinomial. Sau, altfel spus, ar fi suficient s se arate riguros c ntr-o
anumit problem NP-complet, numrul de operaii de baz inevitabile nu poate fi mai mic dect
exponenial.
n situaia unui rspuns negativ la Marea ntrebare, toate punctele de decizie n timp real vor
fi ocupate ca i pn acum de operatori umani ce nu trebuie i nu pot fi privii ca computere umane,
ei comportndu-se uneori omenete, deci ntr-un mod nedeterminist. S nu uitm c avem cu toii
experiena momentelor cruciale din viaa personal ce au cerut stringent luarea unei decizii i n
majoritatea cazurilor decizia luat de noi n-a fost una de tip raional, algoritmic sau dup o
reet anume, ci soluia aleas a avut o component subiectiv intuitiv sau chiar ilogic.

Algoritmi aproximativi
ntruct nu sunt nc semne clare c se va putea gsi n viitorul imediat rspunsul la Marea
ntrebare, dei se fac eforturi mari n aceast direcie, disciplina Complexitatea algoritmilor s-a
mbogit prin introducerea unui capitol consistent: Proiectarea i studiul complexitii algoritmilor
aproximativi. n primul rnd trebuie precizat c nu este necesar proiectarea unor astfel de algoritmi
dect n cazul problemelor crora nu li se cunoate o soluie rezonabil (alta dect exponenial).
Prin algoritm aproximativ se nelege un algoritm de complexitate polinomial (o soluie
rezonabil, deci) care ns nu este capabil s determine soluia optim a problemei ci doar una
aproximativ. Studiul complexitii algoritmilor aproximativi se ocup cu estimarea teoretic a
gradului de aproximare pe care soluia algoritmului aproximativ o ofer, deci implicit studiul
eficienei acestuia. Este evident c, atunci cnd soluia aproximativ este foarte apropiat de soluia
optim iar timpul de obinere al ei este unul polinomial i nu exponenial, este avantajoas folosirea
n practic a unui algoritm aproximativ performant. Desigur, soluiile oferite de algoritmii
aproximativi, chiar dac se apropie de soluia optim a problemei, nu ofer ns nici o informaie n
plus despre soluia optim, aceasta rmnnd n continuare nedeterminat.
________________________________________________________________________________
62
Structuri de date i algoritmi
_______________________________________________________________________________
De exemplu, n cazul Problemei Colorrii Grafului, soluia optim cere determinarea
numrului cromatic, adic a numrului minim de culori necesare pentru colorarea nodurilor grafului
astfel nct oricare dou vrfuri adiacente s fie colorate diferit.
Un exemplu de algoritm aproximativ de colorare a grafului ar fi urmtorul: fie c
1
, c
2
, , c
k
,
irul culorilor; parcurgnd ntr-o anumit ordine mulimea celor n vrfuri ale grafului v
1
, v
2
, ,
v
n
se coloreaz fiecare vrf cu culoarea de indice minimal care i este permis (innd cont de
culorile nodurilor adiacente lui). Parcurgerea celor n vrfuri precum i selectarea culorii de indice
minim necesit un timp polinomial, deci acest algoritm aproximativ este eficient n practic. Ceea
ce este mai dificil este estimarea gradului de aproximare a soluiei optime. Aceasta se face prin
calcularea mediei rapoartelor ntre numrul de culori obinut cu ajutorul acestui algoritm
aproximativ i numrul cromatic (care va trebui aflat apelnd la un algoritm exponenial, gen
backtracking). Eficiena acestui algoritm aproximativ este dat de msura n care valoarea medie a
raportului se apropie de valoarea 1.

Probleme insolvabile algoritmic
Chiar dac nu se cunoate nc rspunsul la Marea ntrebare, se cunoate n schimb
rspunsul la o alt ntrebare important:
exist probleme ce nu pot fi soluionate cu ajutorul calculatorului ?
Rspunsul este afirmativ i el a fost pentru prima dat afirmat n 1936 chiar de Alan Turing,
printele calculatoarelor actuale. Eforturile principale ale lui Turing la acea vreme erau
concentrate tocmai pentru cutarea rspunsului la aceast ntrebare. Lipsa de rigurozitate a
noiunilor: problem, soluie i calculator l-au obligat pe Turing s imagineze modelul matematic
riguros al mainii Turing i s formuleze Teza sa ce permite echivalarea mainii Turing cu noiunea
vag de algoritm, noiune care ine locul noiunii i mai vagi de soluie general a unei probleme.
Enunul simplificat al Problemei Stopului care l-a condus pe Turing la rspunsul ntrebrii
exist probleme insolvabile algoritmic? n mod afirmativ (printr-un exemplu concret de problem)
este urmtorul:
Exist vreo metod general i finit care s decid dac un algoritm (sau o procedur automat)
ofer rspuns n timp finit pentru un set de date de intrare oarecare ?
Ea este foarte asemntoare cu o alt problem insolvabil algoritmic, Problema a zecea a
lui Hilbert:
exist o metod general care s decid n timp finit dac o ecuaie diofantic oarecare are sau nu
soluie n numere ntregi ?
Ideea cheie care st la baza demonstraiei riguroase a insolvabilitii acestor probleme nu
este nou, ci ea a aprut pentru ntia oar n demonstraia teoremelor de incompletitudine ale
matematicii ale lui Gdel de la nceputul anilor 30. Aceast idee este inspirat din faimosul
paradox antic al mincinosului. Astfel, propoziiile de genul Eu sunt mincinos sau Eu spun n
fiecare moment o minciun au un coninut paradoxal. n analizarea coninutului logic al acestor
propoziii ce din punct de vedere semantic sunt de fapt nite negaii se ajunge rapid la paradoxul
semantic de negare a negaiei i, n consecin, nu li se poate determina valoare logic de adevrat
sau fals. Adic, este inacceptabil ca ele s fie adevrate, i este inacceptabil ca ele s fie false!
Godel i Turing au artat n mod asemntor c presupunnd, prin reducere la absurd, c
matematica este complet respectiv c problema stopului este solvabil se va ajunge inevitabil la
propoziii paradoxale din punct de vedere matematic riguros al coninutului logic.

________________________________________________________________________________
63
Structuri de date i algoritmi
_______________________________________________________________________________
Complexitatea algoritmilor, calculatorul i viitorul
De la Gdel i Turing ncoace (anii 30) au aprut o mulime de alte probleme insolvabile
algoritmic (fiecare surprinznd oarecum prin simplicitatea enunului) i despre care putem spune c
vor rmne s fie rezolvate exclusiv prin puterea minii umane (fr ajutorul mainilor automate
actuale), cel puin ct vreme va fi pstrat modelul abstract ce st la baza calculatoarelor actuale.
Momentan aceste probleme au o dificultate ce depete puterea noastr i nu li se pot ntrezrii
soluii. Vor fi aceste probleme soluionate vreodat ? Nu putem afirma, nici c vor fi, nici c nu vor
putea fi soluionate, dar c sunt cele mai complexe i mai dificile probleme ce au aprut n
matematic i informatic putem afirma cu siguran.

________________________________________________________________________________
64
Structuri de date i algoritmi
_______________________________________________________________________________
I.3. PROGRAMARE N TURBO-PASCAL

Pentru a putea utiliza algoritmii la rezolvarea problemelor, este necesar ca ei s fie
"implementai" ntr-un limbaj "neles" de calculator, iar acesta s execute aciunile cerute de
algoritm. Iar pentru a nva corect programarea este necesar s se neleag ntreaga activitate de
programare. In plus, testarea algoritmilor implementai se poate face doar prin traducerea acestora
ntr-un limbaj de programare. n acest scop vom prezenta un minim de cunotine despre limbajul
Pascal, suficiente ns pentru a scrie programe pentru a rezolva o varietate mare de probleme de
matematic (Boian i Frentiu [1992]).

1.3.1. Mediul de programare Turbo Pascal
Mediul de programare Turbo Pascal este un ansamblu de programe complex, conceput
pentru programatorii care utilizeaz limbajul Pascal. Mediul Turbo Pascal permite editarea
(introducerea i corectarea) programelor Pascal, compilarea programului surs introdus, execuia
acestuia dac el este corect sintactic i lexical. Programarea n limbajul Pascal este mult uurat de
acest mediu de programare interactiv cu ajutorul cruia programatorul poate corecta uor erorile de
compilare semnalate direct pe ecran n programul surs unde a fost indicat eroarea (prima eroare
dac sunt mai multe). Dup corectarea erorii programul se poate compila din nou pn cnd se
ajunge la o variant corect. n continuare se poate testa programul introdus prin execuia acestuia.
Toate aceste etape prezentate anterior (editare, compilare, execuie, precum i altele) se pot
parcurge uor din acest mediu, fr a mai apela la alte programe utilitare. Odat apelat mediul
Turbo Pascal putem efectua toate operaiile necesare parcurgerii etapelor programului Pascal fr a
prsi mediul. Prsirea mediului se va face doar la sfrit cnd programul este terminat.
Mediul de programare ofer o interfa prietenoas printr-un sistem de meniuri i opiuni ce
permit editarea fiierelor surs Pascal, compilarea acestora, execuia programelor obinute,
depanarea lor i multe altele.
Pornirea mediului de programare Turbo Pascal se face prin comanda Turbo<Enter> ntr-un
mediu MS-DOS, sau prin accesarea corespunztoare a unei icoane care corespunde mediului de
programare n cazul mediului Windows. Lansarea n execuie a mediului de programare Turbo
Pascal este semnalat de deschiderea unei fereastre de editare care permite editarea textelor surs
Pascal (programele scrise n limbajul Pascal). n partea de superioar a ferestrei este afiat meniul
principal iar n partea inferioar sunt afiate cteva comenzi importante ce se pot efectua direct fr
a apela sistemul de meniuri.
Pentru a accesa un fiier ce conine cod surs Pascal vom putea tasta direct F3 sau putem
accesa fiierul prin intermediul meniului principal (F10 - submeniul File opiunea Open), dup care
se va tasta numele fiierului (de exemplu Test<Enter>).
Dup aceasta, fiierul cu numele specificat i extensia implicit PAS va fi deschis, iar
fereastra de editare este pregtit pentru editarea programului (exemplu: Test.Pas).
Programul se va introduce rnd cu rnd, fiecare rnd fiind terminat cu <Enter>. n editarea
programului se pot utiliza comenzile de editare descrise n anexa A. Dup ce programul a fost
introdus se poate compila pentru a depista eventualele erori sintactice i lexicale. Aceasta se poate
________________________________________________________________________________
65
Structuri de date i algoritmi
_______________________________________________________________________________
realiza fie direct prin tastarea combinaiei de taste Alt+F9 sau F9, fie prin meniul principal (F10 -
submeniul Compile opiunea Compile sau Make). Dac au fost semnalate erori, atunci acestea se
vor corecta, apoi se va relua compilarea, i tot aa, pn cnd compilarea se termin cu succes.
n continuare, se poate trece la etapa de execuie a programului scris (editat) i compilat.
Execuia programului se poate realiza fie direct prin tastarea combinaiei de taste Ctrl+F9, fie prin
meniul principal (F10 - submeniul Run opiunea Run). Eventualele rezultate n timpul execuiei
programului sunt afiate ntr-o nou fereastr. La terminarea execuiei programului se va redeschide
fereastra de editare. Dac sunt depistate erori de execuie atunci programul se corecteaz la nivelul
codului surs i se va relua compilarea i execuia programului.
Dac se dorete terminarea sesiunii de lucru cu mediul Turbo Pascal atunci se prsete
acest mediu direct prin combinaia Alt+X sau prin meniul principal (F10, File i Exit). Dac fiierul
nu a fost salvat niciodat (comanda Save = F2 din submeniul File) atunci se cere confirmarea
salvrii dac programatorul dorete acest lucru (prin Yes).
Mediul Turbo Pascal mparte ecranul n trei zone astfel:
Fig. 4. Structura general a ferestrei de editare a mediului de programare Turbo
Pascal.
Fereastra de editare este utilizat pentru introducerea i corectarea programelor scrise n
limbajul Pascal. Din aceast fereastr se poate accesa meniul principal descris mai jos prin apsarea
tastei F10, apoi prin navigare cu ajutorul tastelor reprezentnd sgeile stnga sau dreapta alegem
________________________________________________________________________________
66
Structuri de date i algoritmi
_______________________________________________________________________________
opiunea dorit. Comenzile de editare sunt descrise i sunt aceleai ca i cele ale editorului WS (vezi
anexa A ). Se poate selecta i direct o anumit opiune din meniul principal prin tastarea simultan
Alt+x, unde x reprezint litera caracteristic din opiunea aleas descris mai sus cu caracter
ngroat ( File = F, Edit = E, ... Help = H ) .
Fig. 5. Structura meniului principal a ferestrei de editare a mediului de programare
Turbo Pascal.
n partea de jos a ecranului se afl afiat linia de memento care arat cu ce taste
(combinaie de taste) putem realiza un anumit lucru direct fr a mai trece prin meniul principal
astfel:

________________________________________________________________________________
67
Structuri de date i algoritmi
_______________________________________________________________________________
Fig. 6. Structura general a meniului memento a ferestrei de editare a mediului de
programare Turbo Pascal.
n continuare vom descrie posibilitile (facilitile) oferite de mediul Turbo Pascal prin
meniul principal:

- File: permite ncrcarea i salvarea fiierelor text ce conin programe surs Pascal (New,
Open=F3, Save=F2, ...), schimbarea directorului curent (Change Dir), tiprirea la imprimant a
programului curent (Print), executarea de comenzi Dos (Dos Shell) i terminarea sesiunii i
prsirea mediului (Exit=Alt+X).
- Edit: permite introducerea i corectarea fiierului Pascal, recuperarea textelor terse
(Undo=Alt+BkSp), mutarea unui bloc de text marcat ntr-o zon tampon numit clipboard
(Cut=Shift + Del), copierea unui bloc n zona tampon (Copy=Ctrl+Ins), inserarea n poziia
cursorului a unui bloc din zona tampon (Paste=Shift+Ins), tergerea unui bloc (Clear=Ctrl+Del) i
vizualizarea zonei tampon (Show clipboard). Pentru a marca un bloc (o secven de program surs)
se utilizeaz simultan tasta Shift i sgeile direcionale de pe tastatur.
- Search: realizeaz funciile de cutare a unui ir de caractere (Find), de nlocuire
(Replace), precum i repetarea ultimei comenzi de cutare/nlocuire (Search again), poziionarea
direct pe o linie din programul surs precizat prin numrul ei (Go to line number), i altele.
________________________________________________________________________________
68
Structuri de date i algoritmi
_______________________________________________________________________________
- Run: permite execuia unui program astfel:
- execuia ntregului program (Run=Ctrl+F9);
- execuia programului pn n poziia cursorului din programul surs (Go to
cursor=F4);
- execuia pas cu pas iar a subprogramelor ntr-un pas (Step over=F8);
- execuia pas cu pas, inclusiv a subprogramelor (Trace into=F7);

- Compile: realizarea compilarea unui program (Compile =Alt+F9), iar destinaia
programului obiect rezultat poate fi n memoria intern sau pe disc (Destination Memory/Disk),
compilarea automat a uniturilor dac acestea au fost modificate (Make=F9), sau necondiionat
(Build) i altele;
- Debug: permite depanarea programelor prin vizualizarea punctelor de ntrerupere
(Breakpoints), afiarea ferestrei de vizualizare a valorilor variabilelor (Watch), afiarea ferestrei de
rezultate (User screen=Alt+F5), vizualizarea i modificarea valorilor variabilelor
(Evaluate/modify=Ctrl+F4), adaug expresii n fereastra de vizualizare (Add watch = Ctrl+F7),
marcarea punctelor de ntrerupere (Add breakpoint i altele.
- Tools: deschide fereastr de mesaje (Messages) i altele.
- Option: seteaz opiuni de compilare (Compiler), directoarele de lucru utile (Directories),
preferine de editare, mouse, startare i culori (Environment), salvare configuraie (Save) ntr-un
fiier (Save a.).
- Window: permite operaii asupra ferestrelor de lucru astfel:
- Tile - toate ferestrele se vd simultan prin mprirea egal a ecranului,
- Cascade - ferestrele sunt aranjate una peste cealalt;
- Size/Move=Ctr+F5 - permite deplasarea i redimensionarea ferestrelor utiliznd
sgeile i tasta shift;
- Zoom=F5 - mrete fereastra activ;
- Next=F6 - afieaz (activeaz) urmtoarea fereastr;
- Close=Alt+F3 - nchide fereastra activ;
- List = Alt+0 - tiprete lista ferestrelor de lucru.
- Help: permite ndrumarea operatorului prin submeniuri i opiuni care conduc la
explicaii i exemple.

1.3.1.1. Programe simple Pascal
________________________________________________________________________________
69
Structuri de date i algoritmi
_______________________________________________________________________________

Limbajul Pascal, definit de Wirth, a aprut n anul 1970, i s-a rspndit rapid datorit
calitilor sale. Wirth a urmrit s prezinte conceptele de baz din domeniul programrii, n scopul
nsuirii acestei activiti. Dei iniial limbajul a fost gndit n scop universitar, el este folosit astzi
la programarea celor mai diverse probleme, pe toate sistemele de calcul existente (Cristea et al.
[1992]).
Ca orice limbaj de programare limbajul Pascal este construit folosind un alfabet ce conine
caracterele ntlnite n scrierea obinuit i cea matematic:
- literele (mari i mici) ale alfabetului latin:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
- cifrele zecimale: 0 1 2 3 4 5 6 7 8 9
- caractere speciale: + - * / . , ; : ( ) [ ] { } etc.
Cu ajutorul lor se vor construi toate instruciunile limbajului.
Menionm c literele mici se consider identice cu literele mari, exceptnd folosirea lor n
valori de tip string (texte). De asemenea, cel puin n constante de tip string, pe lng caracterele
prezentate mai sus, sunt permise toate caracterele existente la tastatura calculatorului. De fapt multe
particulariti ale limbajului depind de implementarea lui pe calculatorul folosit.
n prezentarea care urmeaz vom folosi notaia BNF (Backus-Naur Form) pentru a defini
elementele limbajului Pascal. De exemplu prin notaia:
s ::= e1 | e2 | { e3 [, e4] + } e5
vom nelege c prin definiie elementul s este e1, sau e2, sau construcia { e3 [, e4]+} e5,
care reunete expresiile:
e5
e3 + e5
e3 , e4 + e5
e3 , e4 + e3 + e5
etc.
Prin scrierea unei construcii ntre acoladele { } se indic faptul c acea construcie poate
s se repete de ori cte ori (inclusiv de zero ori). Parantezele drepte ngroate sunt folosite pentru
scrierea construciilor opionale; ceea ce se afl nchis ntre aceste paranteze poate lipsi.
Se observ c n sintaxa de mai sus se folosesc metasimbolurile [, ], { i }. A nu se
confunda cu caracterele [, ], { i } permise i folosite n anumite construcii Pascal.
Pentru alte metasimboluri vom alege anumite cuvinte, scrise cu litere mici ntre caracterele
< i > i scrise cursiv.
Ca n toate limbajele de programare i n Pascal se folosesc frecvent identificatorii. Prin
identificator, notat n definiiile sintactice care urmeaz prin <id>, se nelege o secven de litere
(mari sau mici) i cifre, primul caracter fiind obligatoriu o liter. De asemenea, n construcia
________________________________________________________________________________
70
Structuri de date i algoritmi
_______________________________________________________________________________
identificatorilor este permis i caracterul '_'. Acesta se recomand s se foloseasc n scrierea
identificatorilor compui din dou cuvinte unite prin acest caracter.
O parte dintre identificatori au un rol special n definirea instruciunilor limbajului Pascal.
Acetia se numesc cuvinte rezervate i sunt:

AND DOWNTO IF OR THEN ARRAY ELSE
IN PACKED TO BEGIN END LABEL PROCEDURE
TYPE CASE FILE MOD PROGRAM UNTIL CONST
FOR NIL RECORD VAR DIV FUNCTION NOT
REPEAT WHILE DO GOTO OF SET WITH

Cuvintele rezervate nu pot fi folosite n program n alt scop dect cel fixat, acela de a defini
sintaxa instruciunilor Pascal.
Pentru a sublinia care sunt cuvintele rezervate, n definiiile care urmeaz ct i n primele
programe date ca exemple, vom scrie cuvintele rezervate cu litere mari. De asemenea, aceste
cuvinte vor fi scrise ngroat, pentru a le diferenia clar de celelalte construcii datorate
programatorului.
1.3.1.2. Structura unui program Pascal
Un program Pascal const dintr-un titlu, o parte de declaraii i instruciunile care formeaz
programul principal. El are urmtoarea structur general:
<program> ::= <antet_program> ; <bloc> .
unde
<antet_program> ::= PROGRAM <id> [ ( <lista_id> ) ]
iar
<bloc> ::= <lista_decl> ; <ins_compus>

Construciile <lista_decl> i <ins_compus> vor fi complet nelese puin mai trziu, dup
ce se vor prezenta declaraiile i instruciunile limbajului Pascal. n general prin lista de elemente
<lista_e> se nelege un simplu element <e>, sau o succesiune de elemente
<lista_e> ::= <e> { s <e> }
unde separatorul s este virgula sau uneori caracterul ';', caz n care vom meniona acest
lucru.
n definiia blocului elementul <decl> este metasimbolul folosit pentru declaraia Pascal
________________________________________________________________________________
71
Structuri de date i algoritmi
_______________________________________________________________________________
care va fi definit n seciunea 4.2.5, iar <ins> este metasimbolul folosit pentru a nota o instruciune
Pascal i va fi definit n seciunea 4.2.6.
Aa cum se va vedea mai trziu, n definiia declaraiilor de procedur se folosete
metasimbolul <bloc>. Deci un bloc care conine o procedur conine un alt bloc care, la rndul lui,
poate conine alt bloc.
Oriunde n textul programului pot fi incluse comentarii. Acestea sunt folosite de ctre
utilizatori n scopul mbuntirii claritii programului i a explicrii semnificaiei unor notaii sau
pri de program. Ele nu sunt luate n seam de calculator, singurul lor scop fiind acela de a oferi
programatorului posibilitatea de a insera n program explicaii utile programatorului. Un comentariu
este orice text nchis ntre acolade
<comentariu> ::= { text } (* text *)
Prezentm n continuare un exemplu de program Pascal:
Exemplul I.20
PROGRAM RADICALI; { Programul 1 }
{ Exemplu de program Pascal }
VAR x, r: REAL; { Declaraii }
BEGIN { Instruciunea compus }
REPEAT
READLN(x);
r := SQRT(x); { Functia SQRT este o funcie }
{ standard pentru extragerea radicalului }
WRITELN('Radical din ', x, ' este ', r)
UNTIL x = 0
END.

1.3.3.3. Constante i variabile Pascal
Datele i rezultatele dintr-un program sunt reprezentate prin constante i variabile.
Constantele se caracterizeaz prin faptul c nu-i modific valoarea n timpul execuiei unui
program. Orice constant este precizat prin sintaxa ei i are o valoare bine definit.
Constantele pot fi: numerice, ir de caractere i booleene. La rndul lor constantele
numerice pot fi ntregi sau reale.
Constantele ntregi sunt cele care reprezint numerele ntregi din matematic i au sintaxa
obinuit de scriere a numerelor. De exemplu, 15, 1989, -314 sunt constante ntregi.
Constantele reale sunt cele care reprezint numerele reale. Scrierea unui numr real poate fi
n forma normal i n forma exponenial.
n forma normal este prezent att punctul zecimal "." ct i partea ntreag i partea
________________________________________________________________________________
72
Structuri de date i algoritmi
_______________________________________________________________________________
fracionar a numrului real. De exemplu 3.14159 1.72 -5.749 103.0 0.23 sunt constante reale
corecte. Notaiile .23A 103.+ 37.5. -123.+44 sunt greite.
n forma exponenial, un numr ntreg sau un numr real n forma normal este urmat de
litera E sau e i de un numr ntreg numit exponent. Valoarea numrului real scris n aceast form
este egal cu numrul scris n faa literei E nmulit cu 10 la puterea egal cu exponentul scris dup
litera E. De exemplu:
12345E-6 este egal cu 0.012345 ;
3.123456E5 este egal cu 312345.6 .
Constanta ir de caractere este o secven de caractere (un text) nchis ntre apostrofuri.
Valoarea constantei este chiar textul nchis ntre apostrofuri. Dac este necesar ca n text s apar i
apostroful el trebuie dublat. De exemplu:
'22 Decembrie 1989'
'L''Hospital'
'' { irul vid }
n cazul n care un singur caracter este nchis ntre apostrofuri avem o constant de tip
caracter. O constant ir de caractere este considerat ca fiind rezultatul concatenrii mai multor
constante de tip caracter.
Dei s-a afirmat la nceput c literele mari se consider identice cu cele mici, singura
excepie este folosirea lor n constanta ir de caractere. ntr-o asemenea constant fiecare liter mare
difer de litera mic corespunztoare.
Constanta boolean reprezint o valoare logic i se reprezint prin identificatorii TRUE
pentru valoarea logic "adevrat", respectiv FALSE pentru valoarea logic "fals".
Conceptul de variabil a fost deja prezentat n seciunea 1.2. Ea corespunde unei date care
i poate schimba valoarea n timpul execuiei programului. Variabila are un nume i poate primi o
valoare dintr-un domeniu bine precizat de valori. In Pascal numele unei variabile este un
identificator. In limbajul Pascal fiecare variabil are un tip care trebuie s fie declarat n program
nainte ca variabila s fie folosit.

1.3.3.4. Tipuri de date

Prin tip de date se nelege o mulime de valori i o mulime de operaii ce pot fi efectuate cu
valori de acest tip. Mulimea valorilor se mai numete i domeniul tipului.
Exist mai multe posibiliti de definire a unui tip de date, unele dintre ele vor fi prezentate
mai trziu. Menionm c unele tipuri de date sunt predefinite, iar altele sunt definite de ctre
programator n timpul scrierii programului. Dup elementele care formeaz domeniul tipului
deosebim tipuri de date simple, respectiv compuse cu ajutorul altor tipuri. De asemenea, putem avea
ca domeniu mulimea adreselor memoriei calculatorului. Deci un tip este:
<tip> ::= <tip_simplu> | <tip_structurat> | <tip_referin>
Tipul de date <tip_simplu> se definete n continuare, iar alte dou tipuri vor fi definite n
________________________________________________________________________________
73
Structuri de date i algoritmi
_______________________________________________________________________________
seciunile urmtoare (ARRAY i RECORD).
Tipurile simple de date conin tipurile numerice INTEGER i REAL, tipul BOOLEAN,
tipul CHAR, tipul enumerare i tipul subdomeniu. Avem:
<tip_simplu> ::= <tip_real> | <tip_ordinal>
unde
<tip_ordinal> ::= <tip_ntreg> | <tip_boolean> | <tip_caracter> | <tip_enumerare> |
<tip_subdomeniu>

Tipurile ntreg, real, boolean i caracter sunt predefinite i sunt marcate prin cuvintele
INTEGER, REAL, BOOLEAN, respectiv CHAR. Deci
<tip_real> ::= REAL
<tip_intreg> ::= INTEGER
<tip_boolean> ::= BOOLEAN
<tip_caracter> ::= CHAR

Tipurile INTEGER i REAL se refer la mulimile de numere ntregi i reale, dar mulimea
valorilor fiecrui tip este finit i depinde de calculatorul folosit.
Dei funciile Pascal vor fi indicate n seciunea urmtoare prezentm aici cteva funcii
definite asupra valorilor de tip ordinal sau de tip caracter.
Pentru fiecare tip ordinal, deci i pentru tipul caracter, mulimea valorilor este finit i
ordonat. Pentru obinerea rangului elementului x n aceast mulime ordonat se poate folosi
funcia ORD(x). Pentru primul element p din aceast mulime avem ORD(p) = 0. Excepie este
ORD(i) pentru i ntreg, cnd ORD(i)=i. Funcia SUCC furnizeaz succesorul unui element n
aceast mulime, deci SUCC(x) reprezint succesorul elementului x n domeniul valorilor i este
nedefinit pentru ultimul element din domeniu. Prin PRED(x) se noteaz predecesorul elementului x
n domeniul tipului i este nedefinit pentru primul element din domeniu.
Din definiiile de mai sus se deduc uor urmtoarele proprieti:
ORD( SUCC(x) ) = ORD(x) + 1;
ORD( PRED(x) ) = ORD(x) - 1.

SUCC(x) i PRED(x) trebuie s fie definite.
1.3.3.4. Tipul ntreg

Domeniul tipului ntreg este submulimea numerelor ntregi cuprinse n intervalul [-
MAXINT-1, MAXINT], unde MAXINT este o constant ntreag predefinit a crei valoare
depinde de calculatorul folosit i este determinat de mrimea locaiei pe care se reprezint un
________________________________________________________________________________
74
Structuri de date i algoritmi
_______________________________________________________________________________
numr ntreg n calculatorul respectiv (de exemplu MAXINT = 32767).
o
Semnificaia lui x o y
Operaia o Semnificaia lui x o y
+ adunare
- scdere
* nmulire
DIV mprire ntreag
/ mprire real
MOD Restul mpririi ntregi a lui x la y
Tab.1.3. Operaiile tipului INTEGER

Operaiile definite ntre valori de tip ntreg sunt +, -, *, DIV, MOD i /, iar semnificaia lor
se d n Tabelul 1.3. Uneori, - se noteaz i o operaie unar. Prin -x se nelege opusul lui x fa de
operaia de adunare.

1.3.3.5. Tipul real
Tipul real reprezint o submulime finit de numere reale aflate n intervalul [-vmax,
vmax], submulime care depinde de modul de reprezentare a numerelor reale n calculatorul folosit.
Deci vmax este o constant real care difer de la un calculator la altul, dar nu e o constant
predefinit ca MAXINT n cazul tipului INTEGER.
Operaiile definite ntre valori de tip real sunt adunarea, scderea, nmulirea i mprirea,
notate prin +, -, *, respectiv / . De remarcat c aceste operaii sunt definite i cnd un operand este
ntreg iar cellalt real, rezultatul fiind real, datorit conversiei implicite a tipului ntreg la real.
Menionm c n reprezentarea oricrui numr real n calculator se rein un numr finit de
cifre semnificative. Din aceast cauz rezultatul unei operaii cu numere reale este aproximativ.
Pentru a nelege exact aceste afirmaii este necesar cunoaterea reprezentrii numerelor n
calculator.

1.3.3.6. Tipul boolean
Domeniul tipului boolean const din mulimea valorilor logice "fals" i "adevrat", marcate
prin constantele FALSE, respectiv TRUE. Ordinea este FALSE < TRUE.
________________________________________________________________________________
75
Structuri de date i algoritmi
_______________________________________________________________________________
Operaiile logice binare sunt marcate prin AND (conjuncia logic) i OR (disjuncia
logic), iar negaia (operaie logic unar) prin NOT. Operatorii relaionali au n acest caz
semnificaii logice. Deci prin =, <>, <=, >=, sunt notate echivalena, neechivalena (SAU exclusiv),
implicaia, respectiv implicaia invers.
1.3.3.7. Tipul caracter
Tipul caracter este marcat prin identificatorul CHAR i reprezint mulimea caracterelor cu
care lucreaz calculatorul respectiv. Principial, ordinea acestor caractere poate s difere de la
calculator la calculator. ns indiferent de calculator, limbajul Pascal cere ca mulimea cifrelor
zecimale s fie codificat compact (diferena codurilor a dou cifre consecutive s fie 1), iar
submulimile literelor mari i a literelor mici s fie ordonate alfabetic.
Nu exist operaii definite asupra valorilor de tip CHAR. Pe lng funciile definite pentru
argument de orice tip ordinal, pentru tipul caracter mai ntlnim i funcia CHR. Pentru i ntreg,
CHR(i) furnizeaz caracterul de rang i din domeniul tipului CHAR. S observm c
ORD( CHR(i) ) = i
i
CHR( ORD(c) ) = c .

1.3.3.8 Tipul enumerare
Tipul enumerare se specific prin scrierea valorilor acestui tip ntre paranteze:
<tip-enumerare> ::= ( <lista-id> )
identificatorii din paranteze constituind valorile tipului enumerare definit. Ordinea lor este
cea dat de ordinea identificatorilor n list. Nu este permis ca o valoare a acestui tip (deci un
identificator) s fie reutilizat n definiia altui tip.
Exemple de tip enumerare:
Exemplul 1: (LUNI, MARTI, MIERCURI, JOI, VINERI, SAMBATA, DUMINICA)
Exemplul 2: (PRIMAVARA, VARA, TOAMNA, IARNA)
Pentru aceste exemple avem:
PRED(TOAMNA) = VARA
SUCC(JOI) = VINERI
ORD(LUNI) = 0
ORD(IARNA) = 3 .
Menionm c valorile variabilelor de tip enumerare nu pot fi citite i nici tiprite.

1.3.3.9. Tipul subdomeniu

Tipul subdomeniu poate fi definit din orice tip ordinal prin precizarea limitelor inferioar i
superioar care definesc valorile subdomeniului. Tipul ordinal pentru care se definete subdomeniul
________________________________________________________________________________
76
Structuri de date i algoritmi
_______________________________________________________________________________
se numete tip de baz al subdomeniului. Avem:
<tip-subdomeniu> ::= constanta1 .. constanta2
unde constanta1 i constanta2 sunt valori ale tipului ordinal de baz care satisfac
inegalitatea
Ord(constanta1) <= Ord(constanta2).

De exemplu:
- subdomeniul ntregilor de la 1 pn la 20: 1..20
- subdomeniul zilelor lucrtoare: LUNI .. VINERI
- caracterele cifre zecimale: '0' .. '9'.

1.3.3.9. Expresii Pascal
O expresie Pascal este format din operanzi i operatori. Deci o expresie Pascal are forma:
a[1] o[1] a[2] o[2] ... a[n] o[n] a[n+1]
unde a[i], i = 1, 2, ..., n+1, sunt operanzii expresiei, iar o[i], i = 1, 2, ..., n, sunt operatorii
expresiei. Deoarece n >= 0, pot exista expresii formate dintr-un singur operand. Acest operand
poate avea orice tip Pascal, el fiind i tipul expresiei. n funcie de tipurile operanzilor deosebim
expresii aritmetice, expresii relaionale, expresii logice i expresii ordinale.
ntruct n definirea expresiilor se folosesc i funciile, prezentm cteva funcii Pascal.

1.3.3.9.1. Funcii predefinite

Pe lng operaiile algebrice prezentate deja, exist i funcii frecvent folosite n rezolvarea
unor probleme, cum ar fi extragerea rdcinii ptrate, calculul valorii unei funcii trigonometrice,
calculul logaritmilor etc. Pentru efectuarea acestor calcule n limbajul Pascal exist funcii
predefinite, funcii pe care le dm n tabelul 4.2.1.

1.3.3.9.2. Expresii aritmetice
Expresiile aritmetice sunt expresii n care operanzii sunt valori numerice ntregi sau reale.
Operatorii sunt cei permii de tipurile ntreg i real; se cere ca operaia care leag doi operanzi s fie
definit n tipul acestor operanzi. Operanzii unei expresii aritmetice pot fi:
- constante numerice;
- variabile simple de tip numeric;
- elemente de tablou de tip numeric;
- funcii numerice;
- subexpresii aritmetice, adic o expresie aritmetic, eventual precedat de semnul '-',
________________________________________________________________________________
77
Structuri de date i algoritmi
_______________________________________________________________________________
nchis ntre paranteze.
Notaia S e m n i f i c a i a
abs(i) Valoarea (ntreag) absolut a ntregului i
abs(x) Valoarea (real) absolut a realului x
sqr(i) Ptratul ntregului i
sqr(x) Ptratul numrului real x
int(x) Partea ntreag a numrului real x dac x>0, respectiv
int(abs(x)) dac x<0
trunc(x) ntregul obinut din numrul real x prin eliminarea prii
fracionare
round(x) Cel mai apropiat ntreg de numrul real x
frac(x) Valoarea x - int(x), x real
exp(x) e la puterea x, pentru x ntreg sau real
sin(x) sinusul lui x
cos(x) cosinusul lui x
arctan(x) arctangenta din x, unde x este masura unghiului in radiani
ln(x) logaritm natural din x, x ntreg sau real > 0
sqrt(x) radical din x, x>=0
succ(i) succesorul valorii ordinale i
pred(i) predecesorul valorii ordinale
ord(e) numrul de ordine al valorii e n tipul expresiei ordinale
chr(i) caracterul de ordin i n tipul CHAR
odd(i) funcie logic cu valoarea TRUE dac i este impar i
FALSE dac i este par
Tab.1.4. Funcii Pascal predefinite.

Deci o expresie aritmetic, notat <exp-a>, se poate defini astfel:
<exp-a> ::= <term> <exp-a> + <term> <exp-a> - <term>
________________________________________________________________________________
78
Structuri de date i algoritmi
_______________________________________________________________________________
unde
<term> ::= <factor> <term> * <factor> <term> / <factor> <term> DIV <factor>
<term> MOD <factor>
iar
<factor> ::= <constant numeric fr semn>
<variabil de tip numeric>
<element de tablou de tip numeric>
<funcie de tip numeric>
( <exp-a> )
( -<exp-a> )
Menionm c prioritatea operaiilor este cea cunoscut i folosit n matematic. Pentru a
indica o alt ordine se vor folosi parantezele. De asemenea, menionm c expresiile aritmetice
definite mai sus pot fi precedate de operaia unar -, cu semnificaia cunoscut din matematic.
Tipul unei expresii aritmetice este ntreg dac toi operanzii sunt ntregi i expresia nu
conine operatorul /. Dac ns expresia conine acest operator, sau dac exist cel puin un operand
de tip real, atunci tipul expresiei este real.
n evaluarea unei expresii aritmetice se calculeaz mai nti toi operanzii. O subexpresie
aritmetic este tot un operand. n evaluarea ei se procedeaz ca la o expresie aritmetic; deci dac
toi operanzii sunt ntregi i operaiile sunt definite n tipul ntreg atunci rezultatul este ntreg.
Astfel, valoarea expresiei 5 div 2 + 1.0 este numrul real 3.0 i nu 3.5, ntruct primul
operand al adunrii are valoarea ntreag 2 deoarece 5 div 2 este o expresie de tip ntreg.

1.3.3.9.3.. Expresii relaionale
Expresia relaional are scopul de a permite scrierea n Pascal a unor relaii matematice
care pot fi adevrate sau false. Ea are forma
<e1> <op.rel.> <e2>
unde <e1> i <e2> sunt expresii care au acelai tip ordinal, sau au tipul real, sau sunt
elemente de acelai tip n care s-a definit operaia relaional <op.rel.>, iar
<op.rel.> ::= < | <= | = | > | >= | <>
Valoarea expresiei relaionale de mai sus este TRUE dac ntre valorile expresiilor <e1> i
<e2> are loc relaia indicat i este FALSE n caz contrar. De fapt aceste simboluri noteaz relaiile
cunoscute din matematic.
Atenie ns la relaia de egalitate ntre dou numere reale. Din cauza unor aproximri
calculele cu numere reale nu sunt exacte. De exemplu, dac x=i/3, expresia relaional x = x*3
poate fi fals ntruct, din cauza reprezentrii interne calculele cu numere reale nu sunt exacte, iar
x*3 nu este o valoare ntreag ci o valoare real foarte apropiat de i dar, totui, diferit de i.
Tot ca exemplu, menionm c dac A i B sunt dou mulimi de acelai tip atunci expresia
A = B va avea valoarea logic TRUE n cazul cnd mulimile A i B sunt egale i FALSE n caz
________________________________________________________________________________
79
Structuri de date i algoritmi
_______________________________________________________________________________
contrar.

1.3.3.9.4.. Expresii logice

Expresia logic este o expresie Pascal n care operatorii pot fi operatori logici binari:
AND pentru conjuncia logic;
OR pentru disjuncia logic,
iar operanzii pot fi:
- constante logice;
- variabile de tip logic;
- elemente de tablou de tip logic;
- funcii logice;
- expresii relaionale;
- subexpresii logice, adic expresii logice nchise ntre paranteze;
- negaia unui operand logic din cei de mai sus, deci NOT <operand logic>;
- expresia x in M unde M este o mulime i x o variabil avnd tipul de baz al mulimii M.
n determinarea valorii unei expresii logice se evalueaz mai nti operanzii i apoi
operaiile logice binare n ordinea prioritii lor: mai nti conjunciile logice (operaiile AND) i
apoi disjunciile logice (operaiile logice OR). Operaiile logice cu aceeai prioritate se evalueaz de
la stnga spre dreapta n ordinea scrierii lor.
Menionm c este necesar ca toi operanzii s fie definii, altfel este posibil ca evaluarea
unei expresii logice s se termine cu eroare. Astfel, n expresia logic (i<=10) AND (x[i]>0)
este posibil s ajungem la o eroare dac x are doar 10 componente i i are valoarea 11, ntruct
x[11] nu este definit, deci al doilea operand nu are sens. Unele implementri nu mai evalueaz al
doilea operand n cazul n care primul operand este FALSE, valoarea expresiei fiind n acest caz
FALSE.
De asemenea, menionm c ntr-o expresie logic n care apar operatorii + i AND, ultimul
considerat mai prioritar dect primul, este posibil s se scrie expresii fr sens. Astfel, expresia 0 <
A+B AND C < D este interpretat ca i expresia 0 < A+(B AND C) < D care nu are sens. De
aceea se cere ca, n astfel de cazuri, s se foloseasc parantezele pentru precizarea prioritii
operaiilor.

1.3.3.9.5.. Declaraii Pascal

________________________________________________________________________________
80
Structuri de date i algoritmi
_______________________________________________________________________________
ntr-un program Pascal trebuie precizate toate variabilele i denumirile simbolice nainte de
a le folosi. Spunem c o entitate este declarat atunci cnd ea apare ntr-o declaraie Pascal, n care
se precizeaz tipul ei, eventual alte informaii despre ea, utile att programatorului ct i
compilatorului. Deci, orice obiect pe care dorim s-l folosim ntr-un program Pascal trebuie mai
nti declarat n partea de declaraii a programului.
Dup obiectele pe care le reprezint deosebim urmtoarele declaraii Pascal:
- declaraii de etichete;
- declaraii (definiri) de constante;
- declaraii (definiri) de tipuri;
- declaraii de variabile;
- declaraii de subprograme.
Deci
<decl> ::= <def-et> | <def-const> | <def-tip> | <def-var> |<def-subp>
Dei nu este obligatoriu s le ntlnim pe toate n aceeai unitate de program, atunci cnd
sunt prezente ele trebuie scrise respectnd ordinea enumerrii de mai sus. De asemenea, n limbajul
Pascal standard ntr-o unitate de program fiecare declaraie poate apare cel mult odat. Limbajul
Turbo Pascal a renunat la aceste restricii.
n definiia sintactic a unui program Pascal s-a folosit metasimbolul <lista-decl>. Evident,
elementele acestei liste sunt declaraii, separatorul folosit fiind caracterul ';' .
Dei exist, nu vom folosi declaraia de etichete. Programarea structurat pretinde
renunarea la instruciunea GOTO, instruciune care cere folosirea etichetelor. Prin exemplele care
le dm artm c acest lucru, de altfel demonstrat, este posibil. n consecin, nici nu o vom
prezenta n acest text.
OBS 3.: Evit s foloseti instruciunea GOTO.

1.3.3.9.6.. Definirea constantelor

Prin metasimbolul <def_const> am notat o definire de constante cu nume, care are sintaxa
CONST <id> = <constanta> { ; <id> = <constanta> }
unde <id> este un identificator care va nota numele constantei definite, iar constanta care urmeaz
va preciza valoarea constantei definite. Ea poate fi numeric, boolean, sau un ir de caractere. De
exemplu:
CONST
PI = 3.141592653;
ORDIN = 5; N = 4;
MARCA = '...'
________________________________________________________________________________
81
Structuri de date i algoritmi
_______________________________________________________________________________
definete o constant cu numele PI i valoarea precizat dup semnul egal, alte dou constante cu
numele ORDIN i valoarea 5, respectiv cu numele N i valoarea 4 i constanta cu numele MARCA
cu valoarea egal cu stringul , compus din trei puncte.
Definirea unei constante este necesar atunci cnd ne referim la ea n mai multe pri ale
programului, pentru a prescurta scrierea, sau pentru a permite modificarea ulterioar uoar a
programului. Deci
OBS. 4: Folosete constante cu nume n locul celor anonime.


1.3.3.9.7. Definirea tipurilor
Declaraia <def-tip> de definire a unor tipuri noi are sintaxa

TYPE <id> = <tip> { ; <id> = <tip> }
unde <id> este un identificator ce reprezint numele tipului definit, iar <tip> este un tip definit cu
ajutorul tipurilor deja cunoscute (predefinite, sau definite anterior de utilizator). De exemplu, prin
declaraia:
TYPE domindici = 1..12
se definete un tip cu numele domindici care este un subdomeniu al lui INTEGER, format din toate
numerele ntregi cuprinse intre cele dou limite menionate, 1, respectiv 12.

1.3.3.9.7. Declararea variabilelor

Toate variabilele folosite ntr-un program Pascal trebuie declarate nainte de a fi folosite.
Declaraia de variabile, notat prin metasimbolul <def-var>, are sintaxa
VAR <lista-id> : <tip> { ; <lista-id> : <tip> }
unde <lista-id> este o list de identificatori, iar <tip> este un tip predefinit sau definit de
utilizator. Prin ea se declar toate variabilele din lista de identificatori <lista-id> ca avnd tipul
precizat dup caracterul ':'. De exemplu, prin
VAR M, N, I, J, K: INTEGER;
X, Y, Z: REAL
se declar cinci variabile de tip ntreg, avnd numele M, N, I, J i K i trei variabile de tip real cu
numele X, Y, i Z. Prin declaraia
VAR A: ARRAY[1..9] OF REAL
se declar un vector A cu nou componente. Tipul variabilei A, cel de "vector cu 9 componente
reale", este un tip anonim i nu mai poate fi folosit n alt parte a programului Pascal. Chiar i n
________________________________________________________________________________
82
Structuri de date i algoritmi
_______________________________________________________________________________
aceeai declaraie de variabile folosirea aceleai construcii pentru a defini variabila B tot "vector cu
9 componente reale" se consider diferit de prima. De exemplu prin declaraia
VAR A: ARRAY[1..9] OF REAL;
B: ARRAY[1..9] OF REAL
s-au declarat doi vectori, dar care se consider c nu au acelai tip, spre deosebire de declaraia
VAR C, D : ARRAY[1..9] OF REAL
prin care s-au definit dou variabile de acelai tip.
Astfel se impune o regul important n programare:
OBS. 1.5: Folosete tipuri de date cu nume n locul celor anonime.
Respectarea acestei reguli conduce, pe lng cele artate mai sus, la creterea claritii
textului i a posibilitii de modificare a textului surs (schimbarea structurii marcat prin acest
nume se poate face ntr-un singur loc, cel al definirii ei).
Variabilele i celelalte elemente declarate ntr-o procedur sunt locale n aceast procedur,
deci pot fi folosite n orice instruciune a procedurii, dar nu i n afara ei. De asemenea, ele pot fi
folosite n orice alt procedur declarat n interiorul acestei proceduri, ele fiind variabile globale
pentru acestea, aa cum se va arta n seciunea 4.3.3.

1.3.3.9.8. Instruciuni Pascal
Exist mai multe instruciuni Pascal, toate notate prin metasimbolul <ins>. Exist
instruciuni Pascal simple n interiorul crora nu se afl alte instruciuni i instruciuni structurate,
compuse din alte instruciuni. Deci
<ins> ::= <ins_simple> | <ins_structurate>
unde
<ins_simple> ::= <ins_atribuire> | <ins_vid> | <apel_procedur>
iar
<ins_structurate> ::= <ins_compus> | <ins_condiionale> | <ins_iterative>
Aceste instruciuni vor fi prezentate n continuare.

1.3.3.9.9. Instruciunea de atribuire
Instruciunea de atribuire are scopul de a atribui valori unor variabile. Ea are sintaxa
<ins_atribuire> ::= <variabila> := <expresie>
unde <variabila> i <expresie> sunt de acelai tip, exceptnd cteva cazuri menionate mai jos.
Tipurile tv i te ale elementelor <variabila> i <expresie> pot fi ntreg, real, boolean, enumerare sau
orice tip structurat cunoscut n programul n care apare instruciunea, cu excepia tipului fiier.
Instruciunea cere mai nti evaluarea expresiei din partea dreapt a semnului de atribuire
":=". Dac tv i te sunt identice atunci valoarea expresiei este atribuit variabilei din stnga
semnului de atribuire. Dac aceste tipuri difer atunci se semnaleaz eroare, exceptnd patru cazuri
________________________________________________________________________________
83
Structuri de date i algoritmi
_______________________________________________________________________________
care vor fi prezentate n continuare:
1) Astfel, dac te este INTEGER iar tv este REAL atunci se convertete valoarea ntreag a
expresiei ntr-o valoare real care se atribuie variabilei.
2) Dac tv i te sunt tipuri enumerare sau subdomeniu cu acelai tip de baz i dac valoarea
expresiei aparine tipului tv, aceast valoare se atribuie variabilei.
3) Dac tv i te sunt mulimi atunci este posibil ca unul sau ambele tipuri s fie subdomenii
ale aceluiai tip ordinal. Atribuirea este permis dac valorile din mulimea rezultat sunt incluse n
tipul de baz al variabilei din stnga semnului de atribuire.
4) A patra excepie se refer la tipul STRING; tv i te putnd fi tipuri STRING diferite.
Atribuirea este corect dac valoarea ei se poate atribui variabilei din stnga atribuirii.
Sintactic, n partea stng a semnului de atribuire, <variabila> poate fi o variabil simpl
sau o component a unui tablou sau alt tip de dat structurat. De asemenea, ea poate fi un tablou
atunci cnd i n partea dreapt este un tablou de acelai tip. n acest caz prin A := B, se nelege o
scriere condensat a atribuirilor A[i]:=B[i] pentru toate valorile indicelui i aflate n tipul de index
folosit n definirea tablourilor A i B.
n general, este posibil atribuirea A := B cnd i A i B sunt variabile de acelai tip. n
toate cazurile se cere ca partea dreapt a atribuirii s aib o valoare anterioar, altfel vom spune c
variabila B este neiniializat, iar atribuirea va conduce la erori logice n execuia programului.

1.3.3.9.10. Instruciunea compus i instruciunea vid

n definirea unor instruciuni structurate sau a construciei <bloc> din seciunea 2.1.2, se
cere folosirea unei singure instruciuni, aa cum se va vedea n continuare. Pentru a putea include n
aceste locuri grupuri de instruciuni, n Pascal este posibil s definim o succesiune de instruciuni ca
o singur entitate. Aceast entitate se numete instruciune compus i are sintaxa
BEGIN
<ins>;
{<ins> }
END
n limbajul Pascal caracterul ';' separ dou instruciuni; el nu are rolul de a marca sfritul
acestora. Adesea ns ntlnim caracterul ';' n faa cuvntului END. n acest caz se consider c
ntre ';' i END se afl o instruciune vid:
<ins-vid> ::=
Instruciunea vid are efect nul i n cazul menionat mai sus ea nu este necesar. Este
posibil s ntlnim situaii n care avem nevoie de aceast instruciune. De exemplu, dac la
ndeplinirea unei condiii dorim s mergem la sfritul programului fr a mai executa nimic, vom
face un salt la o instruciune vid, ultima instruciune din programul respectiv.
Subliniem ns c este interzis folosirea instruciunii vide, deci i a caracterului ';' n faa
cuvntului ELSE.
________________________________________________________________________________
84
Structuri de date i algoritmi
_______________________________________________________________________________

1.3.3.9.11. Citirea i scrierea datelor

Pentru transferul datelor ntre memoria intern i suportul extern de date se folosesc
procedurile READ i WRITE. Dei procedurile vor fi prezentate mai trziu, precizm semnificaia
acestor dou proceduri pentru a putea da n continuare exemple complete de programe Pascal.
Procedura READ se folosete pentru transferul datelor n memoria intern. Sintaxa apelului
acestei proceduri este:
READ ( <lista-var> )
unde <lista-var> este o list de variabile care pot avea unul din tipurile ntreg, real, sau caracter.
Efectul acestui apel este de atribuire a unei valori fiecrei variabile prezente n lista de
variabile. Valorile se iau de pe suportul extern ncepnd din punctul n care s-a ajuns dup citirea
anterioar. Valorile sunt astfel luate nct s corespund tipului variabilei corespunztoare. Dac
acest lucru nu este posibil atunci se va semnala o eroare n execuie.
Ca exemplu, dac X este o variabil de tip ntreg iar U i V sunt variabile de tip caracter,
instruciunea
READ(X, U, V)
cere atribuirea unei valori ntregi variabilei X i a cte o valoare caracter variabilelor U i
V. Dac pe suportul extern se afl 125 A atunci X va primi valoarea 125, variabila U va primi
valoarea ' ' (caracterul blanc), iar V va primi valoarea 'A'. Dac ns suportul extern conine 12.4 A
execuia se va termina cu eroare ntruct valoarea 12.4 nu are tipul ntreg.
Tot cu eroare se va termina execuia cnd pe suportul extern avem TEXT 25 ntruct prima
valoare ntlnit nu este un numr ntreg.
Procedura WRITE asigur transferul informaiei din memoria intern pe suportul extern.
Apelul procedurii are forma
WRITE ( <lista-write> )
unde <lista-write> este o list de expresii Pascal de orice tip.
Efectul acestui apel este tiprirea valorilor expresiilor din <lista-write>. Bineneles c
pentru a tipri aceste valori se vor evalua mai nti expresiile prezente n list. Valorile expresiilor
sunt tiprite dar nu sunt reinute n memorie i nu pot fi folosite n alte instruciuni din program.
Dac dorim s folosim valoarea unei expresii i n alte instruciuni atunci o vom atribui mai nti
unei variabile i vom folosi aceast variabil att n <lista-write> ct i n celelalte instruciuni.
Pentru a nelege mai bine procesul de introducere i extragere a datelor vom folosi
noiunea de nregistrare. Prin nregistrare vom nelege informaia pe care o transfer la un moment
dat o unitate periferic. Astfel, pentru un cititor de cartele o nregistrare era o cartel perforat.
Pentru imprimant o nregistrare va fi un rnd al hrtiei de scris (listingului), a crei lungime
depinde de imprimanta folosit (de obicei 80 sau 132 de caractere). Pentru un calculator personal o
nregistrare va fi un rnd al ecranului, sau o succesiune de caractere de lungime variabil, terminat
cu un caracter special EOLN (de la End Of Line).
________________________________________________________________________________
85
Structuri de date i algoritmi
_______________________________________________________________________________
Pe suportul extern datele de transferat se afl scrise, sau vor fi tiprite pe o succesiune de
nregistrri. La procedurile READ i WRITE atunci cnd se epuizeaz o nregistrare se ncepe o alt
nregistrare. Adeseori este ns necesar s se treac la o alt nregistrare nainte de a fi epuizat
precedenta. Pentru aceasta se pot folosi procedurile READLN i WRITELN, care au sintaxa i
semnificaia procedurilor READ, respectiv WRITE, dar cer n plus ca la terminarea execuiei lor s
se treac la nceputul unei noi nregistrri.

1.3.3.9.12. Instruciuni condiionale

Exist dou instruciuni Pascal care permit execuia unor instruciuni n funcie de
ndeplinirea unor condiii: instruciunile IF i CASE.

1.3.3.9.12.1. Instruciunea IF
Instruciunea IF are sintaxa
IF <cond> THEN <ins1>
sau
IF <cond> THEN <ins1> ELSE <ins2>
unde <cond> este o expresie logic iar <ins1> i <ins2> sunt instruciuni Pascal. Subliniem c dup
cuvntul THEN i n faa cuvntului ELSE nu poate fi scris caracterul ';', deci nu poate apare o
instruciune vid.
n ambele variante instruciunea cere mai nti evaluarea expresiei logice <cond>. Dac
valoarea obinut este TRUE atunci se execut instruciunea <ins1> cu care se ncheie execuia
instruciunii IF. Dac valoarea obinut este FALSE atunci, n cazul variantei a doua se execut
instruciunea <ins2>, iar n cazul primei variante nu se execut nimic.
Aceast instruciune permite scrierea in Pascal a structurilor alternative i este echivalent
ca semnificaie cu propoziia Pseudocod:

Dac <cond> atunci <ins1>
altfel <ins2>
Sfdac
Ca un prim exemplu, pentru a efectua atribuirea V:=
X
n Pascal putem scrie:
IF X < 0 THEN V := -X ELSE V := X
Exemplul 21: Exemplu de rezolvare a ecuaiei de gradul 2.
Algoritmul Ecgr2 este:
Citete a, b, c;
________________________________________________________________________________
86
Structuri de date i algoritmi
_______________________________________________________________________________
Fie d := b*b - 4*a*c
Dac d < 0 atunci kod := 0
altfel kod := 1; r := radical din d
x1 := (-b-r)/(a+a); x2 := (-b+r)/(a+a)
sfdac
Dac kod = 0 atunci Tipareste('Ec. nu are rad. reale')
altfel Tipareste('Radacinile ec. sunt:', x1, x2)
sfdac
sf-Ecgr2

Programul Pascal corespunztor este urmtorul:
PROGRAM Ecgr2; { Programul 4.2: Rezolvarea}
{ecuatiei de gradul 2}
VAR a, b, c, {Coeficienii ecuaiei}
d, {Discriminantul ecuaiei}
r, {variabil de lucru}
x1, x2: REAL; {Rdcinile}
kod: INTEGER; {kod =0 pt. rd.reale, 1_complexe}
BEGIN
WRITELN('Se rezolva ecuatia de gradul doi');
WRITELN('Dati coeficientii a, b, c'); READLN(a, b, c);
d := b*b - 4*a*c;
IF d < 0 THEN
kod := 0
ELSE
BEGIN
kod := 1; r := sqrt(d);
x1 := (-b-r)/(a+a);
x2 := (-b+r)/(a+a)
END;
IF kod = 0
THEN WRITE('Ec. nu are radacini reale')
ELSE
WRITE('Radacinile ecuatiei sunt:', x1, x2);
________________________________________________________________________________
87
Structuri de date i algoritmi
_______________________________________________________________________________
END.


1.3.3.9.12.2.. Instruciunea CASE
Instruciunea CASE permite selectarea unei instruciuni dintr-o mulime de instruciuni
marcate, n funcie de valoarea unui selector. Sintaxa instruciunii este
CASE <eo> OF
<lista-c> : <ins> { ;
<lista-c> : <ins> }
[ ELSE <ins> ]
END
unde <eo> este o expresie de tip ordinal, <lista-c> este o list de constante-case, fiecare
constant-case avnd tipul ordinal al expresiei <eo>. n <lista-c> n locul unei constante poate apare
i un subdomeniu c1..c2 pentru o scriere mai condensat n cazul cnd constantele sunt consecutive.
Execuia instruciunii CASE cere mai nti evaluarea expresiei <eo>, obinndu-se o
valoare v, care constituie valoarea selectorului. Apoi se caut n listele de constante-case constanta
egal cu v i se execut instruciunea a crei etichet este chiar v.
Dac nu exist nici o instruciune cu eticheta v atunci, n cazul c este prezent cuvntul
ELSE se execut instruciunea ce urmeaz dup acest cuvnt, altfel nu se execut nici o
instruciune.
Exemplul 22: Ca exemplu vom scrie un program Pascal care calculeaz valoarea unei funcii

PROGRAM Valf; { Programul 2: Valoarea unei funcii }
{ Instruciunea CASE }
VAR x, f : REAL;
a : CHAR;
BEGIN
WRITELN('Se calculeaza f(x,a). Introducei x si a');
READ(a, x);
CASE a OF
'A': f := 5*x-8; { cazul a = 'A' }
'B': f := sin(x); { cazul a = 'B' }
'C': f := 3*x+1 { cazul a = 'C' }
END {CASE};
WRITE('f(', x, ',', a, ')=', f)
________________________________________________________________________________
88
Structuri de date i algoritmi
_______________________________________________________________________________
END.

1.3.3.9.13.. Instruciuni repetitive
n Pascal exist trei instruciuni care permit execuia repetat a unui grup de instruciuni i
anume instruciunile FOR, WHILE i REPEAT.
1.3.3.9.13.1. Instruciunea FOR
Aceast instruciune permite execuia repetat a unei instruciuni n funcie de valoarea
unui contor. Ea are sintaxa
FOR <v> := <e1> TO <e2> DO <ins>
sau
FOR <v> := <e1> DOWNTO <e2> DO <ins>
Aici <v> este un identificator de variabil numit contor, iar <e1> i <e2> sunt expresii,
toate trei avnd acelai tip ordinal (deci nu pot avea tipul real). Valorile vi i vf ale expresiilor <e1>
i <e2> se calculeaz o singur dat la nceputul execuiei instruciunii FOR. Variabila contor <v>
va lua valori ntre limitele vi i vf, cresctor dac n instruciune figureaz cuvntul TO i
descresctor dac n instruciune figureaz cuvntul DOWNTO. Semnificaia acestei instruciuni
este dat prin urmtorul algoritm:
@Calculeaz valorile vi i vf ale expresiilor e1, respectiv e2;
DAC c1 ATUNCI
FIE v := vi;
REPET
@Execut instruciunea ins;
DAC c2 ATUNCI
v:=e3
SFDAC
PNCND c3 SFREP
SFDAC
unde condiiile c1, c2 i c3 i expresia e3 sunt definite n continuare:

Condiii TO DOWNTO
c1 vi = vf vi >= vf
c2 v < vf v > vf
c3 v >=vf v <= vf
________________________________________________________________________________
89
Structuri de date i algoritmi
_______________________________________________________________________________
e3 este SUCC(v) PRED(v)
Tabelul 6: Definirea condiiilor pentru execuia instruciunii FOR.

Contorul v poate fi folosit n instruciunea <ins> dar nu este permis modificarea valorii
sale. Dei unele implementri permit acest lucru, recomandm s nu se modifice valoarea variabilei
contor v n instruciunea <ins>.
Astfel, n mediul Turbo-Pascal nu se consider eroare modificarea variabilei contor, dar
execuia unui astfel de program devine imprevizibil. De exemplu, execuia urmtoarelor
instruciuni intr ntr-un ciclu infinit:
For i:=1 to 5 do {La execuia acestui grup se vor tipari}
begin { int=1, apoi 3, 5, 7, 9, ... }
writeln('int=',i); { deci se intra in ciclu infinit}
readln(j); { in Turbo 7.0 ! }
i:=i+1;
end
Unii programatori folosesc intenionat, atunci cnd e posibil acest lucru, modificarea
valorii contorului pentru a fora ieirea din ciclu. O astfel de programare ncalc semnificaia
instruciunii FOR i nu este recomandabil.
Ca un prim exemplu de folosire a instruciunii FOR dm un program care tiprete toi
divizorii proprii ai numrului natural n>2.
Exemplul 23:
PROGRAM Divizori; { Programul 4.4: Divizorii lui n }
VAR n,i : INTEGER;
BEGIN
WRITELN('Se tiparesc divizorii lui n');
WRITE('Dati n='); READLN(n);
FOR i:=2 TO n-1 DO
IF n MOD i = 0 THEN
WRITELN(i);
END.

1.3.3.9.13.2. Instruciunea WHILE
Aceast instruciune are sintaxa
WHILE <cond> DO <ins>
unde <cond> este o expresie logic iar <ins> este o instruciune Pascal. Semnificaia instruciunii
________________________________________________________________________________
90
Structuri de date i algoritmi
_______________________________________________________________________________
WHILE este aceeai cu a propoziiei Pseudocod:
CTTIMP <cond> EXECUT
<ins> SFCT
Deci execuia instruciunii WHILE cere urmtoarele:
1. evaluarea expresiei logice <cond>;
2. dac valoarea expresiei este TRUE atunci se execut instruciunea <ins> i se revine la
pasul 1, altfel execuia se termin.
Cu alte cuvinte, ea cere execuia repetat a unei instruciuni Pascal n funcie de valoarea de
adevr a unei expresii logice. Dac iniial expresia logic este fals execuia instruciunii respective
nu va avea loc niciodat.
Ca exemplu, vom transcrie n Pascal urmtorul algoritm care gsete primele n numere
prime (Mocanu, et al. [1993]).
Exemplul 23:
Pseudocod:
Algoritmul PRIME este: {Determina primele n numere prime}
Citete n;
Fie k:=2; p[1]:=2; p[2]:=3; i:=5;
Cttimp k<n execut
Fie j:=1;
Cttimp j<=k i (i mod p[j] <> 0) execut
j:=j+1
sfct
Dac j>k atunci
k:=k+1;
p[k]:=i
sfdac
i:=i+2;
sfct
Tiprete p[j], j=1,n;
sf-Prime
Programul Pascal:
PROGRAM PRIME; { Programul 4.5: Calculeaz
primele n numere prime }
________________________________________________________________________________
91
Structuri de date i algoritmi
_______________________________________________________________________________
VAR n,i,j,k : INTEGER;
p : ARRAY [1..200] OF INTEGER;
BEGIN
WRITELN('Se tiparesc primele n numere prime!');
WRITE('Dati n='); READLN(n);
k:=2; p[1]:=2; p[2]:=3; i:=5;
WHILE k<n DO
BEGIN
j:=1;
WHILE (j<=k) AND (i mod p[j] <> 0) DO
j:=j+1;
IF j>k THEN
BEGIN
k:=k+1;
p[k]:=i
END;
i:=i+2

END;
WRITELN('Primele ',n,' numere prime sunt:');
FOR j:=1 TO n DO WRITELN(' p(',j,')=',p[j])
END.

1.3.3.9.13.3. Instruciunea REPEAT
Aceast instruciune permite execuia repetat a unui grup de instruciuni. Ea are sintaxa
REPEAT <ins> { ; <ins> } UNTIL <cond>
unde <ins> este o instruciune Pascal, iar <cond> este o expresie logic. Instruciunea este
echivalent cu urmtoarea propoziie Pseudocod:
REPET
<ins> { <ins> }
PNCND <cond> SFREP
Deci semnificaia instruciunii este urmtoarea:
1. se execut instruciunile scrise ntre cuvintele REPEAT i UNTIL;
________________________________________________________________________________
92
Structuri de date i algoritmi
_______________________________________________________________________________
2. se evalueaz expresia logic <cond>. Dac valoarea expresiei este TRUE atunci execuia
se termin, altfel se revine la pasul 1.
Ca exemplu de folosire a instruciunii REPEAT vom transcrie n Pascal urmtorul algoritm
pentru ordonarea descresctoare a unui ir de numere reale.
Exemplul 24:
Pseudocod:
Algoritmul Ordon este: {Ordoneaz descresctor}
{numerele x[1], ... , x[n]}
Citete n, (x[i],i=1,n);
Repet k:=0;
Pentru i:=1,n-1 execut
Dac x[i]<x[i+1] atunci
k:=1;
t:=x[i];
x[i]:=x[i+1];
x[i+1]:=t;
sfdac
sfpentru
pncnd k=0 sfrep
Tiprete x[i],i=1,n;
sfalgoritm

Programul Pascal corespunztor este:
PROGRAM Ordon; {Programul 4.6: Ordonarea unui sir de numere}
VAR t : REAL;
n,i,k : INTEGER;
x : ARRAY [1..100] OF REAL;
BEGIN
WRITELN('Se ordoneaz o secventa de numere reale');
WRITE('Nr.termenilor='); READLN(n);
WRITELN('Dati termenii');
FOR i:=1 TO n DO
READ(x[i]);
WRITELN;
________________________________________________________________________________
93
Structuri de date i algoritmi
_______________________________________________________________________________
WRITELN('Sirul initial este:');
FOR i:=1 TO n DO
WRITE(x[i]:8:1);
REPEAT
k:=0;
FOR i:=1 TO n-1 DO
IF x[i] < x[i+1] THEN
BEGIN
k:=1;
t:=x[i];
x[i]:=x[i+1];
x[i+1]:=t
END;
UNTIL k=0;
WRITELN(' Sirul ordonat este:');
FOR i:=1 TO n DO
WRITE(x[i]:8:2);
END.

1.3.3.10. Subprograme Pascal

Subprogramele n Pascal corespund subprogramelor din Pseudocod. Rolul i importana lor
sunt cele deja menionate n capitolul doi. Importana subprogramelor n programare a fost deja
subliniat n capitolul trei. n scopul refolosirii subalgoritmilor i subprogramelor e bine ca pentru
orice problem s descriem un subalgoritm pentru rezolvarea ei.
Obs. Xx: Concepe subalgoritm i scrie subprogram pentru orice problem care-ar putea fi rentlnit
n viitor.
1.3.3.10.1. Sintaxa subprogramelor Pascal
Ca i n alte limbaje de programare i n limbajul Pascal exist dou tipuri de subprograme:
funcii i proceduri. Definirea acestor subprograme n cadrul unui program Pascal se face n partea
de declaraii. Avem
<def-subprogram> ::= <def-funcie> <def-procedur>
________________________________________________________________________________
94
Structuri de date i algoritmi
_______________________________________________________________________________
unde <def-funcie> ::= <antet-funcie> ; <bloc>
<def-procedur> ::= <antet-procedur> ; <bloc>
iar
<antet-funcie> ::= FUNCTION <id> [ (l.p.f.) ] : <tipf>
<antet-procedur> ::= PROCEDURE <id> [ (l.p.f.) ]
n aceast sintax <id> este un identificator care constituie numele subprogramului definit.
Lista parametrilor formali <l.p.f.> este opional i ea precizeaz variabilele de care depinde
subprogramul i tipul acestor variabile.

1.3.3.10.2. Lista parametrilor formali

Lista parametrilor formali este format din mai multe seciuni de parametri separate ntre
ele de caracterul ';'. Sintaxa acestei liste este:
<l.p.f.> ::= <spf> { ; <spf> }
unde prin <spf> s-a notat o seciune de parametri formali, seciune care are sintaxa
<spf> ::= <sp-val> <sp-var> <pf-funcie> <pf-procedur>
Din punct de vedere sintactic seciunea de parametri valoare <sp-val> este orice list de
identificatori urmat de caracterul ':' i de un identificator de tip care va fi tipul tuturor
identificatorilor din lista de identificatori. Deci
<sp-val> ::= <lista-id> : <id-tip>
Seciunea de parametri variabil <sp-var> are sintaxa
<sp-var> ::= VAR <lista-id> : <id-tip>
unde <id-tip> este un identificator de tip, definit anterior, deci asemntoare seciunii parametrilor
valoare, singura diferen fiind prezena cuvntului VAR n faa listei.
Menionm c identificatorii care noteaz parametrii formali nu pot fi declarai din nou n
partea de declaraii a subprogramului. Ei se consider declarai i pot fi folosii n tot subprogramul,
ca orice alt variabil local definit n subprogram.
Ca semnificaie, parametri formali noteaz datele de intrare (cele presupuse cunoscute) i
datele de ieire (rezultate) ale subprogramului. Ei sunt chiar parametrii formali din definiia
subalgoritmilor corespunztori.

1.3.3.10.3. Variabile locale i variabile globale

n definiia unui subprogram apare la nceput un antet, dup care urmeaz un bloc. Deci
subprogramul are o structur similar unui program. S ne reamintim c un bloc const din dou
pri: o list de declaraii i o instruciune compus. Elementele definite n lista de declaraii sunt
locale pentru blocul n care sunt definite. Acesta constituie domeniul de vizibilitate al acestor
________________________________________________________________________________
95
Structuri de date i algoritmi
_______________________________________________________________________________
elemente; ele pot fi folosite numai n interiorul subprogramului n care au fost declarate, nu i n
afara acestuia.
Fie S un subprogram al programului P. Pe lng variabilele locale ale subprogramului S
toate elementele declarate n lista de declaraii ale programului P sunt considerate globale pentru
subprogramul S i pot fi folosite n acest subprogram. Deci elementele declarate n S pot fi folosite
numai n S, nu i n restul programului P. Ele sunt locale pentru S, dar sunt globale i pot fi folosite
n subprogramele S1 i S2 incluse n S. Elementele definite n P sunt globale i pot fi folosite n S,
S1 i S2.
Considernd programul principal ca un bloc de nivel 0, vom considera subprogramele
definite n el ca blocuri de nivel 1. n general, un bloc definit ntr-un bloc de nivel i are nivelul i+1.
Dac ntr-un bloc de nivel i se folosete o variabil v i acelai identificator v noteaz o
variabil ntr-un bloc de nivel i+1, cele dou variabile se consider distincte dei au acelai nume. n
acest caz variabila din blocul interior este cea considerat existent n acest bloc, iar cea exterioar
nu exist dect n partea blocului de nivel i exterioar blocului de nivel i+1.
Ca exemplu, s considerm programul 4.9 din seciunea 4.3.6. n procedura S1 se folosete
variabila local x. Dar i n programul principal se folosete o variabil global cu numele x.
ntruct procedura S1 folosete variabila local cu numele x, variabila global x i pierde
semnificaia n interiorul acestei proceduri (n care exist o variabil local cu numele x). Cele dou
variabile (cu acelai nume x) au rezervate locaii de memorie distincte i, n consecin, sunt
distincte. Ct privete folosirea variabilelor globale recomandm

Obs. Xx: Nu folosii variabile globale dect n cazuri speciale.

1.3.3.11. Funcii Pascal
Am vzut c definiia unei funcii const dintr-un antet i dintr-un bloc care va defini
aciunile prin care se calculeaz valoarea funciei. n antet se precizeaz numele funciei, lista
parametrilor formali i tipul funciei, <tipf>. Acesta trebuie s fie un nume de tip referin, sau un
tip simplu.
Este necesar ca n instruciunile din corpul <bloc> al funciei s existe cel puin o atribuire
prin care identificatorului <id> s i se atribuie o valoare.
Apelul unei funcii se face scriind ntr-o expresie numele funciei urmat de lista
parametrilor actuali. Trebuie s existe o coresponden biunivoc ntre parametrii actuali i cei
formali folosii n definiia funciei. Dac nu au existat parametri formali n definiie atunci apelul se
face scriind doar numele funciei. Despre corespondena dintre parametrii formali i parametrii
actuali vom vorbi n seciunea 4.3.6.
Ca exemplu dm n continuare un program care folosete un subprogram de tip funcie
pentru a obine numrul zilelor lunii cu numrul de ordine i pentru a calcula a cta zi din anul curent
este ziua curent (zi, luna, an).
Se folosesc dou funcii:
________________________________________________________________________________
96
Structuri de date i algoritmi
_______________________________________________________________________________
- NRZILE(i) furnizeaz numrul zilelor existente n luna i;
- BISECT(an) adevrat dac anul dintre paranteze este bisect.
Exemplul 25:
Algoritmul n Pseudocod este urmtorul:

ALGORITMUL NUMR_ZILE ESTE:
CITETE zi, luna, an;
FIE nr := zi;
DAC luna > 1 ATUNCI
PENTRU i := 1, luna-1 EXECUT
nr := nr + NRZILE(i)
SFPENTRU
SFDAC
DAC luna > 2 ATUNCI
DAC BISECT(an) ATUNCI
nr := nr + 1
SFDAC
SFDAC
TIPRETE nr;
SFALGORITM

Programul Pascal corespunztor este urmtorul:
PROGRAM APELFUNCTIE; { Programul 4.7 Exemplu de funcii Pascal}
VAR zi, luna, an, { Aceste variabile conin data curent }
nr: INTEGER; { nr va fi rezultatul cerut }
FUNCTION NRZILE(i: INTEGER): INTEGER; {Furnizeaza numarul zilelor}
{lunii cu numarul i}
BEGIN
CASE i OF
2: NRZILE := 28;
4, 6, 9, 11: NRZILE := 30;
1, 3, 5, 7, 8, 10, 12: NRZILE := 31
END {CASE}
END; {Nrzile}
________________________________________________________________________________
97
Structuri de date i algoritmi
_______________________________________________________________________________

FUNCTION BISECT(a: INTEGER): BOOLEAN; {Adevarata daca a este an bisect}
BEGIN
IF a mod 4 = 0 {and alte cerinte} {verivica daca a este an bisect}
THEN BISECT := TRUE
ELSE BISECT := FALSE
END; {Bisect}

BEGIN {programul principal}
WRITELN('Dati data curenta.');
WRITE('ziua = '); READLN(zi);
WRITE('luna = '); READLN(luna);
WRITE('anul = '); READLN(an);
nr := zi;
IF luna > 1 THEN
FOR i := 1 TO luna - 1 DO
nr := nr + NRZILE(i);
IF luna > 2 THEN
IF BISECT(an)
THEN nr := nr + 1;
WRITE('Data(', zi, ',', luna, ',', an, ') este a ');
WRITELN(nr, '-a zi din an');
END.

Funcia NRZILE definit mai sus este apelat n partea dreapt a unei atribuiri prin scrierea
ei n locul unei expresii. La fel, funcia boolean BISECT este apelat prin scrierea ei ntr-o
expresie logic.

1.3.3.12. Instruciunea apel de procedur

Apelul unei proceduri se face scriind numele procedurii urmat de lista parametrilor actuali
pe locul unei instruciuni, ceea ce echivaleaz cu execuia tuturor instruciunilor din bloc.
<apel-procedur> ::= <id> [ (<lista-p.a.> ]
________________________________________________________________________________
98
Structuri de date i algoritmi
_______________________________________________________________________________
Apelul unei proceduri are ca efect execuia tuturor instruciunilor procedurii apelate,
considernd c fiecare parametru formal este egal cu parametrul actual corespunztor (a se vedea
seciunea 4.3.6).
Dm un exemplu de program n care se definesc i se apeleaz proceduri. n plus,
programul ilustreaz modul de lucru cu cifrele privite drept caractere, precum i folosirea funciei
ORD.
Se cere s se tipreasc toate numerele ntregi ntlnite ntr-un ir de caractere care se
termin prin caracterul '$'.
Algoritmul de rezolvare se d n continuare. El folosete un subalgoritm, CITCIFRA(b,c),
care citete un caracter c i atribuie lui b valoarea TRUE dac c este o cifr, respectiv FALSE n caz
contrar.
Exemplul 26:
Algoritmul n Pseudocod este urmtorul:

ALGORITMUL CONVERSII ESTE:
REPET
@Caut o cifr {cu care ncepe un ntreg}
@Calculeaz numrul ntreg format din cifrele consecutive ntlnite.
@Tiprete numrul gsit.
PNCND c='$' SFREP
SFALGORITM

Programul Pascal corespunztor se d n continuare.
PROGRAM CONVERSII; { Programul 4.8: Conversii
{de secvente de cifre in intregi}
VAR c: CHAR;
nr: INTEGER;
b: BOOLEAN;

PROCEDURE CITCIFRA(Var b: BOOLEAN; {b=TRUE daca c este}
Var c: CHAR); {cifra; c=caracterul citit}
BEGIN
READ(c); b:= TRUE;
IF (c<'0') OR (c>'9') THEN
b := FALSE;
________________________________________________________________________________
99
Structuri de date i algoritmi
_______________________________________________________________________________
END;

BEGIN {Programul principal}
REPEAT
CITCIFRA(b, c);
WHILE NOT(b) AND (c<>'$') DO
CITCIFRA(b, c);
IF c <> '$' THEN
BEGIN
nr := 0;
REPEAT nr := nr*10 + Ord(c) - Ord('0');
CITCIFRA(b, c);
UNTIL NOT(b);
WRITELN('nr. citit = ', nr)
END
UNTIL c='$'
END.

1.3.3.13. Corespondena dintre parametri actuali i formali

Apelul unui subprogram se face scriind numele acestuia urmat de lista parametrilor actuali.
ntre parametrii din lista parametrilor actuali i parametrii din lista parametrilor formali trebuie s
existe o coresponden biunivoc, iar parametrii care sunt n coresponden trebuie s aib acelai
tip. De fapt, ei trebuie s aib aceeai semnificaie, s se refere la acelai obiect, s reprezinte
aceeai structur de date.
Sintactic un parametru actual poate fi o expresie Pascal, o variabil, un identificator de
procedur sau un identificator de funcie.

1.3.3.13.1. Parametri valoare
Parametrul actual corespunztor unui parametru formal valoare f poate fi orice expresie
Pascal e de acelai tip cu parametrul f. La apelul subprogramului se calculeaz valoarea expresiei e
i se atribuie valoarea obinut parametrului formal f. Mai exact, parametrul formal f de tip valoare
are rezervat o locaie de memorie n care se depune valoarea expresiei e nainte de a ncepe
execuia instruciunilor subprogramului. n continuare aceast variabil f este considerat variabil
local n subprogram. Ea i poate schimba valoarea dar aceast valoare nu poate fi transmis n
unitatea de program n care s-a fcut apelul.
________________________________________________________________________________
100
Structuri de date i algoritmi
_______________________________________________________________________________
Menionm c este posibil ca elementele f i e s nu aib acelai tip. Excepiile sunt cele
permise de atribuirea f := e.
De asemenea, menionm c parametrii formali de tip valoare corespund variabilelor care se
consider cunoscute la intrarea n subalgoritm (datelor de intrare).
Prezentm n continuare un program n care se poate vedea un exemplu de apel al unui
subprogram cu parametri valoare.
Exemplul 27:
PROGRAM Parval; { Programul 4.9: Parametri formali }
VAR x, z : INTEGER; { de tip valoare i variabila }

PROCEDURE S1(y: INTEGER);
VAR x: INTEGER;
BEGIN
x := y*y;
y := x;
z := y-4;
writeln('In procedura y, z = ', y:5, z:5);
END; {S1}

BEGIN
FOR x := 2 TO 4 DO
BEGIN
S1(x);
writeln('In program x, z = ', x:5, z:5);
END
END.
La execuia acestui program se obin urmtoarele rezultate:
In procedura y, z = 4 0
In program x, z = 2 0
In procedura y, z = 9 5
In program x, z = 3 5
In procedura y, z = 16 11
In program x, z = 4 11
________________________________________________________________________________
101
Structuri de date i algoritmi
_______________________________________________________________________________

Se poate observa c valorile variabilei locale y nu au fost retransmise n programul
principal, parametrul actual x nemodificndu-i valorile prin execuia procedurii S1.

1.3.3.13.1.2. Parametrii de tip referin

Parametri de tip referin se folosesc pentru a transmite valori ntre unitatea apelant i
subprogramul apelat, n ambele sensuri. De obicei sunt folosii pentru a nota rezultatele obinute n
subprogram. Parametrul actual a corespunztor unui parametru formal de tip referin f este
obligatoriu o variabil de acelai tip cu parametrul formal f. La apelul unui subprogram parametrul
formal se consider identic cu parametrul actual corespunztor. Practic acest lucru se realizeaz prin
faptul c amndoi au aceeai adres n memorie. Astfel, parametrul actual a devine parametru
global; orice modificare a parametrului formal f este i o modificare a parametrului actual a.
Se recomand ca parametrii actuali corespunztori parametrilor formali variabil s fie
distinci. Unele implementri consider eroare cnd la doi parametri formali corespunde acelai
parametru actual, altele accept o astfel de coresponden. Atenie ns la o asemenea situaie
ntruct fiind identici cu acelai parametru actual, cei doi parametri formali devin identici ntre ei,
ceea ce poate duce la efecte neateptate. De aceea recomandm s se evite o asemenea utilizare,
chiar dac ea este permis.

1.3.3.13.1.3. Parametrii funcie i parametrii procedur

Din definiia sintactic a listei parametrilor formali se observ c un parametru formal poate
fi i o funcie sau o procedur. Parametrul actual trebuie s fie o funcie, respectiv o procedur
similar parametrului formal corespunztor.
Un exemplu de program n care se folosesc parametrii formali i actuali funcii i proceduri
este cel de mai jos, n care se calculeaz radicalii de ordinul doi i trei din constanta mm (n
program egal cu 2) rezolvnd ecuaiile:
x2 - mm = 0, notat g(x) = 0,
respectiv
x3 - mm = 0, notat h(x) = 0.
Pentru rezolvarea unei ecuaii se pot folosi mai multe metode. n program am ales dou:
metoda njumtirii i metoda coardei. ntruct metoda coardei folosete i prima derivat, am
notat prin f1, respectiv g1 derivatele funciilor f i g.
Exemplul 28:
Program lpf; { Program 4.10: P.F. funcii si proceduri}
Const mm = 2;
________________________________________________________________________________
102
Structuri de date i algoritmi
_______________________________________________________________________________
Type
fct = function (x: real): real;
sub1 = procedure (a, b: real; var r:real; f,f1:fct);
Var r: real;
i: integer;

Function g(s: real): real;
Begin
g := s*s - mm;
end;

Function h(s: real): real;
Begin
h:= s*s*s - mm;
end;

Function g1(s: real): real;
Begin
g1 := s + s;
end;

Function h1(s: real): real;
Begin
h1 := 3*s*s;
end;

Procedure coarda(a, b: real; var r: real; f, f1: fct); {Se rezolva ecuatia f(x) = 0 prin metoda
coardei}
Var c, t: real;
Begin
c := a; t := b;
Repeat
c := c - f(c)*(t-c)/(f(t)-f(c));
t := t - f(t)/f1(t);
________________________________________________________________________________
103
Structuri de date i algoritmi
_______________________________________________________________________________
until t - c < 0.00001;
r := (c+t)/2
end;

Procedure juma(a, b: real; var r: real; f, f1: fct); {Se rezolva ecuatia f(x)=0 prin metoda
injumatatirii}
Begin
Repeat
r := (a+b)/2;
If f(a)*f(r) < 0 then
b := r
else
a := r;
until b - a < 0.00001
end;

Procedure Rezec(a, b: real; var r: real; f, f1: fct; met: sub1);
Begin
met(a, b, r, f, f1);
end;

Begin
writeln('injumatatire coarda: ');
writeln('radical din 2');
Rezec(1, 2, r, g, g1, juma);
write('r = ', r:9:5);
Rezec(1, 2, r, g, g1, coarda);
writeln(' ', r:9:5);
writeln('radical din 3');
Rezec(1, 2, r, h, h1, juma);
write('r = ', r:9:5);
Rezec(1, 2, r, h, h1, coarda);
writeln(' ', r:9:5);
end.
________________________________________________________________________________
104
Structuri de date i algoritmi
_______________________________________________________________________________

1.3.3.14. Apel recursiv

n exemplele date se observ c apelul unui subprogram se face dup ce el a fost definit.
Este ns permis ca n interiorul unei proceduri s fie definit o alt procedur. Aceast procedur
poate fi utilizat numai n interiorul procedurii n care a fost declarat i numai dup ce a fost
definit.
Este posibil ca un subprogram s se apeleze pe el nsui, recursiv. Ca exemplu, prezentm
n continuare un program care folosete o funcie care calculeaz recursiv valoarea n! cu ajutorul
formulei n! = n.(n-1)! .
Exemplul 29:
Program ApelRecursiv; { Programul 4.11: n Factorial }
Type nat = 0..maxint;
Var i: nat;
Function Fact(n: nat): nat;
Begin
If n = 0 then
Fact := 1
else
Fact := n * Fact(n-1)
end;

Begin
For i:=3 to 7 do
Writeln(i,'! = ', Fact(i))
end.
S urmrim execuia apelului FACT(n) pentru n = 3. S observm c funcia Fact nu are
nici o variabil local n afar de parametrul formal valoare n. Deci la apelul acestei funcii se vor
rezerva dou locaii de memorie, una pentru n i una pentru valoarea funciei FACT, fiecare apel
nsemnnd o astfel de rezervare.
Deci, dup primul apel, zona de memorie alocat este cea situaia a) de mai jos. Pentru a
efectua atribuirea Fact(1) := 3*Fact(2) se apeleaz Fact(2) i se rezerv din nou dou locaii de
memorie, ajungnd la situaia din situaia b) de mai jos. La execuia acestui apel trebuie efectuat
atribuirea Fact(2) := 2*Fact(1). Deci are loc un al treilea apel, Fact(1), pentru care se rezerv din
nou memorie, ajungndu-se la situaia c) de mai jos. De aceast dat se cere efectuarea atribuirii
Fact(3) := 1*Fact(0) i are loc un al patrulea apel, Fact(0), ajungndu-se la situaia d) de mai jos.
________________________________________________________________________________
105
Structuri de date i algoritmi
_______________________________________________________________________________
Cnd ultimul apel s-a executat, el ntoarce valoarea Fact(4) := 1 i se elibereaz zona de memorie
corespunztoare ajungndu-se la situaia situaia e) de mai jos. ntruct i apelul Fact(1) a fost
executat, se ajunge la situaia f) de mai jos. Se efectueaz i atribuirea Fact(2) := 2*Fact(1) = 2 cu
care se termin execuia apelului Fact(2), ajungndu-se la situaia g) de mai jos. n aceast situaie
se ncheie i execuia primului apel cu valoarea Fact(1) := 6.
3 ?
n Fact1
a) 3 ? 2 ?
n Fact1 n Fact2
b) 3 ? 2 ? 1 ?
n Fact1 n' Fact2 n" Fact3
c) 3 ? 2 ? 1 ? 0 1
n Fact1 n' Fact2 n" Fact3 n"' Fact4
d) 3 ? 2 ? 1 1
n Fact1 n' Fact2 n" Fact3
e) 3 ? 2 2
n Fact1 n Fact2
f) 3 6
n Fact1
g)

S observm att modul de execuie al unui apel recursiv ct i faptul c necesarul de
memorie crete la fiecare apel. Iar n cazul n care zona de date locale ale procedurii este mare,
volumul de memorie utilizat poate crete foarte mult.
Din aceast cauz apelul recursiv nu este indicat. Consumul de memorie i timpul necesar
execuiei sunt mult mai mari dect n cazul unui program nerecursiv corespunztor aceleai
probleme. Totui, folosirea procedurilor recursive are avantajul unei descrieri mai clare i mai
apropiat de limbajul matematic.
n programul urmtor sunt date cteva exemple de funcii recursive cu argumente numere
ntregi pentru determinarea cifrei maxime a unui numr ntreg, sumei cifrelor unui numr ntreg i a
celui mai mare divizor comun a dou numere ntregi.
Exemplul 30:
Program ExempleRecursvitate; {Programul 4.12: Cifre}
Const Nm = 1000;
Var a, b: Integer;
Function Max2(a, b: Integer): Integer; {Determina maximul a doua numere intregi a, b}
________________________________________________________________________________
106
Structuri de date i algoritmi
_______________________________________________________________________________
Begin
If a>b then Max2:= a else Max2:= b
end;

Function CifMax(a: Integer): byte; {Calculeaza cifra maxima}
Begin { a numarului intreg a}
If a < 10 then
CifMax := a
else
CifMax := Max2(CifMax(a div 10), a mod 10)
end;

Function SumCif(a: Integer): Integer; {Calculeaz }
Begin { suma cifrelor numarului a}
If a < 10 then
SumCif := a
else
SumCif := SumCif(a div 10) + a mod 10
end;

Function Cmmdc(a, b: Integer): Integer; {Cel mai mare }
Begin { divizor comun al numerelor a, b}
If b = 0 then Cmmdc := a
else
Cmmdc := Cmmdc(b, a mod b)
end;

Begin
Randomize; a := Random(Nm); b := Random(Nm);
Writeln ('Cifra maxima a nr. ', a, ' este ', CifMax(a));
Writeln ('Suma cifrelor nr. ', a, ' este ', SumCif(a));
Writeln ('C.m.m.d.c.(', a, ',', b, ') = ', Cmmdc(a,b));
end.
________________________________________________________________________________
107
Structuri de date i algoritmi
_______________________________________________________________________________
Urmtorul program Pascal utilizeaz cteva funcii i proceduri recursive corespunztoare
unor operaii elementare asupra irurilor de numere (generarea i tiparirea elementelor unui ir,
valoarea i pozitia elementului maxim respectiv minim dintr-un ir, suma elementelor unui ir,
cutarea unei valori ntr-un ir i precizarea dac un ir este sau nu ordonat crector respectiv
descresctor).
Exemplul 31:
Program ExRecSir; {Programul 4.13: Exemple de }
{ funcii i proceduri recursive}
Const Dm = 30;
Type Telem = Integer; {Poate fi orice alt tip}
{Orice schimbare nseamn doar o redefinire}
Sir = Array [1..Dm] of Telem;
Var A:Sir; n:byte; x:Telem;

Procedure Genereaza(Var A:Sir; n:byte); {Genereaz irul A cu n valori aleatoare }
Begin
If n > 0 then
Begin
a[n] := Random(100); { D valoare ultimului element}
Genereaza(A, n-1) { apoi primelor n-1 elemente}
end
end {Genereaza};

Procedure Tipareste (A:Sir; n:byte); { Tiprete din }
Begin { sirul A primele n elemente}
If n > 0 then
Begin
Tipareste (A, n-1); { Tiprete primele n-1 elemente }
Write (a[n], ',') { apoi elementul n }
end
else
Writeln
end;

________________________________________________________________________________
108
Structuri de date i algoritmi
_______________________________________________________________________________
Procedure TipInvers (A:Sir; n:byte); {Tiprete n ordine inversa}
Begin {primele n elemente ale irului A}
If n > 0 then
Begin
Write (a[n], ','); {Tiprete elementul n,}
TipInvers(A, n-1) {apoi n ordine invers primele}
end {n-1 elemente}
end;

Function Max2l(a, b: Telem): Telem; {Max2(a,b) = cel mai mare dintre a si b }
Begin
If a > b then Max2 := a else Max2 := b
end;

Function Maxim(A:Sir; n:byte): Telem; {Elementul maxim }
Begin {din sirul A cu n elemente este egal cu elementul
maxim din primele n elemente}
If n=1 then
Maxim := a[1]
else
Maxim := Max2(a[n], Maxim(A,n-1)) {Maximul dintre primele n
este cel mai mare dintre}
end; {ultimul element i maximul dintre primele n-1 elemente}

Function Min2(a,b: Telem): Telem; {Min2(a, b) = cel mai mic dintre a i b}
Begin
If a<b then Min2:= a else Min2:= b
end;

Function Minim(A: Sir; n: byte): Telem; {Elementul minim }
Begin { din sirul A cu n elemente}
If n = 1
then Minim := a[1]
else
________________________________________________________________________________
109
Structuri de date i algoritmi
_______________________________________________________________________________
Minim := Min2(a[n], Minim(A,n-1))
end;

Function PozMax(A: Sir; n: byte): Telem; {Poziia elementului maxim din irul A de n
elemente}
Function PozMax2(i, j: byte): byte; {Poziia elementului }
Begin { mai mare dintre Ai si Aj}
If a[i] > a[j]
then
PozMax2 := i
else
PozMax2 := j
end;
Begin {Pozitia maximului din primele n elemente}
If n = 1 {este pozitia celui mai mare}
then PozMax := 1 {dintre ultimul si elementul}
else
PozMax:= PozMax2(n, PozMax(A, n-1)) {maxim}
end; din primele n-1}

Function PozMin(A: Sir; n: byte): Tel; {Poziia elementului minim din irul A cu n
elemente}
Function PozMin2(i, j: byte): byte;
Begin
If a[i] < a[j] then PozMin2 := i else PozMin2 := j
end;
Begin {PozMin}
If n = 1 then PozMin := 1
else PozMin := PozMin2(n, PozMin(A, n-1))
end;

Function Exista(A: Sir; n: byte; x: Telem): Boolean;
Begin {x apartine A?: x=A[n] sau x exist n primele n-1}
Exista := (n > 0) and ((x = a[n]) or Exista(A, n-1, x))
________________________________________________________________________________
110
Structuri de date i algoritmi
_______________________________________________________________________________
end;

Function Cresc(A: Sir; n: byte): Boolean; {Este irul A ordonat cresctor ?}
Begin {Primele n-1 sunt ordonate crescator i A[n-1]<A[n]}
If n=1 then Cresc:= True
else
Cresc:= Cresc(A, n-1) and (a[n-1] <= a[n])
end;

Function Descr(A: Sir; n: byte): Boolean; {Este sirul A ordonat descresctor ?}
Begin
If n=1 then Descr:= True
else
Descr:= Descr(A, n-1) and (a[n-1] >= a[n])
end;

Function Suma(A: Sir; n: byte): Telem; {Suma elementelor irului A. Suma primelor n }
Begin { elemente = suma primelor n-1 el.+ A[n]}
If n = 0 then Suma := 0
else
Suma := Suma(A, n-1) + a[n]
end;
Begin
Randomize;
n := Random(20) + 10; Genereaza(A, n);
Tipareste(A, n); Writeln;
TipInvers(A, n);
Writeln('Maximul = ', Maxim(A, n));
Writeln ('Minimul = ', Minim(A, n));
Writeln ('Poz_Max = ', PozMax(A, n));
Writeln ('Poz_Min = ',PozMin(A,n));
Randomize; x := Random(100);
If Exista(A, n, x)
then Writeln('In sir exista el. ', x)
________________________________________________________________________________
111
Structuri de date i algoritmi
_______________________________________________________________________________
else Writeln('In sir nu exista el. ', x);
If Cresc(A, n)
then Writeln('Sirul este ordonat crescator.')
else Writeln('Sirul nu este ordonat crescator.');
If Descr(A, n)
then Writeln('Sirul este ordonat descrescator.')
else Writeln('Sirul nu este ordonat descresc.');
Writeln('Suma elementelor sirului = ',Suma(A,3));
Readln
end.

Este posibil ca dou proceduri s se apeleze una pe cealalt. ns s-a afirmat mai sus c o
procedur nu poate fi apelat nainte de a fi definit. Ori procedurile P1 i P2 se apeleaz reciproc:
P1 apeleaz pe P2 i P2 apeleaz pe P1. n acest caz se permite ca nainte de a apela pe P2, care nc
nu a fost declarat naintea apelului, s se specifice c ea va fi definit ulterior. Pentru aceasta este
nevoie s se foloseasc directiva FORWARD. Cu ajutorul acestei directive se precizeaz antetul
procedurii P2 naintea procedurii P1, iar definiia procedurii P2 va fi fcut dup procedura P1,
conform schemei de mai jos.
Procedure P2(<lista p.f.2>); Forward;
Procedure P1(<lista p.f.1>);
textul procedurii P1 n care apare apelul
P2(<lista p.a.2>)
end; {Sfrsitul procedurii P1}
Procedure P2;
textul procedurii P2 n care apare apelul
P1(<lista p.a.1>)
end;
Aici, n textul procedurii P2 se folosesc parametri formali ai procedurii P2 declarai n
<lista p.f.2>, list care nu mai este prezent n antetul procedurii P2, declarat dup procedura P1.
Dm n continuare un exemplu de program n care subprogramele care se apeleaz reciproc
calculeaz valorile funciilor f i g definite prin
f(0) = 1; g(0) = 1 ;
g(x) = x*x*f(x-1) , pentru x >= 1;
f(x) = (2*x-1)*g(x), pentru x >= 1.
Programul tabeleaz valorile acestor funcii pentru x = 1, 2, ..., 6.
Exemplul 32:
________________________________________________________________________________
112
Structuri de date i algoritmi
_______________________________________________________________________________
Program ApelRec2; { Programul 4.14: Proceduri recursive }
Type nat = 0..maxint;
Var n: nat;
Function G(x: nat): nat; Forward ;
Function F(x: nat): nat ;
Begin
If x = 0 then F := 1
else
F := (x+x-1)*G(x)
end;
Function G;
Begin
If x = 0 then G := 1
else
G := x*x*F(x-1)
end;
Begin
For n:=1 to 6 do
Writeln('F(', n, ')=', F(n), ' G(', n, ')=', G(n))
end.


1.3.3.15. Tipuri de date structurate

Am vzut c prin termenul de dat nelegem o valoare a unei informaii folosit ntr-un
algoritm, cum ar fi numrul 1394, sau caracterul 'A', sau (1, 'Martie', 1996). O dat atomic este o
dat pe care o putem considera, cel puin pentru un moment, o entitate nedecompozabil. De
exemplu, numrul 1394 poate fi considerat o dat atomic memorat, scris pe aceast hrtie. Dar,
putem vedea acest ntreg i ca o dat compus, ca o secven de cifre scrise aici de la stnga spre
dreapta; n acest caz fiecare cifr este considerat atomic, ns ntregul va fi o dat compus. O
cifr la rndul ei ar putea fi considerat compus, de exemplu, din puncte. Astfel putem alege orice
nivel la care s oprim descompunerea unei date, considernd-o apoi atomic.
Dac descompunem o dat, ca i mai sus ntregul 1394, atunci valorile obinute le vom
numi elemente componente, sau simplu elemente. O dat care se compune din mai multe elemente
o numim dat structurat. O dat structurat are elemente componente i o structur, care definete
modul de aranjare sau relaiile ce se pot stabili ntre elemente.
________________________________________________________________________________
113
Structuri de date i algoritmi
_______________________________________________________________________________
n ncercarea de a grupa datele dup caracteristici comune a fost introdus noiunea de tip.
Printr-un tip de date nelegem o mulime de valori (de date) i o mulime de operaii ntre aceste
valori. Dac valorile din mulime sunt atomice atunci avem un tip de date atomic, iar dac valorile
sunt structurate atunci avem un tip de date structurat, sau o structur de date. Deci o structur de
date este un tip de date ale crui valori:
(1) pot fi descompuse ntr-o mulime de elemente de date, fiecare element putnd fi atomic
sau o alt structur de date;
(2) includ o mulime de asocieri, sau relaii (structura) ntre elementele componente.
Operaiile unui tip de date structurat pot s acioneze nu numai asupra valorilor tipului de
date ci i asupra elementelor componente ale structurii de date.
Alegerea unei reprezentri potrivite pentru obiectele de date pe care le folosim ntr-un
program este de importan major. Dar s definim nti ce nelegem prin reprezentarea datelor.
Termenul reprezentarea datelor nseamn o alegere particular, din mai multe care sunt posibile, a
componentelor, a tipului lor, i a organizrii acestor valori memorate ntr-un obiect.
n acest capitol sunt prezentate cteva alternative disponibile n limbajul Pascal pentru
reprezentarea datelor structurate.

1.3.3.15.1. Structura de tablou

Una din structurile de date eseniale n programare sunt cele de tip tablou. Cel mai simplu
mod de a folosi tablourile este de a reprezenta date organizate ca i un ir elemente. La fel, cu
ajutorul lor se pot reprezenta diferite tipuri de tabele. De exemplu, un tabel al notelor obinute la un
examen de studenii dintr-o grup, ar putea arta astfel
Student Nota
1 9
2 7
3 10
..........................
25 8

Un astfel de tabel ar putea fi reprezentat ntr-un program printr-un tablou.
Un tablou const dintr-un ir elemente, fiecare element fiind identificat printr-un indice.
Elementele sunt toate de acelai tip de date, care poate fi orice tip. Indicii sunt dintr-un subdomeniu
al unui tip ordinal. Caracteristicile eseniale ale unui tablou sunt dou: elementele sunt ordonate prin
irul valorilor indicilor, respectiv elementele sunt de acelai tip.
Pentru a defini reprezentarea unui tablou trebuie s precizm dou lucruri: subdomeniul
indicilor i tipul de date al elementelor componente. Sintaxa specificrii n Pascal a unei structuri de
tablou este
________________________________________________________________________________
114
Structuri de date i algoritmi
_______________________________________________________________________________
<tablou> ::= array [<tip1>] of <tip2>
unde parantezele drepte i tipurile <tip1> i <tip2> sunt obligatorii. Tipul <tip1> se
numete tip de indexare i precizeaz valorile pe care le poate lua indicele tabloului. El poate fi
orice tip ordinal diferit de Integer, putnd ns fi un subdomeniu al tipului Integer. Tipul
elementelor tabloului este <tip2>, care poate fi orice tip definit anterior: predefinit sau definit de
ctre utilizator, sau orice tip anonim.
Astfel, prin array[1..25] of integer
se specific un tip de tablou cu componente ntregi, ale crui elemente sunt indexate prin numere
ntregi de la 1 la 25.
Prin array['A'..'Z'] of real
se specific o structur de tablou cu componente reale ale crui elemente sunt indexate prin
caractere aflate n subdomeniul 'A'..'Z' . Dac tabloul Tab are acest tip atunci elementele sale sunt
Tab[c] pentru c n subdomeniul 'A'..'Z'.
Un element al tabloului se refer prin scrierea numelui tabloului urmat de rangul
elementului n acest tablou (indicele) scris ntre parantezele drepte [ i ]. Un element selectat al
tabloului poate fi folosit ca i orice variabil de tipul elementelor tabloului.
Singura operaie predefinit asupra tablourilor este atribuirea, A := B, care are ca efect
copierea valorilor elementelor tabloului B n elementele corespunztoare tabloului A. Cele dou
tablouri trebuie s fie de acelai tip.
Un tablou este reprezentat n memoria calculatorului ca i un ir de locaii de memorare,
fiecrui element corespunzndu-i o locaie. Tabloul Pascal este o abstractizare care ascunde detaliile
despre cum este organizat un tablou n memoria calculatorului. n figura urmtoare este sugerat
reprezentarea unui tablou n memorie, fiecrei locaii de memorare corespunzndu-i un dreptunghi,
valoarea unui element fiind nscris n dreptunghiul corespunztor. S notm c indicii nu sunt
memorai ca i parte a tabloului.
Nota[1] Nota[2] Nota[3] ... Nota[25]
9 7 10 ... 8
Elementele unui tablou pot fi la rndul lor tablouri. Astfel, elementele unui tablou de tipul
array[1..10] of array[1..6] of real
sunt vectori cu 6 componente reale. Dac T este un tablou de acest tip atunci T are 10 componente,
fiecare component fiind un vector cu 6 componente. De fapt este vorba de o matrice cu 10 linii i 6
coloane. Componenta T[i] a acestui tablou va fi un vector cu 6 componente numere reale.
Selectarea elementului cu indicele j al tabloului T[i] poate fi fcut prin T[i][j].
Menionm c se accept o prescurtare a declaraiei de mai sus sub forma
array[1..10, 1..6] of real
Dei nu este o declaraie echivalent cu cea de mai nainte ea permite totui declararea unei
matrice cu 10 linii i 6 coloane. Diferena const n faptul c folosind aceast declaraie o linie a
matricei nu mai este considerat ca o entitate de sine stttoare. Referirea la linia i prin T[i] este
greit n acest caz, iar prin T[i, j] se refer elementul din linia i coloana j.
________________________________________________________________________________
115
Structuri de date i algoritmi
_______________________________________________________________________________
n continuare vom scrie un program n care se folosete un subprogram pentru ordonarea
cresctoare a unui ir de numere reale, pe care-l vom apela pentru a ordona mai nti un ir dat de
numere reale x[1], x[2], ..., x[n], iar apoi pentru a ordona ptratele acestor numere. Subalgoritmul
de ordonare a acestor numere este dat n capitolul apte, seciunea 7.1.
Exemplul 33:

Program Tablou1; {Programul 4.14: Tablouri}
type Vector = array[1..100] of real;
var i, n: Integer;
x : Vector;

procedure Tipar(n:integer; x:vector); {Tipareste, vectorul X cu n elemente}
begin
writeln;
for i:=1 to n do Write(x[i])
end; {Tipar}
procedure Ordonare(n: Integer; var X: Vector); {Ordoneaz nedescrescator primele }
{ n componente ale vectorului X}
var i, kod: Integer;
t: Real;
begin
repeat kod := 0;
for i:=1 to n-1 do
if x[i] > x[i+1] then
begin
kod := 1; t := x[i];
x[i] := x[i+1];
x[i+1] := t
end {if}
until kod = 0
end; {Ordonare}
begin
Write('n = '); Readln(n);
for i:=1 to n do
________________________________________________________________________________
116
Structuri de date i algoritmi
_______________________________________________________________________________
Read(x[i]);
Writeln('Sirul ordonat este:');
Ordonare(n, X);
Tipar;
for i:=1 to n do
x[i] := x[i]*x[i];
Writeln('Sirul patratelor dupa ordonare:');
Ordonare(n, X);
Tipar(n,X)
end.
Dm i un exemplu de program n care apar matrice. Programul rezolv urmtoarea
problem:
Exemplul 34:

Se d o matrice patrat A i se cere s se tipreasc matricele A, A
2
, A
3
i A
4
. Pentru
tiprirea unei matrice i pentru nmulirea a dou matrice se folosesc procedurile TipMat, respectiv
ProdMat. Programul Pascal este urmtorul:

Program PuteriMat; {Programul 4.15: Puterile unei matrice}
const n = 5;
type Mat = array[1..n, 1..n] of Real;
var A, B, C: Mat;

Procedure CitMat(n: Byte; var A: Mat); {Citeste matricea A}
var i, j: byte; {patrata de ordinul n}
begin
for i:=1 to n do
for j:=1 to n do
begin
Write('A(', i, ',', j, ')=');
Readln(A[i,j])
end;
end;

________________________________________________________________________________
117
Structuri de date i algoritmi
_______________________________________________________________________________
procedure TipMat(n: Integer; {Tiparete mesajul s si}
A: Mat; s: String); {matricea A de ordinul n}
var i, j: Integer;
begin
writeln; writeln;
writeln(s);
for i:=1 to n do
begin
Writeln;
for j:=1 to n do
Write(A[i,j]:8:1);
end
end; {TipMat}

Procedure ProdMat(n: Byte; A, B: Mat; var C: Mat); {n = ordinul matricelor}
{C := A * B}
var i, j, k: Integer;
s : Real;
begin
for i:=1 to n do
for j:=1 to n do
begin
s:=0;
for k:=1 to n do
s := s+A[i,k]*B[k,j];
C[i,j] := s
end
end; {ProdMat}

begin
Writeln('Se tiparesc puterile unei matrice');
Writeln('Dati matricea !);
CitMat(n, A);
TipMat(n, A, 'Matricea A este: ');
________________________________________________________________________________
118
Structuri de date i algoritmi
_______________________________________________________________________________
ProdMat(n, A, A, B);
TipMat(n, B, 'Matricea A*A este: ');
ProdMat(n, A, B, C);
TipMat(n, C, 'Matricea A*A*A este: ');
ProdMat(n, B, B, C);
TipMat(n, C, 'Matricea A*A*A*A este:');
end.

1.3.3.15.2. Structura de date nregistrare

Multe obiecte din lumea real le descriem de obicei prin enumerarea unor atribute
importante pe care le au. Atributele servesc la descrierea clasei generale de obiecte - tipul
obiectului. Un obiect particular de acel tip este definit prin asocierea unei valori particulare fiecrui
atribut. De exemplu, o noti dintr-o agend telefonic personal poate referi o persoan prin
atributele Nume, Telefon i Adres, iar o persoan notat n agend ar putea fi:
Ioana Pop; 174563; G. Enescu, 25/A.
n programare putem descrie date compuse (deci i tipul de date corespunztor) ntr-un
mod asemntor. Precizarea (definirea) tipului de date se va face prin enumerarea numelor unor
atribute i precizarea unui tip de date asociat fiecrui atribut. Un obiect particular de acest tip nou va
conine o valoare particular pentru fiecare atribut specificat. Un astfel de tip de date l vom numi
tip de date nregistrare. Fiecare atribut l numim cmp al nregistrrii. Un obiect de date de tip
nregistrare va fi numit o nregistrare.
Observm c structura de date nregistrare modeleaz produsul cartezian din matematic. O
nregistrare const dintr-un numr fix de elemente componente de diferite tipuri. Caracteristica
esenial a unei nregistrri este c ea grupeaz elemente de dat de diferite tipuri ntr-o singur
entitate. Acest aspect contribuie la o exprimare concis i uor de urmrit n programare.
Sintaxa specificrii unui tip nregistrare n limbajul Pascal este:
record <selector> : <tip> { ; <selector> : <tip> } end
unde <selector> este un identificator sau o list de identificatori iar <tip> este un tip
predefinit sau definit anterior i specific tipul selectorului din stnga sa. Selectorii care apar dup
cuvntul record trebuie s fie distinci ntre ei i constituie numele dat componentelor
corespunztoare ale produsului cartezian.
Un astfel de tip nregistrare poate primi un nume folosind declaraia type, prezentat n
seciunea 4.2.5.2. De exemplu, prin
type Data = record
zi : 1..31;
luna: 1..12;
an : 1900..1999
________________________________________________________________________________
119
Structuri de date i algoritmi
_______________________________________________________________________________
end;
se definete un tip nregistrare cu numele Data i care are trei componente: zi, luna, an. Se observ
c este un tip ce conine toate datele din secolul nostru, sub forma unor triplete (z,l,a).
Operaiile asupra nregistrrilor sunt atribuirea nregistrrilor i selectarea unui cmp al unei
nregistrri. Dac A i B sunt dou nregistrri de acelai tip, atunci atribuirea A := B, va avea ca
efect copierea valorilor cmpurilor nregistrrii B n cmpurile nregistrrii A. Pentru selectarea
unui cmp particular al unei nregistrri vom folosi notaia
<variabila-nregistrare> . <selector>
Astfel, pentru variabila V de tipul Data vom avea urmtoarele trei componente (variabile
selectate):
V.zi, V.luna, V.an.
Vom scrie o procedur care rezolv problema de mai jos i care folosete tipul Data, definit
mai sus. Problema este urmtoarea:
Exemplul 35:
S se determine vrsta unei persoane n numr de zile dac se cunoate data naterii
persoanei i data curent. Subalgoritmul pentru determinarea vrstei, dat sub form de funcie, este
urmtorul:
Pseudocod:
Funcia VARSTA(Dnas, Dazi) este:
Fie nr := NRZIAN(Dazi);
@Pentru (fiecare an ntreg din via) adun la nr
numrul zilelor anului respectiv.
Fie VARSTA := nr - NRZIAN(Dnas);
sf-VARSTA
Acest subalgoritm folosete funcia NRZIAN(zi) pentru a determina a cta zi din an este o
dat curent. Funcia menionat este descris n continuare.
Funcia NRZIAN(zian) este:
Fie nr := ziua curent a lunii;
Dac (nu suntem n ianuarie) atunci
Pentru fiecare lun ntreag execut
Fie nr := nr + numrul zilelor lunii i;
sfpentru
Dac (a trecut februarie) atunci
Dac anuI este bisect atunci
nr:=nr+1
________________________________________________________________________________
120
Structuri de date i algoritmi
_______________________________________________________________________________
sfdac
sfdac
sfdac
Fie NRZIAN:=nr;
sf-NRZIAN
Procedura Pascal corespunztoare se definete n programul urmtor:
Program ApelFunctie; { Programul 4.16: Tipul inregistrare}
const NZile: array[1..12] of Integer = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
type Data = record
zi : 1..31;
luna: 1..12;
an : 1900..1999
end;
var Dnas, { Data nasterii }
Dazi: Data; { Data curenta }

function Bisect(a: Integer): Boolean; { Adevarata daca }
begin { a e bisect }
if a mod 4 = 0 then
Bisect := True
else
Bisect := False
end;

Procedure CitData(var D: Data); { Citete un triplet }
begin { zi, lun, an care }
Write('ziua='); Readln(D.zi); { reprezint o dat }
Write('luna='); Readln(D.luna);
Write('anul='); Readln(D.an);
end;

Function NrZiAn(V: Data): Integer; { NRZIAN := a cata zi }
var i, nr: Integer; { in an este data V }
begin
________________________________________________________________________________
121
Structuri de date i algoritmi
_______________________________________________________________________________
nr := V.zi;
if V.luna > 1 then
for i:=1 to V.Luna-1 do
nr := nr + NZile[i];
if V.luna > 2 then
if Bisect(V.an) then
nr := nr + 1;
NrZiAn := nr
end; {NRZIAN}

Function Varsta(Dnas, Dazi: Data): Integer; { Varsta := }
var i, nr: Integer; {numarul de zile aflate}
begin {intre datele Dnas si Dazi}
nr := NrZiAn(Dazi);
for i := Dnas.an to Dazi.an-1 do
begin
nr:=nr+365;
if Bisect(i) then
nr:=nr+1
end; {for}
Varsta := nr - NrZiAn(Dnas);
End; {Varsta}
Begin {Programul principal}
Writeln('Dati data nasterii: '); CitData(Dnas);
Writeln('Dati data curenta: '); CitData(Dazi);
Writeln('Persoana nascuta in: ');
Writeln('(', Dnas.zi, ',', Dnas.luna, ',', Dnas.an, ')');
Writeln('are varsta ', VARSTA(Dnas,Dazi), ' zile.');
End.

n definirea unui tip nregistrare o component poate fi la rndul ei de tipul nregistrare. Un
astfel de exemplu se d n continuare:
type Student = record
________________________________________________________________________________
122
Structuri de date i algoritmi
_______________________________________________________________________________
nume, prenume: array[1..8] of char ;
datan: record
zi : 1..31 ;
luna: 1..12 ;
an : 1900..1989
end;
note: array[1..12] of 1..10
end;

n acest caz, dac X are tipul Student atunci prin X.datan se noteaz tripletul
X.datan.zi X.datan.luna X.datan.an
care reprezint data naterii studentului X, iar X.nume este numele acestui student.
xxxxxxx Tipul referin
n multe aplicaii practice care folosesc prelucrri de date, nu este posibil s cunoatem a
priori dimensionalitatea datelor. Din aceast cauz, utilizarea unui tablou pentru a stoca aceste date
este ineficient, deoarece fie facem risip de memorie printr-o alocare static acoperitoare, fie sub
dimensionm tabloul pentru stocarea datelor, ceea ce poate duce la fenomene de depire a zonei de
memorie alocat datelor, acest fenomen fiind un fenomen sever care poate duce la blocarea
execuiei programului i chiar la blocarea sistemului de calcul. Limbajul de programare Turbo
Pascal stabilete dimensiunea de memorie alocat datelor de la nivelul codului surs, care, compilat
i link-editat se transform n cod executabil. Pe parcursul execuiei nu se pot modifica dinamic
alocrile de date declarate la nivelul codului surs.
De aceea, pentru a rezolva problema unei alocri dinamice a memoriei trebuie s utilizm un
tip de dat special, numit tip referin sau pointer i o serie de proceduri speciale care s aloce
memorie sau s elibereze zona de memorie folosit i care nu mai este necesar.
Tipul de date referin (pointer) va conine adresa unui anumit tip de dat. Declaraia de tip
este:
nume_dat = ^tip;
unde nume_dat este numele noului tip de dat referin, iar tip reprezint tipul datelor referite de
ctre datele de tip nume_dat.
Declaraia de mai sus este o declaraie generic de tip, neavnd ca efect rezervarea propriu-
zis de memorie. Pentru a realiza efectiv alocarea unei zone de memorie de dimensiunea dat de
tipul de dat tip, va trebui s folosim procedura NEW. Apelul procedurii se face astfel:
NEW(variabil _referin);
Unde variabil_referin este o variabil numit variabil dinamic (Cristea, et al. [1992]).
Procedura NEW realizeaz alocarea dinamic a memoriei heap pe parcursul execuiei programului.
________________________________________________________________________________
123
Structuri de date i algoritmi
_______________________________________________________________________________
n urma apelrii procedurii NEW, variabilei dinamice variabil_referin i se va atribui o adres de
memorie de dimensiune egal cu zona de memorie ocupat da o dat de tipul referit.
Asupra variabilelor dinamice pot fi efectuate orice operaii permise de tipul acestora.
Variabilele dinamice pot primi valori i prin operaii de atribuire, pot apare n expresii relaionale
care utilizeaz operatorii relaionali = i <>.
Limbajul Turbo Pascal permite utilizarea tipului pre-definit pointer. Acest tip de dat este
compatibil cu orice tip referin definit de utilizator. Unei variabile de tip pointer i poate fi atribuit
valoarea adresei oricrei variabile, proceduri sau funcii definite de utilizator. O astfel de adres
poate fi obinut prin utilizarea operatorului @, astfel:
@variabil;
Dac o variabil de referin are valoarea NIL nseamn c variabila respectiv conine o
adres imposibil, care nu exist n zona de memorie.
Eliberarea efectiv a spaiului de memorie ocupat se face cu ajutorul procedurii DISPOSE,
dup urmtoarea regul:
DISPOSE(variabil _referin);
Unde adresa zonei de memorie ce se va elibera este coninut n variabil_referin. Dimensiunea
zonei de memorie eliberat este dat de dimensiunea tipului de dat referit de variabil_referin.
Dac dorim s alocm sau s eliberm n mod explicit un anumit numr de octei putem
folosi procedurile GetMeM i FreeMem.

1.3.3.16. Probleme propuse

1. Se d un ir de numere naturale al crui sfrit este marcat prin valoarea 0. Spunem c
dou numere naturale sunt asemenea dac scrierile lor n baza 10 se face cu aceleai cifre (Ex.
36668 i 8363). S se gseasc secvena de numere consecutive asemenea de lungime maxim din
irul dat i frecvenele cifrelor n scrierea numerelor date.
2. Se citesc mai multe iruri de numere naturale nenule fiecare ir terminndu-se la citirea
valorii zero. Pentru fiecare ir s se tipreasc secvena de elemente consecutive de lungime
maxim format din numere prime. La sfrit se vor tipri i toate numerele prime ntlnite. Citirea
se va ncheia cnd irul citit are 0 termeni (altfel spus la citirea a doi de zero consecutivi)
3. S se scrie un program pentru determinarea reuniunii unor mulimi de numere ntregi
pozitive. O mulime se d ntotdeauna ncepnd pe un rnd nou, iar sfritul elementelor sale este
marcat prin numrul 0. Mulimile se termin la ntlnirea mulimii vide. Se va tipri reuniunea
acestor mulimi i mulimea cu cele mai multe elemente, tiprirea elementelor unei mulimi se va
face n ordinea cresctoare a valorilor elementelor.
4. Fiind date mai multe polinoame cu coeficieni reali s se determine suma lor i
polinomul de grad maxim. Un polinom se d fie prin monoamele sale, fie prin grad i coeficieni.
________________________________________________________________________________
124
Structuri de date i algoritmi
_______________________________________________________________________________
Citirea polinoamelor se va ncheia la introducerea gradului negativ.
5. Participanii la un concurs sunt identificai printr-un numr strict pozitiv (numr
legitimaie), i obin un punctaj (numr ntreg). S se scrie un program Pascal care citete rezultatele
obinute la acest examen i tiprete toi candidaii ordonai cresctor dup numrul legitimaiilor,
cu punctajul corespunztor i primii m (m > 0) candidai n ordinea descresctoare a punctajelor
(dac doi dintre acetia au punctaje egale atunci ei se difereniaz n ordine cresctoare dup
numrul legitimaiei).
6. S se scrie un program care citete cte un polinom cu coeficieni ntregi (introdus fie
prin grad i coeficieni fie prin monoamele sale), pn la ntlnirea unui polinom de grad 0. Pentru
fiecare polinom P citit, determin rdcinile naturale ale lui P i le tiprete sub forma:
Rdcinile naturale ale polinomului P cu coeficienii
. . .
sunt ...
7. Se dau un polinom P (grad + irul coeficienilor), i un ir de triplete (a, b, e) pentru care
P(a)*P(b) <= 0 si e>0, irul terminndu-se cu un triplet n care e<0. S se gseasc rdcina ecuaiei
P(x)=0 din intervalul [a,b], prin metoda njumtirii, cu eroarea e, i s se tipreasc:
"n intervalul [a,b] polinomul are rdcina ..., aproximat cu precizia ...(valoarea lui e)".
pentru fiecare triplet, iar la sfrit s se tipreasc toate rdcinile pozitive gsite.

8. S se scrie un program care creeaz matricea ptratic de ordinul n (dat), format din
scrierea cifrelor semnificative ale numerelor naturale n ordinea liniilor i tiprete matricele A,
A2, ... , Am.
9. Fiind date dou numere naturale s se scrie un program Pascal pentru a determina cel
mai mic i cel mai mare dintre ele. Un numr poate avea cel mult 100 cifre. Numerele se introduc
de la tastatur prin cifrele lor (reprezentare n baza 10).
10. S se scrie un program Pascal care citete mai multe matrice i tiprete matricea care
are determinantul cel mai mare. Pentru fiecare matrice programul citete ordinul matricei i
elementele n ordinea liniilor. Execuia programului se ncheie cnd se introduce 0 pentru ordinul
unei matrice.
11. S se scrie un program care citete dou numere naturale nenule a i b si tiprete restul
mpririi lui a la b. Numerele pot avea cel mult 50 cifre i sunt reprezentate n baza 10.
12. S se scrie un program care tiprete rdcinile raionale ale unui polinom cu
coeficieni ntregi (dac exist), polinom dat prin grad i coeficienii si.

________________________________________________________________________________
125
Structuri de date i algoritmi
_______________________________________________________________________________
II. Structuri de date
II.1. Lista liniar simplu nlnuit
Multe din informaiile prelucrate de calculator sunt organizate ca liste: elementele unui
vector, irul format de numele din cartea de telefon (lista abonailor), lista candidailor la admitere
ntr-o facultate, lista materialelor necesare dintr-o secie industrial, lista locatarilor unui imobil . De
aceea lista ocup un loc important ntre structurile de date uzuale. n cele ce urmeaz, prezentm
cteva elemente de baz referitoare la liste, modalitile de reprezentare a listelor n calculator i
unele aplicaii semnificative.
________________________________________________________________________________
126
Structuri de date i algoritmi
_______________________________________________________________________________
II.1.1. Definiii
Prin list nelegem un ir (eventual vid) de elemente aparinnd unei mulimi de date (Tomescu
[1997]). Memorarea listelor liniare se poate face n mai multe moduri, n continuare prezentndu-se
unele dintre ele.
Alocarea secvenial (static) const n a memora elementele listei n locaii succesive de
memorie, conform ordinei acestor elemente n list; n acelai timp se memoreaz adresa de baz
(adresa primului element al listei). Un exemplu tipic este cel n care elementele listei sunt memorate
ntr-un vector, adresa de baz fiind adresa primului element al vectorului.
Alocarea nlnuit (dinamic) presupune c fiecare element al listei liniare este nlocuit cu o
celul format din dou pri: o parte conine o informaie specific al elementului i o parte cu
informaia de legtur, care conine adresa celulei corespunztor urmtorului element.
Fig.2.1. Structura unui nod al listei simplu nlnuite.
Ca i la alocarea secvenial mai trebuie memorat o adres de baz; n plus, partea de
legtur a ultimei celule primete o valoare ce nu poate desemna o legtur.
Utilizm forma de alocare dinamic, ceea ce nseamn c n timpul rulrii programului, n
funcie de necesiti, se aloc memorie suplimentar sau se renun la ea. Pentru alocarea dinamic
utilizm tipul de date referin. Se consider secvena de program cu implementarea elementelor,
element oarecare al listei care este format din informaia util (info) i un pointer care se refer la
urmtorul element al listei :
O list liniar simplu nlnuit este o structur de forma:
Fig.2.2. Structura unei liste simplu nlnuite.
unde semnificaia notaiilor folosite este urmtoarea:
adr1, adr2, ..., adrn reprezint adresele din memorie ale celor n nregistrri;
inf1, inf2, ..., infn reprezint informaiile utile din cele n nregistrri
________________________________________________________________________________
info
successor
nod
127
Structuri de date i algoritmi
_______________________________________________________________________________
Implementarea unui element al acestei structuri se face n felul urmtor n limbajul Pascal:
Type
adresa = ^ nod ;
nod=record
info : tip ;
succesor : adresa ;
end;
Var
List : adresa ;
Numele de "simplu nlnuit " provine din faptul c fiecare element al listei conine o
singur adres i anume adresa elementului urmtor din list. Aici avem o excepie pentru ultimul
element, care are cmpul de adres cuvntul cheie NIL ( semnificnd "nici o adresa" ).
II.1.2. Operaii specifice listei
Coninutul listei se poate modifica prin urmtoarele operaii:
a. iniializarea unei liste ca o list vid;
b. inserarea de noi elemente n orice loc din list;
c. cutarea unor elemente n orice poziie din list;
d. tergerea de elemente din orice poziie a listei;
e. modificarea unui element dintr-o poziie dat;

Alte operaii sunt cele de caracterizare. Acestea nu modific structura listelor, ci furnizez
informaii despre ele . Dintre operaiile de caracterizare vom considera n continuare:
determinarea lungimii listei ( numrul de elemente ) ;
localizarea elementului din list care ndeplinete o anumit condiie ;
a. Algoritmul Creare (Iniializare)
Operaia realizeaz iniializarea listei ca o list vid, adic o list fr elemente:
.
Procedura Creare
List = NIL
End;
b. Algoritmul Inserare

b1. Inserare_nceput : inserm un element la nceputul listei;
- alocarea de spaiu elementului nou;
- modificare de legturi ( a i b );
________________________________________________________________________________
128
Structuri de date i algoritmi
_______________________________________________________________________________

Fig.2.3. Operaia de inserare la nceputul unei liste simplu nlnuite.
Procedure Inserare_nceput ( List , info_nou )
Begin
new(adr);
adr^.succesor = List;
List = adr;
adr^.info = info_nou;
end.
b2. Inserare_Sfrit : inserm un element la sfritul listei ;

Fig.2.4. Operaia de inserare la sfritul unei liste simplu nlnuite.
Secvena de operaii necesar :
- gsirea adresei ultimului element ;
- alocarea spaiului elementului nou ;
- a ( ultimul devine penultimul ) ;
- b ( noul element devine ultimul ) ;
- introducerea de informaii ;
Procedure Inserare_Sfrit ( List , info_nou )
Var
ultim : adresa;
Begin
ultim = List;
________________________________________________________________________________
129
Structuri de date i algoritmi
_______________________________________________________________________________
while ultim^.succesor <> NIL do
ultim = ultim^.succesor;
nou (adr);
ultim^. succesor = adr;
adr^.succesor = NIL;
adr^.info = info_nou;
end;
b3. Inserare_Mijloc : inserm un element nou dup un element dat din list, a crui adres este
numit dup;
Fig.2.5. Operaia de inserare n interiorul unei liste simplu nlnuite.
Secvena de operaii necesar:
- alocare de spaiu ;
- succesorul noului element devine elementul listei ( pas a. ) ;
- succesorul elementului ' dup ' devine noul element (pas b. ) ;
- introducem informaia nou ;
Procedura Inserare_Interior ( List , dup , info_nou )
Begin
new(adr);
adr^.succesor = dup^.succesor;
dup^.succesor = adr;
adr^.info = info_nou;
End;
c. Algoritmul cutare
Algoritmul caut n lista simplu nlnuit nodul care conine informaia info_cutat. Dac
ea exist, funcia de cutare va returna adresa nodului ce conine informaia cutat. Dac
informaia nu exist, atunci funcia va returna o adres vid (NIL).
Function Cutare ( List , info_cutat )
Var
________________________________________________________________________________
130
Structuri de date i algoritmi
_______________________________________________________________________________
adr: adresa;
Begin
adr = List;
while adr <> NIL do
if adr^.info = info_cutat
then begin
cutare = adr;
Exit;
end
else
adr = adr^.succesor;
Cutare = NIL;
End.
d. Algoritmul tergere
d1. tergere_nceput : tergerea elementului de la nceputul listei;
Secvena de operaii necesar:
- salvarea adresei de eliberare;
- primul element devine succesorul fostului prim element;
- eliberarea memoriei;
Fig.2.6. Operaia de tergere la nceputul unei liste simplu nlnuite.
Procedure tergere_nceput ( Var List )
Var liber : adresa;
Begin
liber = List;
List = List^.succesor;
DISPOSE ( liber );
End;
d2. tergere_Sfrit: tergerea ultimului element din list;

________________________________________________________________________________
131
Structuri de date i algoritmi
_______________________________________________________________________________
Fig.2.7. Operaia de tergere la sfritul unei liste simplu nlnuite.
Secvena de operaii necesar:
- gsirea adresei penultimului element din list ;
- salvarea adresei elementului de ters ;
- succesorul penultimului element devine NIL;
- eliberarea memoriei ;
Procedure tergerea_Sfrit ( [ Var ] List )
Var penultim, liber : adresa;
Begin
penultim = List;
while penultim^.succesor^.succesor <> NIL do
penultim = penultim^.succesor;
liber = penultim^. succesor;
penultim^.succesor = NIL;
DISPOSE ( liber );
End;
d3. tergere_Mijloc: tergerea unui element dup un element dat din list, a crui adres este
numit dup;


Fig.2.8. Operaia de tergere n interiorul unei liste simplu nlnuite.
Secvena de operaii necesar:
________________________________________________________________________________
132
Structuri de date i algoritmi
_______________________________________________________________________________
- salvarea adresei de eliberat;
- succesorul lui 'dup' devine succesorul succesorului acestuia ( pas a.);
- eliberarea memoriei;
Procedure tergere_Mijloc ( List , dup )
VAR liber : adresa;
Begin
liber = dup^.succesor;
dup^.succesor = dup^.succesor^.succesor;
DISPOSE ( liber );
End;
e. Algoritmul modificare
Algoritmul apeleaz funcia de cutare n lista simplu nlnuit, cutnd nodul care conine
informaia nrcutat. Dac ea exist, se modific informaia existent n acel nod cu informaia
nrmodificat. Dac informaia nu exist, atunci procedura va returna o adres vid (NIL).
Procedure MODIFICARE ( List , nrcutat , nrmodificat )
Begin
adr:= CUTARE ( List , nrcutat );
if adr = NIL then
write ( ' Nu exista informaia cutat !!! ' )
else
begin
write (' Exista informaia cutat !!! ')
adr^.info:=nrmodificat
end;
End;

II.1.3. Probleme propuse
1.) S se creeze o list liniar simplu nlnuit cu trei noduri, s se iniializeze elementele listei.
2.) Definii i iniializai o list simplu nlnuit. Efectuai tergerea temporar a unui element.
Afiai lista modificat, reactivai elementul.
3.) Se consider o list ce conine elemente care au ca informaie util: cod produs, cantitate, pre.
Scriei i apelai funcia care calculeaz total valoare pentru materialele existente n list.
4.) S se scrie procedurile care realizeaz diferite modaliti de tiprire a unei liste simplu nlnuite.
________________________________________________________________________________
133
Structuri de date i algoritmi
_______________________________________________________________________________
5.) S se scrie programul pentru adunarea a dou matrice rare, memorate sub forma de liste liniare
simplu nlnuite.
6.) S se construiasc o list liniar simplu nlnuit i apoi s se scrie funciile de inserare a unui
element n list la nceput de list, la sfritul listei i n interiorul listei.
7.) Scriei funcia care efectueaz copierea unei liste nerecursiv, cu eliminarea elementelor ce au ca
informaie util o valoare mai mic dect un nivel specificat de un parametru.
8.) Modelai i programai servirea " peste rnd " la distribuirea unor produse deficitare, folosind o
structur de date de tip lista liniar simplu nlnuit.
9.) Numrai elementele pozitive, negative i nule ale unei liste ntr-o funcie care dup apelare,
returneaz un pointer la un vector cu trei componente, se stocheaz rezultatele parcurgerii listei.
10.) Scriei programul pascal pentru inserarea unui element ntr-o list simplu nlnuit ale crei
elemente sunt deja sortate cresctor, pe poziia care pstreaz lista ordonat.
11.) S se genereze o list simpl nlnuit care s conin culoarea, marca i numrul de
nmatriculare al unor autoturisme aflate la o coad la benzin. S se mute toate mainile de culoare
alb n fa, iar cele roii n spate. S se elimine din coad mainile cu numr < 1000. S se
determine numrul mainilor cu marca "DACIA".
12.) Fiind dat o matrice rar, s se alctuiasc o list nlnuit n care elementele au forma ( linia,
coloana, valoarea) i valoarea diferit de 0.
S se listeze elementele alate pe diagonala principal (toate).
S se determine elementul minim de pe diagonala principal (toate).
S se elimine elementul de valoare maxim.
13.) S se memoreze o matrice rar sub forma unei liste nlnuite, n care elementele matricei vor
fi reinute n ordinea lor natural (pe linii), indiferent de ordinea introducerii lor. S se tipreasc
aceast matrice n forma normal (toate elementele, inclusiv cele nule).
II.2. Lista dublu nlnuit

II.2.1. Definiii

Observm c odat pornit cutarea ntr-o list, nu ne mai putem ntoarce napoi doar dac o
lum de la nceput. Acest lucru nu este deloc convenabil, n afar de situaia n care nu avem de ce
s ne ntoarcem napoi. Exist operaii precum: inserarea naintea elementului curent din list sau
________________________________________________________________________________
134
Structuri de date i algoritmi
_______________________________________________________________________________
tergerea elementului curent, care presupun referirea la elementul dinaintea elementului curent -
operaie care se realizeaz cu dificultate. Mul mai comode sunt listele de forma prezentat n figura
urmtoare, liste dublu nlnuite cu posibilitatea de navigare dubl (Tomescu, I., [1997]).
Memorarea listelor liniare se poate face n mai multe moduri, n continuare prezentndu-se
unele dintre ele.
Alocarea secvenial (static) const n a memora elementele listei n locaii succesive de
memorie, conform ordinei acestor elemente n list; n acelai timp se memoreaz adresa de baz
(adresa primului element al listei). Un exemplu tipic este cel n care elementele listei sunt memorate
ntr-un vector, adresa de baz fiind adresa primului element al vectorului.
Alocarea nlnuit (dinamic) presupune c fiecare element al listei liniare este nlocuit cu o
celul format din dou pri: o parte conine o informaie specific al elementului i o parte cu
informaia de legtur, care conine adresa celulei corespunztor urmtorului element.
Ca i la alocarea secvenial mai trebuie memorat o adres de baz; n plus, partea de
legtur a ultimei celule primete o valoare ce nu poate desemna o legtur.

O list liniar dublu nlnuit este o structur de forma:


Fig.2.9. Operaia de tergere n interiorul unei liste simplu nlnuite.
Lista dublu nlnuit este un tip special de list, care necesit un spaiu mare de memorie
mai mare, n care ns n afar de informaia util, mai conine i informaia de legtur a fiecrui
element, care cuprinde att adresa elementului precedent n list (predecesor), ct i adresa
elementului urmtor (succesor). Dac elementul succesor sau cel predecesor nu exist, pointerii
respectivi au valoarea NIL.
Elementul care are adresa succesorului NIL se va numi primul element al listei n raport cu
legtura succesor i ultim element n raport cu legtura predecesor. Elementul care are adresa
predecesorului NIL se va numi ultim element al listei n raport cu legtura succesor i primul
element n raport cu legtura predecesor.
Utilizm forma de alocare dinamic, ceea ce nseamn c n timpul rulrii programului, n
funcie de necesiti, se aloc memorie suplimentar sau se renun la ea. Pentru alocarea dinamic
utilizm tipul de date referin. Se consider secvena de program cu implementarea elementelor,
element oarecare al listei care este format din informaia util (info)
i un pointer care se refer la urmtorul element al listei:

Type
________________________________________________________________________________
135
Structuri de date i algoritmi
_______________________________________________________________________________
adresa = ^ nod;
nod=record
info : tip;
succesor : adresa;
predecesor : adresa;
end;
Var
List : adresa;
Observaie 2.1.: din pcate cei doi pointeri din fiecare element al listei dublu nlnuite consum
destul de mult memorie, i de aceea listele simplu nlnuite sunt mai des folosite.
II.2.2. Operaii specifice listei
Structura i coninutul listei se poate modifica prin urmtoarele operaii:
a. iniializarea unei liste ca o list vid;
b. inserarea de noi elemente n orice loc din list;
c. cutarea unor elemente n orice poziie din list;
d. tergerea de elemente din orice poziie a listei;
e. modificarea unui element dintr-o poziie dat ;
Alte operaii sunt cele de caracterizare. Acestea nu modific structura listelor, ci
furnizeaz informaii despre ele. Dintre operaiile de caracterizare vom considera n continuare:
- determinarea lungimii listei ( numrul de elemente );
- localizarea elementului din list care ndeplinete o anumit condiie;
Setul de operaii, considerat n cele ce urmeaz, utilizeaz poziia curent n list, definit ca
poziia elementului accesibil la un moment dat. Operaiile de prelucrare se refer la elementul din
poziia curent. n afara acestora, sunt definite operaii care asigur modificarea poziiei curente.
S analizm fiecare operaie n parte:
a. Algoritmul creare: are loc iniializarea listei ca o list vid, adic o list fr elemente;


Procedura Creare
List = NIL;
End;
b. Algoritmul Inserare
b1. Inserare_nceput: inserm un element la nceputul listei ;
________________________________________________________________________________
136
Structuri de date i algoritmi
_______________________________________________________________________________

Fig.2.10. Operaia de inserare la nceputul unei liste dublu nlnuite.
Secvena de operaii necesar:
- alocarea de spaiu elementului nou ;
- predecesorul elementului nou devine NIL ;
- se face legtura dintre succesorul noului element i List ;
- predecesorul lui List devine noul element ;
- List preia adresa noului element ;
- introducerea informaiei ;

Procedure Inserare_nceput ( Var List , info_nou )
new(adr );
adr^.predecesor = NIL;
adr^.succesor = List ;
List^.predecesor = adr ;
List = adr ;
adr^.info = info_nou ;
End;
b2. Inserare_Sfrit : inserm un element la sfritul listei ;
Fig.2.11. Operaia de inserare la sfritul unei liste dublu nlnuite.
________________________________________________________________________________
137
Structuri de date i algoritmi
_______________________________________________________________________________
Secvena de operaii necesar:
- gsirea adresei ultimului element ;
- alocarea spaiului elementului nou ;
- predecesorul noului element devine ultimul ;
- succesorul ultimului element devine noul element ;
- introducerea de informaii ;
- modificarea adresei ultimului element ;

Procedure Inserare_Sfrit ( Var List , info_nou )
Var
ultim : adresa ;
Begin
ultim = List;
while ultim^.succesor <> NIL do
ultim = ultim^.succesor
nou (adr);
adr^.predecesor = ultim;
ultim^. succesor = adr;
adr^.succesor = NIL;
adr^.info = info_nou;
ultim = adr;
End;
b3. Inserare_Mijloc: inserm un element nou dup un element dat din list, a crui adres este
numit dup;

Fig.2.11. Operaia de inserare n interiorul unei liste dublu nlnuite.
Secvena de operaii necesar:
- alocare de spaiu ;
- predecesorul noului element devine elementul listei ;
- predecesorul succesorului lui 'dup' devine noul element ;
- succesorul elementului nou devine succesorul elementului 'dup';
- introducem informaia nou ;

________________________________________________________________________________
138
Structuri de date i algoritmi
_______________________________________________________________________________
Procedura Inserare_Mijloc ( Var List , dup , info_nou )
new (adr) ;
adr^.predecesor = dup ;
dup^.succesor^.predecesor = adr ;
adr^.succesor = dup^.succesor ;
adr^.info = info_nou ;
End;
c. Algoritmul Cutare:
Algoritmul caut n lista dublu nlnuit nodul care conine informaia info_cutat. Dac ea
exist, funcia de cutare va returna adresa nodului ce conine informaia cutat. Dac informaia
nu exist, atunci funcia va returna o adres vid (NIL). Cutarea se poate face bidirecional, pe
legtura succesor sau pe legtura predecesor.
Function Cutare ( List , info_cutat ): adresa
Var
adr : adresa ;
Begin
adr:=List;
while adr < > NIL do
if adr^.info = nrcautat then
begin
Cutare = adr ;
exit;
end
else
adr = adr^.succesor ;
Cutare = NIL ;
End;
d. Algoritmul tergere
d.1 tergere_nceput : tergerea elementului de la nceputul listei ;
Fig.2.12. Operaia de tergere la nceputul unei liste dublu nlnuite.
________________________________________________________________________________
139
Structuri de date i algoritmi
_______________________________________________________________________________
Secvena de operaii necesar:
- salvarea adresei de eliberare ;
- predecesorul succesorului lui List s devin NIL ;
- List devine succesorul primului element ;
- predecesorul lui List va devine NIL ;
- eliberarea memoriei ;

Procedura tergere_nceput ( Var List )
Var
liber : adresa ;
Begin
if List = NIL then
write(" Lista este vid ")
else
liber = List ;
List = List^.succesor ;
List^.predecesor = NIL ;
DISPOSE ( liber ) ;
End;
d.2 tergere_Sfrit : tergerea ultimului element din list ;

Fig.2.13. Operaia de tergere la sfritul unei liste dublu nlnuite.

Secvena de operaii necesar:
- gsirea adresei ultimului element din list ;
- salvarea adresei elementului de ters ;
- succesorul predecesorului lui ultim devine NIL;
- eliberarea memoriei ;

Procedure tergerea_Sfrit ( Var List )
Var
ultim , liber : adresa ;
________________________________________________________________________________
140
Structuri de date i algoritmi
_______________________________________________________________________________
Begin
ultim = List ;
while ultim^.succesor < > NIL do
ultim = ultim^.succesor ;
liber = ultim ;
ultim^.predecesor^.succesor = NIL ;
DISPOSE( liber ) ;
End;
d.3 tergere_Mijloc : tergerea unui element dup un element dat din list, a crui adres este
numit dup;
;
Fig.2.14. Operaia de tergere la sfritul unei liste dublu nlnuite.
Secvena de operaii necesar:
- salvarea adresei de eliberat ;
- predecesorul succesorului 'dup' devine predecesorul lui 'dup' ;
- succesorul predecesorul 'dup' devine succesorul lui 'dup' ;
- eliberarea memoriei ;
Procedure tergere_Mijloc ( Var List, dup )
Var
liber : adresa ;
Begin
liber = dup ;
dup^.succesor^.predecesor = dup^.succesor ;
dup^.predecesor^.succesor = dup^.succesor ;
DISPOSE ( liber );
End;
e. Modificare (Actualizare) :
Algoritmul apeleaz funcia de cutare n lista dublu nlnuit, cutnd nodul care conine
informaia nrcutat. Dac ea exist, se modific informaia existent n acel nod cu informaia
________________________________________________________________________________
141
Structuri de date i algoritmi
_______________________________________________________________________________
nrmodificat. Dac informaia nu exist, atunci procedura va returna o adres vid (NIL). Cutarea
informaiei de modificat se poate face pe ambele legturi, predecesor i succesor.
Procedure MODIFICARE ( List , nrcutat , nrmodificat )
Begin
adr := CUTARE ( List , nrcutat );
if adr = NIL then
write ( ' Nu exista informaia cutat !!! ' ) ;
else
begin
write (' Exista informaia cutat !!! ') ;
adr^.info := nrmodificat ;
end;
End;
Probleme propuse
1.) S se construiasc o list dublu nlnuit i s se scrie elementele acesteia n ambele sensuri n
funcie de opiune. S se tearg apoi un element al listei i s tipreasc lista rezultat.
2.) S se construiasc o list dublu nlnuit cu 5 elemente citite dintr-un vector. S se scrie funcia
recursiv de tiprire a listei n ambele sensuri. S se scrie funcia de tergere a unui element din
list.
3.) Scriei i apelai funcia care verific dac matricea rar ptratic ale crei elemente sunt stocate
ntr-o list conine numai elemente ale diagonalei principale.
4.) S se construiasc un arbore genealogic (folosind o list nlnuit) utiliznd pentru fiecare
membru introdus legturile de tip : printe, copil (primul), frate, so_soie. S se gseasc, pentru
membru dat, toi verii de grad I (copiii frailor prinilor).
5.) S se creeze o list nlnuit cu articole cu structura : Nume_student, An, Grup, Medie. S se
listeze toi studenii cu media > 9 iar apoi s se elimine din list toi studenii din anul 5.
6.) Fiind dat o matrice ale crei elementele reprezint localiti, s se construiasc o list, n care
pentru fiecare localitate se vor memora legturile cu localitile nvecinate n cele patru direcii (N,
E, S, V). S se parcurg un traseu, plecnd de la o anumit localitate de start, urmnd un ir de
direcii ( Se vor ignora direciile inaccesibile).
7.) O matrice rar poate fi memorat printr-o list dublu nlnuit avnd ca elemente elementele
nenule ale matricei respective. Fiecare linie sau coloan va fi reprezentat printr-o list dublu
nlnuita Se cere un program care s permit memorarea unei astfel de matrice rare i efectuarea
de operaii de citire, adunare, scdere sau nmulire i de asemenea tiprirea unei matrice.
________________________________________________________________________________
142
Structuri de date i algoritmi
_______________________________________________________________________________
8.) S se construiasc o list nlnuit cu componentele de forma : X
i
, Leg_Urm, Leg_Prim, unde
X
i
N i X
i
< X
j
pentru i < j, Leg_Urm este adresa urmtorului element din list, iar Leg_Prim este
adresa ultimului numr prim dinaintea lui X
i
. S se listeze toate numerele X
i
n ordine cresctoare,
apoi doar numerele prime din list n ordine descresctoare.

9.) Se d o list nlnuit. Se cere o procedur care s permit adugarea unui element pe poziia n;
(dac lista conine mai puine de n-1 elemente, adugarea se va efectua n coada listei) i o
procedur care s efectueze tergerea elementului de pe poziia n (dac lista conine mai puin de n
elemente, se va terge ultimul element).
10.) Se citete un ir X
1
, X
2
, ..., X
N
de numere naturale distincte i un numr natural b > 1, n funcie
de care irul dat se poate mpri n b subiruri astfel: X
i
S
k
dac restul mpririi lui X
i
la b este k.
S se construiasc o list de forma: X
i
, Leg_Sir, Leg_Elem, unde Leg_Sir este adresa primului
element din urmtorul subir, iar Leg_Elem este adresa urmtorului element din acelai subir.
Pentru un numr k dat, s se listeze subirul S
k
.
11.) S se depun numerele reale X
1
, X
2
, ..., X
N
ntr-o list, apoi s se ordoneze cresctor aceast
list folosind o procedur care aduce elementul minim pe prima poziie i o procedur care mut
elementul pe ultima poziie.
12.) Se d o mulime de maini caracterizate prin culoare, marc, numr. S se construiasc o list
cu toate mainile avnd acea culoare. S se listeze numerele de nmatriculare ale mainilor care au o
culoare i o marc dat.
13.) Fiind dat o list cu numerele naturale X
1
, X
2
, ..., X
n
, s se elimine elementele care se repet,
apoi dup fiecare element s se adauge divizorii si.
14.) Se dau numerele reale a, X
1
, X
2
, ..., X
n
. S se construiasc o list care s poat fi parcurs n
ambele sensuri, apoi s se elimine din list primul i ultimul element egal cu a.
II.3. Stiva (stack)
II.3.1. Generaliti
O stiv (n englez stack), este o list linear de un tip special, n care adugarea sau
scoaterea unui element se face la un singur capt al listei, numit vrful stivei (Aho et al. [1987]).
Elementul introdus primul n stiv poart numele de baz a stivei. O stiv fr nici un element se
numete stiv vid sau stiv goal. Ca orice list liniar, o stiv poate fi realizat practic
(implementat) fie folosind o reprezentare static (secvenial), fie prin reprezentare dinamic
(nlnuit). Indiferent de reprezentare, implementarea presupune alocarea unui spaiu limitat, dac
el este n ntregime ocupat, spunem c avem stiva este plin.
Stiva se poate asemna unui vraf de farfurii aezat pe o mas, modalitatea cea mai comod
________________________________________________________________________________
143
Structuri de date i algoritmi
_______________________________________________________________________________
de a pune o farfurie fiind n vrful stivei, tot de aici fiind cel mai simplu s se ia o farfurie. Datorit
locului unde se acioneaz asupra stivei, operaiile de inserare i extragere, aceste structuri se mai
numesc de tip LIFO (Last In - First Out), adic ultimul sosit - primul ieit.
II.3.2. Stiva alocare static
n reprezentarea secvenial, elementele stivei vor fi memorate ntr-un vector (tabel) numit
Stiva cu n componente, n fiind capacitatea maxim a stivei. Vom nota cu TOP numrul efectiv de
elemente din stiv, i anume:
TOP = 0 va reprezenta o stiv goal (deci nu vom mai putea extrage elemente din stiv)
TOP >= n - va reprezenta o stiv plin (deci nu vom mai putea insera elemente n stiv)


TOP

Fig.2.15. Reprezentare unei stive secveniale.
Operaiile efectuate asupra stiva sunt:
a. testare capacitate superioar (stiv plin);
b. testare capacitate inferioar (stiv goal);
c. inserare de noi elemente, operaie numit PUSH
d. extragere (tergere) din stiv, operaie numit POP.
a.Testare capacitate superioar (stiv plin);
Function Full_Stack(TOP:INTEGER): boolean
Begin
If TOP = n then
Full_Stack:=TRUE
else
Full_Stack:=FALSE;
End;
a.Testare capacitate inferioar (stiv goal);
________________________________________________________________________________
144
Structuri de date i algoritmi
_______________________________________________________________________________
Function Empty_Stack(TOP:INTEGER): boolean
Begin
If TOP = 0 then
Empty_Stack:=TRUE
else
Empty_Stack:=FALSE;
End;
c.Inserare - PUSH;
Procedure PUSH (VAR TOP:INTEGER, info_nou:tip)
Begin
If NOT FULL_Stack(TOP) then
Begin
Stiva[TOP]:=info_nou;
TOP=TOP+1;
else
writeln(OVERFLOW);
End;
d.Extragere - POP;
Function Pop (VAR TOP:INTEGER):tip
Begin
If NOT Empty_Stack(TOP) then
Begin
TOP=TOP-1;
Pop:=Stiva[TOP];
else
writeln(UNDERFLOW);
End;
II.3.3. Stiva alocare dinamic
n reprezentarea dinamic, stiva va fi implementat cu ajutorul unei liste simplu nlnuite.
Adresa ultimului element din stiv va fi numit TOP, avnd semnificaia de a indica spre elementul
din vrful stivei. Structura va fi manipulat ca i orice list simplu nlnuit prin adresa primului
element, notat LIST, care va semnifica baza stivei.
________________________________________________________________________________
145
Structuri de date i algoritmi
_______________________________________________________________________________
Fig.2.16. Reprezentare unei stive dinamice.
Operaiile efectuate asupra stiva sunt:
a. testare capacitate inferioar (stiv goal);
b. inserare de noi elemente, operaie numit PUSH
c. extragere (tergere) din stiv, operaie numit POP.
Obs. 2.2.: Memoria fiind alocat dinamic nu este necesar testul de capacitate superioar.
a.Testare capacitate inferioar (stiv goal);
Function Empty_Stack(TOP:adresa): boolean
Begin
If TOP = NIL then
Empty_Stack:=TRUE
else
Empty_Stack:=FALSE;
End;
c.Inserare - PUSH;
Procedure PUSH (VAR TOP:adresa, info_nou:tip)
Begin
Inserare_sfrsit(LIST,TOP,info_nou)
End;
d.Extragere - POP;
Function POP (VAR TOP:adresa):tip
Begin
If NOT Empty_Stack(TOP) then
________________________________________________________________________________
LIST
TOP
146
Structuri de date i algoritmi
_______________________________________________________________________________
Begin
tergere_sfrsit(LIST,TOP)
else
writeln(UNDERFLOW);
End;
II.3.4. Probleme propuse
1.) S se realizeze evidena materialelor existente,ntr-o magazie. La intrarea n stoc a materialelor
pe baza de factur, se adaug elemente unei stive. La eliberarea spre consum productiv, se terge
vrful stivei. Procedeul continu dup cum avem intrri sau consumuri de materiale. Se va scrie i
funcia pentru numrarea facturilor.
2.) Se consider o stiv nevid de lungime mai mare ca 5. Scriei funcia pentru dealocarea
memoriei ocupate de aceast stiv .
3.) O echip realizeaz demontarea unei instalaii cu dispunerea reperelor i sub-ansamblelor ntr-
un mod corespunztor reparrii i mai apoi asamblri. O alt echip efectueaz asamblarea. Scriei
programul care afieaz lista operaiilor de asamblare tiind ca aceste operaii sunt specificate prin
numele reperelor sau sub-ansamblelor.
4.) Se consider mulimea literelor mari i mulimea literelor mici. S se construiasc pornind de la
un ir oarecare de litere, dou stive ce conin literele mari, respectiv, literele mici.
S se afieze literele mici i mari n ordinea n care au fost introduse.
5.) Scriei i apelai funcia de tergere a unei stive pn la elementul a crui informaie util
coincide cu un parametru dat.
6.) Dndu-se stivele A i B care conin cod produs, cantitate i, respectiv, cod produs i pre, creai
stiva ale crei elemente conine cod produs, cantitate i pre. La apelarea funciei, elementele sunt
presupuse sortate dup cod.
7.) Descompunei folosind o funcie pe care o apelai, o stiv n dou stive cu numr egal de
elemente, numai dac acest lucru este posibil.
8.) Gsii o formul simpl pentru numrul de permutri de n elemente, ce pot fi obinute cu
ajutorul unei stive.
9.) Artai c permutarea p
1
, p
2
, ..., p
n
se poate obine pornind de la 1, 2, ..., n utiliznd o stiv dac
i numai dac nu exist indici i < j < k astfel nct p
j
< p
k
< p
i
.
________________________________________________________________________________
147
Structuri de date i algoritmi
_______________________________________________________________________________
II.4. Coada (queue)
II.4.1. Generaliti
n prelucrarea unei mulimi de elemente pot s fie utilizate diferite metode de alegere a
urmtorului element supus prelucrrii (Dale i Lilly [1988]). Aceast alegere poate s fie aleatoare
sau s respecte un anumit criteriu. De exemplu, pentru o mulime la care este semnificativ ordinea
n care elementele au fost introduse n mulime se poate considera un criteriu care s se bazeze pe
aceast ordine. Modelul intuitiv al acestei structuri este coada care se formeaz la un magazin,
lumea se aeaz la coad la sfritul ei, cei care se gsesc la nceputul cozii sunt servii, i prsesc
apoi coada.
Coada reprezint o alt categorie special de list liniar, n care toate elementele se
insereaz la un capt (sfrit) i se extrag (terg) la cellalt capt (nceput).
Prelund o terminologie din domeniul sistemelor de operare, coada mai poart numele de
list FIFO (First In - First Out), adic primul intrat n coad va fi primul care va iei din coad.

II.4.2. Coada alocare static
n reprezentarea secvenial, elementele cozii vor fi memorate ntr-un vector (tabel) numit
coada cu n componente, n fiind capacitatea maxim a stivei. Vom nota cu Front indexul
elementului ce urmeaz a fi servit, iar cu Rear indexul primului element liber din coad. Dac:
Front = Rear va reprezenta o coad goal (deci nu vom mai putea extrage elemente din coad)
Rear >= n - va reprezenta o coad plin (deci nu vom mai putea insera elemente n coad)
Front Rear

Fig.2.17. Reprezentare unei cozi secveniale.
Operaiile efectuate asupra cozii sunt:
e. testare capacitate superioar (stiv plin);
f. testare capacitate inferioar (stiv goal);
g. inserare de noi elemente, operaie numit ENQUEUE;
h. extragere (tergere) din stiv, operaie numit DEQUEUE.
________________________________________________________________________________
148
extragere inserare
Structuri de date i algoritmi
_______________________________________________________________________________
a. Testare capacitate superioar (coad plin);
Function Full_Queue(Rear:INTEGER): boolean
Begin
If Rear = n then
Full_Queue:=TRUE
else
Full_ Queue:=FALSE;
End;
b. Testare capacitate inferioar (coad goal);
Function Empty_ Queue (Front, Rear:INTEGER): boolean
Begin
If Front = Rear then
Empty_ Queue:=TRUE
else
Empty_ Queue:=FALSE;
End;
c.Inserare - ENQUEUE;
Procedure ENQUEUE (VAR Rear:INTEGER, info_nou:tip)
Begin
If NOT FULL_Queue(Rear) then
Begin
Coada[Rear]:=info_nou;
Rear=Rear+1;
else
writeln(OVERFLOW);
End;
d.Extragere - DEQUEUE;
Function DEQUEUE(VAR Front:INTEGER):tip
Begin
If NOT Empty_Queue(Front, Rear) then
Begin
Dequeue:=coada[Front];
Front=Front+1;
else
________________________________________________________________________________
149
Structuri de date i algoritmi
_______________________________________________________________________________
writeln(UNDERFLOW);
End;
II.4.3. Coada alocare dinamic
n reprezentarea dinamic, coada va fi implementat cu ajutorul unei liste simplu
nlnuite. Adresa ultimului element din stiv va fi numit Rear, avnd semnificaia de a indica
adresa ultimul element inserat n coad. Adresa primului element din stiv va fi numit Front,
avnd semnificaia de a indica adresa primului element inserat n coad, deci a elementului care
urmeaz a fi extras.
Fig.2.16. Reprezentare unei stive dinamice.
Operaiile efectuate asupra stiva sunt:
a. testare capacitate inferioar (coad goal);
b. inserare de noi elemente n coad, operaie numit ENQUEUE;
c. extragere (tergere) din coad, operaie numit DEQUEUE.
Obs. 2.2.: Memoria fiind alocat dinamic nu este necesar testul de capacitate superioar.
a.Testare capacitate inferioar (coad goal);
Function Empty_Queue(Front:adresa): boolean
Begin
If Front = NIL then
Empty_Stack:=TRUE
else
Empty_Stack:=FALSE;
End;
________________________________________________________________________________
Front
Rear
150
Structuri de date i algoritmi
_______________________________________________________________________________
b.Inserare - ENQUEUE;
Procedure ENQUEUE (VAR Rear:adresa, info_nou:tip)
Begin
Inserare_sfrsit(Front,Rear,info_nou)
End;
c.Extragere - DEQUEUE;
Function DEQUEUE(VAR Front:adresa):tip
Begin
If NOT Empty_Stack(Front) then
Begin
tergere_sfrsit(LIST,TOP)
else
writeln(UNDERFLOW);
End;
II.4.4. Probleme propuse
1.) O coad biterminal cu restricii la intrare este o list linear n care elementele nu pot fi inserate
dect la un capt, dar pot fi terse de la ambele capete; n mod clar o astfel de coad biterminal
poate opera att ca o stiv ct i ca o coad, dac nu tergem elemente dect da la un singur capt.
Se poate ca i o coad biterminal cu restricii la ieire s opereze fie ca o coad ?
2.) Exist permutri ale elementelor 1, 2, ..., n care nu pot fi obinute cu ajutorul unei cozi care nu
este cu restricii nici la intrare, nici la ieire ?
3.) Folosind o structur de tip stiv i coad s se decid dac un cuvnt este palindrom. Un
palindrom este un cuvnt care coincide cu inversul su. Exemple: lupul este palindrom, acesta
nu este palindrom.
4.) Se introduc n numere reale ntr-o stiv i ntr-o coad. Se extrage un numr din stiv i se
introduce n coad. Se extrage un numr din coad i se introduce n stiv. S se tipreasc
coninutul stivei i al cozii dup k pai.
II.5. Arborele binar

Cnd am discutat despre structurile de date nlnuite, liste simplu sau dublu nlnuite, am
vzut avantajele evidente ale stocrii de date ordonate. Folosirea eficient a spaiului de memorare,
________________________________________________________________________________
151
Structuri de date i algoritmi
_______________________________________________________________________________
manipularea ntregii structuri de date doar prin intermediul adresei de nceput, etc. sunt doar cteva
din argumentele folosirii acestor structuri de date dinamice. Dezavantajul evident al structurilor de
date de tip list nlnuit este ns provocat de procedurile de cutare secvenial care au o
performan de ordinul O(n). De aceea, s-a construit o nou structur de date dinamic, de tip
nlnuit, care s pstreze avantajele flexibilitii structurii de date tip list nlnuit i s se bazeze
pe o performan mult mbuntit a algoritmului de cutare, de ordinul O(log
2
n).
II.5.1. Definiii
Un arbore este o mulime de elemente numite noduri, un singur nod avnd rolul de nod
rdcin, mpreun cu o relaie de tip printe-fiu care definete o structur ierarhic pe mulimea
nodurilor. n mod formal, un arbore poate fi definit recursiv astfel (Aho et al. [1987]):
1. Un arbore poate conine un singur nod. Acest nod este i nodul rdcin al arborelui.
2. Fie n un nod i T
1
, T
2
, , T
k
arbori cu nodurile rdcin n
1
, n
2
, , n
k
. Putem construi un nou
arbore, fcnd ca nodul n s devin nodul printe al nodurilor n
1
, n
2
, , n
k.
n acest arbore, n
este nodul rdcin, iar T
1
, T
2
, , T
k
se numesc subarbori. Nodurile n
1
, n
2
, , n
k
se numesc
noduri fiu ale nodului n.
Un arbore binar este o structur arborescent n care fiecare vrf are cel mult doi
descendeni, fcndu-se ns distincie clar ntre descendentul drept i descendentul stng al
fiecrui vrf. Se accept i arborele binar cu 0 vrfuri, numit arbore binar vid.
Arborii binari nu reprezint cazuri particulare de arbori orientai, dect dac se face
abstracie de distincia menionat ntre descendentul drept i cel stng al fiecrui vrf. ntr-adevr
dac un vrf are un singur descendent, aceast informaie este suficient n cazul unui arbore, dar
insuficient n cazul unui arbore binar, cnd trebuie precizat dac acest descendent este descendent
stng sau descendent drept.
ntr-o structur de tip arbore, elementele sunt structurate pe nivele; pe primul nivel, numit
nivel 0, exist un singur nod numit rdcin, de care sunt legate mai multe noduri, numite fii care
formeaz nivelul 1; de acestea sunt legate elementele de pe nivelul 2 .a.m.d.
Fig. 2.x. Exemplu de arbore i organizarea sa pe nivele.
________________________________________________________________________________
152
Structuri de date i algoritmi
_______________________________________________________________________________
Un arbore este compus din elementele numite noduri sau vrfuri i legturile dintre acestea.
Un nod situat pe un anumit nivel este nod tat pentru nodurile legate de el, situate pe nivelul
urmtor, acestea reprezentnd fiii si. Fiecare nod are un singur tat, cu excepia rdcinii care nu
are tat. Nodurile fr fii se numesc noduri terminale sau noduri frunz.
Termenii 'nod tat', 'nod fiu', 'nod bunic', 'nod nepot' sau 'nod frate' sunt preluai de la arborii
genealogici, cu care arborii se aseamn foarte mult.
Arborii, ca structuri dinamice de date, au extrem de multe aplicaii n informatic. Deosebit
de utilizat n aplicaii este structura de tip arbore binar. Un arbore binar este un arbore n care
fiecare nod are cel mult doi fii, fiul stng i fiul drept (fiul stng este legat n stnga tatlui i cel
drept n dreapta). Dac se elimin rdcina i legturile ei, se obin doi arbori binari care se numesc
subarborele stng i subarborele drept ai arborelui iniial.
Arborele binar este, deci, o structur recursiv de date. Un arbore binar nevid fie se reduce
la rdcin, fie cuprinde rdcina i cel mult doi subarbori binari. Un arbore binar se poate
implementa foarte uor cu ajutorul adreselor de nlnuire, fiecare element cuprinznd, n afar de
informaia proriu-zis asociat nodului, adresa fiului stng i adresa fiului drept, acestea exprimnd
legturile existente ntre noduri.

Implementarea arborilor binari
n majoritatea implementrilor i cei doi subarbori sunt adresai indirect; n funcie de
varianta de implementare - dinamic sau static, adresarea se realizeaz fie prin intermediul
pointerilor, fie prin intermediul indicilor de tablou.
Alegem implementarea dinamic cea mai simpl form de reprezentare a nodurilor. Un nod
al unui arbore binar AB are urmtoarea structur:
Fiu_st Inf
o
Fiu_dr
Figura V.14. Structura nodului unui arbore binar.
unde:
fiu_st : reprezint adresa fiului stnga;
Info: informaia atat nodului.;
fiu_dr: reprezint adresa fiului dreapta;
Structura nodului n implementarea Pascal este urmtoarea (Albeanu [1994]):
Type
Adresa = ^Nod
Nod = RECORD
fiu_st : Adresa;
________________________________________________________________________________
153
Structuri de date i algoritmi
_______________________________________________________________________________
Info : tipinfo;
fiu_dr : Adresa;
end
V.3.3. Operaii ntr-un arbore binar AB
Operaiile n cazul arborilor binari sunt:
a. creare-iniializare;
b. inserare-balansare;
c. cutare;
d. tergere;
e. traversarea:
Ne vom ocupa doar de operaia de traversare care nu este dependent de organizarea
particular a arborelui, fiind aceeai pentru toi arborii binari. Construirea unui arbore binar se face
n funcie de relaia definit pe datele coninute n nodurile arborelui binar. n general, se alege o
parte a datei stocat n nodurile arborelui binar, dup care se va ordona noua structur de date
arborescent. Informaia dup care se ordoneaz arborele binar se numete cheie.
Cea mai des utilizat form de organizare a unui arbore binar este urmtoarea:
Cheia nodului fiu stnga < Cheia nodului fiu stnga < Cheia nodului fiu stnga (2.x)
Utiliznd formula de mai sus se obin arbori binari speciali, utilizai pentru organizarea i
cutarea datelor, numii arbori binari de cutare ABC.
e. Traversarea arborelui binar. Const n parcurgerea pe rnd a nodurilor n vederea prelucrrii
informaiilor ataate acestora. Traversarea arborelui presupune vizitarea fiecrui nod o singur dat,
operaie echivalent cu o liniarizare a arborelui. Exist trei modaliti importante de traversare a
unui arbore binar, exprimate prin regulile recursive:
1.) n preordine: se viziteaz rdcina, apoi tot n preordine se viziteaz nodurile subarborelui stng
i apoi acelea ale subarborelui drept.
2.) n inordine: se viziteaz n inordine nodurile subarborelui stng, apoi rdcina i apoi tot n
inordine, nodurile subarborelui drept.
3.) n postordine: se viziteaz n postordine nodurile subarborelui stng, apoi tot n postordine,
nodurile subarborelui drept i, la sfrit, rdcina.
Obs.2.x:
________________________________________________________________________________
154
Structuri de date i algoritmi
_______________________________________________________________________________
1. evident, dac arborele se reduce la un singur nod, vizitarea acestuia n preordine, inordine
sau postordine presupune parcurgerea acestuia, deci prelucrarea informaiilor asociate lui;
2. cele trei modaliti de traversare difer prin, momentul n care se viziteaz rdcina i
anume, n cazul:
preordine: se viziteaz nti rdcina, apoi subarborele stng i dup aceea cel drept
(RSD Rdcin, Stnga, Dreapta);
inordine: se viziteaz subarborele stng, se viziteaz rdcina i subarborele drept
(SRD - Stnga, Rdcin, Dreapta);
postordine: se viziteaz subarborele stng, se viziteaz subarborele drept i rdcina
(SDR - Stnga, Dreapta, Rdcin);
Descrierea algoritmilor de traversare, n limbajul Pascal este:
Procedure inordine ( def : adresa ) ; { traversare inordine }
begin
if def <> nil then
begin
inordine ( def^.fiu_st ) ;
write ( def^.info : 3 ) ;
inordine ( def^.fiu_dr ) ;
end ;
end ;
Procedure preordine ( def : adresa ) ; { traversare preordine }
begin
if def <> nil then
begin
write ( def^.info : 3 ) ;
preordine ( def^.fiu_st ) ;
preordine ( def^.fiu_dr ) ;
end ;
end ;
Procedure postordine ( def : adresa ) ; { traversare postordine }
begin
if def <> nil then
begin
postordine ( def^.fiu_st ) ;
postordine(def^.fiu_dr);
write ( def^.info : 3 ) ;
end ;
end ;
Probleme propuse
________________________________________________________________________________
155
Structuri de date i algoritmi
_______________________________________________________________________________
1.) Cte structuri arborescente diferite exist pentru trei noduri A,B i C ?
2.) Dac nodul A are trei frai iar B este tatl lui A, care este gradul lui B ?
3.) Exist arbore binar care s nu fie arbore ?
4.) S se creeze arborele genealogic propriu pe parcursul a trei sau patru generaii, punndu-se n
nodul rdcin prenumele iar n nodurile descendente ale fiecrui nod, numele prinilor.
5.) Pentru arborele binar din figura 32 s se scrie listele de vrfuri obinute n urma celor trei
metode de parcurgere.
6.) S se scrie un program pentru determinarea adncimii maxime a unui arbore binar, adic al
numrului de nivel maxim asociat nodurilor terminale.
7.) S se scrie un program pentru listarea tuturor nodurilor aflate pe un nivel dat ntr-un arbore
binar.
8.) Aplicnd cele trei metode de parcurgere a unui arbore binar, s se extrag, n ordinea n care
apar, nodurile descendente, n ordinea de la stnga la dreapta.
9.) S se conceap algoritmi de prelucrare (creare, parcurgere etc. ) pentru arborescene, utiliznd
pentru fiecare nod cte o list cu toate nodurile descendente, n ordinea de la stnga la dreapta.
10.) S se scrie un algoritm care, pe baza succesiunii nodurilor n inordine i postordine ale unui
arbore binar, s produc succesiunea n preordine a acestora. Analog, pe baza succesiunilor n
ordine i preordine, s se obin lista nodurilor n postordine.
II.5. Grafuri
II.5.1. Grafuri orientate
II.5.1.1. Definiii i generaliti
Definiia 1.5. Un graf orientat este un cuplu G (X, U), unde X este o mulime finit i nevid de
elemente numite vrfuri, i U XX este o mulime de elemente numite arce.
________________________________________________________________________________
156
Structuri de date i algoritmi
_______________________________________________________________________________
Fie un arc u = (x,y) U. Spunem c arcul u este incident exterior cu vrful x, este incident
interior cu vrful y, i are sensul (orientarea) de la x la y. Vrful x este extremitate iniial i
predecesorul lui y, i vrful y este extremitate final i succesorul lui x. Deci n precizarea unui arc
conteaz ordinea vrfurilor.
Dou vrfuri sunt adiacente dac ntre ele exist un arc. Dou arce distincte sunt adiacente
dac au o extremitate comun.
Definiia 1.6. Un graf orientat este un cuplu G (X, ), unde X este o mulime de elemente numite
vrfuri, i este o aplicaie multivoc : X X (adic o funcie definit pe X cu valori n familia
P(X) a prilor lui X).
Dac x X atunci y (x) precizeaz c de la vrful x la vrful y exist un arc i spunem c
y este succesor al lui x. Spunem c x este predecesor al lui y i notm x
1
(y).
Se d un graf G (X, ) i fie x X un vrf. Notm cu g
+
(x) numrul succesorilor si, adic
| (x)|; acest numr se numete semigradul exterior al lui x. Notm cu g

(x) numrul predecesorilor


si, adic |
1
(x)|; acest numr se numete semigradul interior al lui x. Suma g(x) g
+
(x) + g

(x) se
numete gradul lui x. Dac g(x) 0 spunem c vrful x este izolat.
Cele dou definiii sunt analoge:
(x) {y X | (x, y) U}; (x, y) U y (x).
Definiia 1.7 Un graf orientat este simetric dac pentru orice pereche de vrfuri x, y X avem: (x,y)
U (y,x) U.
Un graf este bipartit dac exist o partiie X X
1

X
2
astfel nct pentru orice (x,y) U
avem x X
1
i y X
2
.
Un graf G (A, V) este subgraf al grafului G = (X, U) dac A X i V (AA)

U.
Un graf G (X, V) este graf parial al grafului G (X, U) dac V U.
Un graf G (A, V) este subgraf parial al grafului G (X, U) dac A X i V (AA)

U.
Definiia 1.8 Fiind dat un graf orientat G (X, U), un drum n graful G este o succesiune de arce cu
________________________________________________________________________________
157
Structuri de date i algoritmi
_______________________________________________________________________________
proprietatea c extremitatea terminal a unui arc coincide cu extremitatea iniial a arcului urmtor
din drum. Un drum se poate defini i prin succesiunea de vrfuri care sunt extremiti ale arcelor ce
compun drumul: o succesiune de vrfuri cu proprietatea c orice dou vrfuri consecutive sunt unite
printr-un arc.
Un drum ntr-un graf este:
simplu, dac nu folosete de dou ori un acelai arc;
compus, dac nu e simplu;
elementar, dac nu trece de dou ori prin acelai vrf;
eulerian, dac este simplu i folosete toate arcele grafului;
hamiltonian, dac este elementar i trece prin toate vrfurile grafului;
circuit, dac extremitatea iniial a drumului coincide cu cea final.
II.5.1.2. Reprezentarea grafurilor orientate
a. Reprezentarea cu ajutorul matricelor de adiacen
Fie un graf orientat G (X, U), unde presupunem c
{ } n G , , 2 , 1
. Matricea de adiacen
A asociat grafului este o matrice ptratic de ordinul n, definit astfel:
[ ]
( )
( )

'

U j i dac
U j i dac
j i A
, , 0
, , 1
,
(5.x)
Exemplu 5.1: S considerm graful reprezentat n figura de mai jos:
________________________________________________________________________________
158
Structuri de date i algoritmi
_______________________________________________________________________________

1
Fig. 5.x.: Exemplu de graf orientat.
Atunci matricea de adiacen ataat grafului este:

,
_

0 1 0 0
0 0 1 0
1 0 0 0
0 1 1 0
A
Dezavantajul utilizrii reprezentrii grafurilor orientate cu ajutorul matricelor de adiacen
este dat de faptul c spaiul ocupat este de ordinul (n
2
). Orice operaie efectuat asupra grafului
orientat necesit parcurgerea matricei de adiacen asociat, care este o operaie de ordinul O(n
2
).
b. Reprezentarea cu ajutorul listelor de adiacen
Pentru a elimina dezavantajele reprezentrii grafurilor orientate cu ajutorul matricelor de
adiacen putem folosi o metod bazat pe reprezentarea cu liste nlnuite, numit reprezentare cu
liste de adiacen.
Lista de adiacen pentru un vrf i este o list simplu nlnuit a tuturor nodurilor adiacente
cu i. n acest fel reprezentarea grafului orientat G (X, U), se face cu o tabel n dimensional
numit CAP, elementul CAP[i] reprezentnd un pointer ctre capul listei de adiacen al vrfului i.
Exemplu 5.2: Reprezentarea grafului din Figura 5.x cu ajutorul listelor de adiacen:
________________________________________________________________________________
159
Structuri de date i algoritmi
_______________________________________________________________________________

1
Fig. 5.x:Reprezentarea grafului orientat din Figura 5.x cu ajutorul listelor de adiacen.
Reprezentrii grafurilor orientate cu ajutorul listelor de adiacen necesit un spaiu de
memorare ocupat este de ordinul (n+nr.de_arce). De aceea, aceast form de reprezentare este
preferabil atunci cnd expresia n+nr.de_arce este mai mic dect n
2
. De asemenea constatarea
faptului dac exist sau nu un arc de la vrful i la vrful j necesit un timp proporional cu O(n).
II.5.2. Grafuri neorientate
II.5.2.1. Definiii i generaliti
Definiia 1.9. Un graf neorientat este un cuplu G = (X, U), unde X este o mulime de elemente
numite vrfuri, i U este o mulime de perechi neordonate de vrfuri numite muchii. O muchie (x, y)
nu are orientare, astfel c (x, y) (y, x).
O muchie este incident vrfurilor care sunt extremiti ale sale. Dou vrfuri sunt adiacente
dac ntre ele exist o muchie. Dou muchii sunt adiacente dac au o extremitate comun. Gradul
unui vrf x este numrul de muchii incidente cu acesta i se noteaz g(x).
Definiia 1.10. Un lan este o succesiune de muchii cu proprietatea c orice muchie are un vrf
comun cu muchia precedent i cellalt vrf comun cu muchia succesoare.
n mod analog definim noiunea de ciclu corespunztoare noiunii de circuit de la grafuri
orientate.
________________________________________________________________________________
160
Structuri de date i algoritmi
_______________________________________________________________________________
Definiia 1.11. Un graf neorientat este conex dac ntre orice dou vrfuri exist un lan.
O component conex a unui graf neorientat este un subgraf conex maximal n raport cu operaia
de incluziune. Cu alte cuvinte, nu exist o submulime de vrfuri mai numeroas care s induc un
subgraf conex.
Definiia 1.12. Un arbore este un graf conex fr cicluri.
Lema 1.1. Un arbore cu n vrfuri are n1 muchii.
Demonstraie (Livovschi i Georgescu [1986]). Considerm pentru nceput un graf cu dou
vrfuri unite printr-o muchie, care este evident un arbore. La fiecare pas adugm un vrf nou pe
care l unim printr-o muchie cu un vrf deja existent. Presupunem c dup un numr de pai avem
un arbore cu k vrfuri i k1 muchii. La urmtorul pas obinem un arbore parial cu k+1 vrfuri i k
muchii. Nu se obine nici un ciclu: pentru aceasta ar fi trebuit ca noul vrf ales s fi fost deja
conectat cu unul din cele k vrfuri, fapt imposibil.
II.5.2.2. Reprezentarea grafurilor neorientate
a. Reprezentarea cu ajutorul matricelor de adiacen
Fie un graf neorientat G (X, U), unde presupunem c
{ } n G , , 2 , 1
. Matricea de
adiacen A asociat grafului este o matrice ptratic de ordinul n, definit astfel:
[ ]
( )
( )

'

U j i dac
U j i dac
j i A
, , 0
, , 1
,
(5.x)
Obs. 5.x: Se observ c matricea de adiacen ataat grafului este simetric n raport cu diagonala
principal.
Exemplu 5.1: S considerm graful reprezentat n figura de mai jos:
________________________________________________________________________________
161
Structuri de date i algoritmi
_______________________________________________________________________________

1
Fig. 5.x.: Exemplu de graf neorientat.
Atunci matricea de adiacen ataat grafului este:

,
_

0 1 1 1
1 0 1 0
1 1 0 1
1 0 1 0
A
b. Reprezentarea cu ajutorul listelor de adiacen
Pentru a elimina dezavantajele reprezentrii grafurilor neorientate cu ajutorul matricelor de
adiacen putem folosi o metod bazat pe reprezentarea cu liste nlnuite, numit reprezentare cu
liste de adiacen.
Lista de adiacen pentru un vrf i este o list simplu nlnuit a tuturor nodurilor adiacente
cu i. n acest fel reprezentarea grafului orientat G (X, U), se face cu o tabel n dimensional
numit CAP, elementul CAP[i] reprezentnd un pointer ctre capul listei de adiacen al vrfului i.
Exemplu 5.2: Reprezentarea grafului din Figura 5.x cu ajutorul listelor de adiacen:
________________________________________________________________________________
162
Structuri de date i algoritmi
_______________________________________________________________________________

1
Fig. 5.x:Reprezentarea grafului orientat din Figura 5.x cu ajutorul listelor de adiacen.
II.5.4. Grafuri planare
Pentru a reprezenta unele structuri geometrice n plan sau n spaiu se folosete o categorie
special de structuri de date: grafuri planare.
Definiia 1.13. Un graf G este planar dac este posibil s fie reprezentat pe un plan astfel nct
vrfurile s fie distincte, muchiile curbe simple i dou muchii s nu se intersecteze dect la
extremitile lor (dac sunt adiacente).
Reprezentarea grafului conform cu condiiile impuse se numete graf planar topologic i se
noteaz tot prin G. Nu se consider distincte dou grafuri planare topologice dac le putem face s
coincid prin deformarea elastic a planului.
Definiia 1.14. O fa a unui graf planar este o regiune a planului delimitat de muchii, care are
proprietatea c orice dou puncte din aceast regiune pot fi unite printr-o curb simpl care nu
ntlnete nici muchii i nici vrfuri.
Definiia 1.15. Frontiera unei fee este mulimea muchiilor care ating faa respectiv. Dou fee
sunt adiacente dac frontierele lor au cel puin o muchie comun.
ntr-un graf topologic, frontiera unei fee este format din unul sau mai multe cicluri
elementare disjuncte, din muchii suspendate sau care unesc dou cicluri disjuncte (istmuri).
________________________________________________________________________________
163
Structuri de date i algoritmi
_______________________________________________________________________________
Definiia 1.16. Conturul unei fee este conturul ciclurilor elementare care conin n interiorul lor
toate celelalte muchii ale frontierei.
Exist ntotdeauna o fa infinit i care are frontier, dar nu are contur; toate celelalte fee
sunt finite i admit un contur.
Teorema 1.2 (Euler). ntr-un graf planar topologic conex cu n vrfuri, m muchii i f fee avem
relaia:
n m + f 2
Demonstraie (Tomescu, I. [1981]).Dac f 1 atunci m n1 pentru un arbore (lema 1.1),
deci relaia este adevrat.
Presupunem afirmaia adevrat pentru orice graf planar conex cu f 1 fee, i s considerm un
graf planar conex cu f fee. Fie (x,y) o muchie a unui ciclu; aceasta se afl pe frontiera a dou fee S
i T. Dac eliminm muchia (x,y) se obine un graf planar conex cu n n vrfuri, m m1 muchii
i f f 1 fee. Conform ipotezei de inducie nm+f n1m+1+f 2, de unde obinem c n
m+f 2.
Corolar 1.3. n orice graf planar topologic conex cu n vrfuri, m muchii i f fee avem:
(i) n 2m/3 ; m 3f6 ; n 2f4 (dac fiecare vrf are gradul cel puin trei)
(ii) f 2m/3 ; m 3n6 ; f 2n4 (dac graful are cel puin dou muchii)
Demonstraie. (i) Din fiecare vrf pleac cel puin trei muchii, i fiecare muchie unete dou
vrfuri; rezult 3n 2m. Celelalte dou inegaliti rezult prin simpl nlocuire.
(ii) Dac m 2 atunci f 1 i n 3. Dac f 1 i m > 2 atunci n m+1. Dac f 2 atunci
fiecare fa are cel puin trei laturi (muchii), i o muchie este comun la cel mult dou fee; rezult
3f 2m. Celelalte dou inegaliti rezult prin simpl nlocuire.
S considerm n spaiul tridimensional un poliedru convex cu n vrfuri, m muchii i f fee.
Putem s-l reprezentm pe o sfer astfel nct dou muchii s nu se intersecteze dect la extremiti.
Efectund o proiecie stereografic al crei centru s fie n mijlocul unei fee, poliedrul se poate
________________________________________________________________________________
164
Structuri de date i algoritmi
_______________________________________________________________________________
reprezenta pe un plan. Graful fiind planar, se obine relaia lui Euler nm+f 2.
________________________________________________________________________________
165

S-ar putea să vă placă și