Documente Academic
Documente Profesional
Documente Cultură
Curs Sda 1
Curs Sda 1
M.Craus
Partea I
Complexitatea algoritmilor
Capitolul
Aspecte generale
Teoria complexitii are ca obiect de studiu clasicarea problemelor, bazat pe timpul de execuie i
spaiul de lucru utilizat de algoritmi pentru soluionarea lor. Cnd se analizeaz algoritmi paraleli, se
poate lua n considerare i numrul de procesoare.
Dei teoria complexitii a fost dezvoltat pentru probleme de decizie, aceasta nu este o restricie
sever deoarece multe alte probleme pot formulate n termeni de probleme de decizie. De exemplu, o
problem de optimizare poate rezolvat prin punerea ntrebrii existenei unei soluii cu cel mult sau
cel puin o valoare specicat.
1.1
Msurarea complexitii
a unei
probleme, pe o masin cu
procesoare (p
de acesta.
Pentru algoritmii paraleli complexitatea spaiu nu este ntotdeauna relevant. Din acest motiv aceasta
este mai puin studiat la astfel de algoritmi.
O problem se numete
p.
de dimensiunea mainii este un algoritm ce rezolv o problem PDD. Altfel, algoritmul se numete
independent de dimensiunea mainii.
Factorul de ncrcare (L) al unei probleme este raportul n=p. Viteza Sp (n)
T1 (n)=Tp (n). Eciena (Ep (n)) unui algoritm paralel se denete
este raportul
pozitive de variabile
n,
se noteaz:
1.2
Clase de complexitate
P, NP, Pspace.
: conine problemele solvabile n timp polinomial, ceea ce nseamn c pentru aceste prob-
leme exist algoritmi determiniti secveniali cu timpul de executie mrginit de un polinom de variabil
Pspace :
conine problemele care sunt solvabile utiliznd un spaiu polinomial, adic spaiul de lucru
Evident,
P are i ea problemele ei complete. Problemele P-complete sunt generalizri ale tuturor celorP, n termenii transformrilor care necesit spaiu de lucru logaritmic. Formal,
o problem este P-complet sub transformri spatiale logaritmice dac aparine clasei P i orice alt
problem din P este reductibil la ea prin transformri ce utilizeaz spaiu logaritmic. Dac o problem
P-complet ar aparine clasei Polylogspace, atunci ar adevrat incluziunea P Polylogspace.
Clasa
Cum aceast incluziune se presupune a fals, nu este de ateptat s existe un algoritm pentru o problem
Teze
Relaia ntre calculul secvenial i paralel este dat de teza calculului paralel (Chandra,
Kozen & Stockmeyer, 1981; Goldshlager, 1982): pentru orice funcie T (n), (n = dimensiunea problemei), clasa problemelor solvabile de o main cu paralelism nemrginit n timp T (n)O(1) (polinomial n T (n)) este egal
cu clasa problemelor solvabile de maini secveniale cu spaiul (T (n))O(1) .
Aceast tez este o teorem pentru multe dintre modelele relativ rezonabile. Astfel, clasa problemelor
solvabile n
()
T n
O (1)
timp de o main
PRAM
T n
()
T n
O (1)
In consecin, clasa
PRAM
necesit
Dac o astfel de problem ar rezolvabil n timp paralel polilogaritmic ar urma c aparine clasei
Polylogspace
PPolylogspace.
ateptat o soluie n timp paralel polilogaritmic. Orice metod de rezolvare pentru problemele grele din
P necesit probabil timp superlogaritmic i aceasta deoarece natura lor este probabil inerent secvenial.
Aceasta nu nseamn ns c paralelismul nu poate aduce creteri substaniale de vitez algoritmilor de
rezolvare.
In concluzie, clasa
poate partiionat n
Capitolul
O.
Deniie:
Fie f : N ! N i g : N ! N dou funcii. Spunem c f 2 O(g ) i notm f = O(g ) dac i numai dac
exist o constant c 2 R+ i un numr n0 2 N astfel nct pentru 8n > n0 ; f (n) < c g (n).
Observaie:
f n
n
+ +
Exemplul 1:
Fie
A,
Cutarea secvenial.
de ordin
n,
elementele tabloului.
SECV_SEARCH(A,n,b)
i 1;
WHILE ( A[i]<>b and i<n ) DO
i i+1
END_WHILE
5
se a printre
IF (A[i]=b) THEN
RETURN(i); // b a fost gsit pe poziia i n tabloul A
ELSE
RETURN(0); // b nu a fost gsit n tabloul A
END_IF
END
Complexitatea timp:
A.
Dac notm cu T (n) timpul de execuie n pai al acestui algoritm, atunci T (n) = 1+2n 1+1 = 2n +
1 = numrul de atribuiri i comparaii. O expresie logic este asimilat n cele ce urmeaz cu o comparaie
(ex. A[I]<>b and i<=n ) . Putem spune c T (n) = O (n) deoarece T (n) o funcie polinomial de gradul
I. Conteaz deci doar gradul polinomului, nu polinomul n ansamblu i nici coecientul termenului de
grad maxim , iar la numrarea pailor concentrarea se focalizeaz asupra numrului buclelor, nu asupra
pailor din interiorul buclei.
inteschimbare(a,b);).
Comportarea medie: Se poate
aux a; a b; b aux
versus
poziia
( )=
(3 + 5 + : : : + 2n 1 + 2n + 1 + 2 + 1) =
+ < n + 3 = O(n)
1
n+1
2(n+1)(n+2)
2(n+1)
T n
n+1
Observtie:
se a pe poziia
nu se a n tabloul
A.
s se ae n tabloul
pe
1
pentru ecare i
n+1
1
n
n+1
n tabloul
Complexitatea spaiu:
Memoria auxiliar utilizat de algoritmul SECV_SEARCH este cea necesar reprezentrii valorilor
lui
(1).
n continuare va analizat doar complexitatea timp pe cazul cel mai defavorabil. Complexitate timp
mediu i complexitatea spaiu vor calculate doar pentru algoritmi relevani n acest sens.
END
Exemplul 3:
( ) = 1 + 2(n 1).
T n
Inserarea elementului
k,
elementele
n secventa
[1 k 1] presupune:
plasarea lui
Ak
INSERTION_SORT (A,n)
FOR k = 2 to n DO
temp
A[k];
i
k-1;
WHILE (i >=1 and A[i] > temp) DO
A[i+1]
A[i];
i
i-1;
END_WHILE
A[i+1]
temp;
END_FOR
END
Exemplul 4:
PROD_MAT (A,B,C,n)
FOR i = 1 to n DO
FOR j = 1 to n DO
C[i,j]
0;
FOR k = 1 gets n DO
C[i,j]
C[i,j] + A[i,k] * B[k,j];
END_FOR
END_FOR
END_FOR
END
Rezult complexitatea
Exemplul 5:
Fie
A,
( ).
O n3
de ordin
n,
mid
low,
(de la middle).
BINARY_SEARCH (A,n,b)
low
1;
high
n;
WHILE (low =< high) DO
mid
(low + high)/2; // partea ntreag
IF (A[mid]=b) THEN
RETURN (mid);
ELSE
IF A[mid]>b THEN
high mid-1; // restrng cutarea la partea stng
ELSE
low
mid+1; // restrng cutarea la dreapta
se a printre
high,
iar mijlocul
END_IF
END_IF
END_WHILE
RETURN(0)
END
Calculul complexitii algoritmului const n determinarea numrului de ori pentru care se execut
bucla while.
Se observ c, la ecare trecere, dimensiunea zonei cutate se njumtete.
secvenial, cazul cel mai defavorabil este situaia n care vectorul
Pentru simplitate, se consider
printr-o majorare,
( ) log n + 1.
T n
=2
unde
log
Ca i la cutarea
= log
Fie f; g : N
! N.
Dac f
Aceast propriatate este util n majorarile care apar necesare atunci cnd se estimeaz dimensiunea
resursei timp sau spaiu utilizat de un algoritm.
2)
Fie f; g; h : N
Aceast proprietate poate folosit la ncadrarea unui algoritm n alt clas de complexitate, pentru
a prelua rezultate cunoscute relative la clasa n care a fost inclus.
Fie f ; f ; g ; g : N ! N .
f = O(g g )
3)
i
f1
i f1
Proprietatea 3) permite ca, atunci cnd dou bucle (de complexiti diferite) sunt succesive, complexitatea total s se obin prin adunarea complexitilor buclelor. Dac buclele sunt imbricate, complexitatea total se obine prin nmulirea complexitilor buclelor.
Aceast proprietate este de asemenea util atunci cnd algoritmul conine apeluri de funcii ale cror
complexitate este cunoscut.
Mai mult chiar, proprietatea 3) poate folosit la schimbarea unitii de masur a instruciunilor unui
algoritmi. Astfel, dac un algoritm conine instruciuni nedetaliate, atunci complexitatea algoritmului
rezultat prin detaliere se poate obine prin inmulirii complexitti calculate n ipoteza c o instruciune
nedetaliat solicia
Teorem:
( ) O(a ).
O nc
k+1
Pentru calculul complexitii se va ncerca ncadrarea n clasa cea mai mic de complexitate din acest
ir:
O
O
O
O
O
O
(1)
(log n)
(log n)
(n)
(n )
(n )
k
k+1
(2 )
n
= n(n2+ 1) ) O(n )
i=1
X
n
i2
i=1
= n (n4+ 1) ) O(n )
i3
i=1
X
n
P
n
i=1
( ) = P i2
n
G n
2 =2
n+1
2
( ) = 2 G(n)
n+1
i=0
i=1
( )=
G n
=n2
2+
G n
X
n
X
n
2i 2
i=1
X
n
P
n
i=1
(i 1 i) 2 = n 2
i=1
2 =
i=1
n+1
X
n
i=1
n
X
i=1
(n 1) 2
2
i+1
X
n
2 =
i
i=1
2 = (n 1) 2
i
n+1
+2
10
Partea II
Structuri de date
11
Capitolul
Aspecte generale
3.1
Deniie.
O structur de
date este
o colecie organizat
set de operaii.
Organizarea coleciei presupune existena unei topologii relaionale ntre elementele coleciei.
Att
structura
ct i
referite.
Colecia referit de un tip de date este omogen n timp ce colecia referit de o structur poate i
neomogen.
C referit de un tip de date este denit cel mult o relaie de ordine "".
Peste colecia
Structura
presupune un sistem relaional care n varianta cea mai simpl poate induce o relaie de ordine. n general
sistemul relaional
un alt element
e2
dac
Tipul de date presupune uzual un model de reprezentare a elementelor mulimii la care se refer tipul.
intreg denete o submulime a mulimii numerelor ntregi, reprezentate pe 2 octei
De exemplu, tipul
n cod complementar peste care sunt denite operaiile : +, :, *, /, operaii la nivel de bii (not, si,
i structura presupune un model de reprezentare (implementare) a
datelor coleciei dar n plus aceasta presupune i un model de reprezentare (implementare) a sistemului
relaional. Focalizarea la tip se face pe reprezentarea datelor n timp ce la structur n centrul ateniei
nu intereseaz reprezentarea,
abstracte.
de date se numesc
Un tip poate ncorpora o structur n sensul c elementele tipului pot structuri. Astfel de
structurate.
Operaiile denite
tipuri
se
numesc
reprezentarea elementelor acesteia. Astfel la tipul ntreg operaiile sunt caracteristice numerelor ntregi
reprezentate n cod complementar. Pentru tipul ntreg abstract operaiile sunt cele denite pe mulimea
numerelor ntregi.
Dac tipul este structurat operaiile caracteristice tipului sunt dependente de cele
denite pe structura care este la baza tipului. Colecia referit de un tip de date este nit i are caracter
static n sensul ca este nemodicabil n timp, aspect ce caracterizeaz noiunea matematic de mulime.
Operaiile denite pe colecia referit de o structur deriv din compoziia coleciei, din sistemul
relaional denit peste colecie i caracterul static sau dinamic al acesteia. Corespunztor caracterului
static sau dinamic al coleciei de date avem dou tipuri de structuri: statice i dinamice. Pentru ecare
12
13
determinarea operaiile denite pe structurle statice. Acestea sunt dominant dependente de compoziia
coleciei referite de structur.
Structurile dinamice colecii potenial innite, modicabile n timp. Operaiile caracteristice structurilor dinamice sunt dependente de sistemul relaional denit peste colecie. Urmatoarele operaii sunt
tipice structurilor dinamice:
explorarea
colecie;
R denit peste colecie: aceasta nseamn c dac perechea de elemente (e ; e ) 2 R atunci e este
predecesorul direct a lui e ( e = pred(e ) ) iar e este succesorul direct al lui e ( e = succ(e ) );
1
3.2
elementelor coleciei.
ntr-o asfel de
relaional are la baz arhitectura poziiilor, ind astfel exterior elementelor coleciei referite de structur.
Astfel, relaiile ntre elementele coleciei sunt implicite, motiv pentru care astfel de structuri se mai
numesc i structuri implicite. Implementarea unei astfel structuri presupune alocarea n prealabil a unei
grupri de locaii succesive de memorie sucient de mare i de dimensiune nemodicabil, zon n care
va incrcat i procesat structura. Aceasta limiteaz potenialul unei astfel de structuri.
O
respectiv. Astfel, sistemul relaional al elementelor este nregistrat n structura acestora deci este explicit.
Capitolul
Tablouri
4.1
Aspecte generale
Deniie. Tabloul ca structur abstract este o colecie omogen de date n care ecare element poate
identicat pe baza unui index, colecia asigurnd acces direct i timp de acces constant pentru ecare
element. Tabloul este deci o structur ordonat.
Tabloul este o structur static n sensul imposibilitii modicrii n timp a dimensiunilor acestuia.
Valorile coninute ntr-un tablou pot modicate n timp ceea ce nseamn ns c doar atributele de
valoare ale elementelor tabloului se schimb n timp i nu elementele lui.
Prin implementarea (reprezentarea) unui tablou se nelege plasarea valorilor asociate elementelor ce
compun tabloul n locaii succesive de memorie:
Locaiile de memorie pot numerotate, permind accesarea direct a oricrui element. Numerele
asociate astfel locaiilor de memorie se numesc indecii tabloului.
V alori.
Indeci peste care este denit o relaie de ordine total iar valoare aparine la o mulime numit
23
Observaie.
ij
2
3
1 3 5
4 2 10 12 5
5 4 3
poate gndit ca ind mulimea de perechif< (0; 0); 1 >; < (0; 1); 3 >; < (0; 2); 5 >; < (1; 0); 2 >; <
(1; 1); 10 >; < (1; 2); 12 >; < (2; 0); 5 >; < (2; 1); 4 >; < (2; 2); 3 >g
Generaliznd, un tablou multidimensional A 1 2 m poate implementat ca o mulime f<
(i ; i ; : : : ; i ); a 1 2 m > = 0 i n 1; k = 1; 2; : : : ; mg unde (i ; i ; : : : ; i ) (j ; j ; : : : ; j ) ,
n
i ;i ;:::;i
:::
14
+
+ +
+
+:::+n i
n2 n3 : : : nm i1 n3 n4 : : : nm i2
j2 : : : nm jm 1 jm
15
+i n n :::n j +n n :::n
rare unde majoritatea elementelor sunt 0. Elementele cu valoarea 0 nu vor mai reprezentate n memorie
din motive de utilizare ecient a acestei resurse. Trebuie precizat ns c n aceste condiii tablourile
devin structuri dinamice nlanuite. Elementul de tablou nu va mai atomic ci va include n compoziia
sa
4.2
Exerciii
A1n
este o secven
= j . Suma
unei seciuni este denit ca ind suma elementelor sale. Se presupune c elementele vectorului
sunt numere ntregi negative. S se scrie un algoritm care calculeaz seciunea de sum minim.
2. Se consider un tablou bidimensional
x,
i0 ; j0
astfel nct
Ai0 ;j0
=x.
Dac
2
4
a11
a21
a31
a12
a22
a32
a13
a23
a33
3
5
90 ,
o
2
4
Exemplu: Dac
atunci
rotit cu
90
este:
2
4
a11
a21
a31
a12
a22
a32
a13
a23
a33
a31
a32
a33
a21
a22
a23
a11
a12
a13
3
5
3
5
Capitolul
Liste simple
5.1
Aspecte generale
8e ; e 2 C ; e 6= e
1
3.
2 i
(e ; e ) 2 R ) (e ; e ) 2= R;
1
pentru care:
mulimea elementelor.
O consecina a propriettii
2 este aceea c ultimul element al listei are cel mult un succesor direct
(capul listei) i capul are cel mult un predecesor direct (ultimul element).
Din proprietatea
tranzitiv a lui
i+1
coleciei.
Colecia de elemente care compun lista este modicabil n timp. Lista este deci o structur dinamic.
ntre elementele unei structuri de tip list
Celelalte sunt n general accesibile indirect prin intermediul sistemului relaional care furnizeaz secvenial
informaii de identicare a elementelor n cadrul listei.
informaiile de identicare a elementelor n cadrul listei se obin dup accesarea elementului predecesor
sau uneori succesor direct. Exist totui i situaii n care toate elementele unei liste sunt direct accesibile
(cazul listelor ordonate).
5.2
Operaiile de baz care se pot face n cadrul unei liste simple sunt cele caracteristice structurilor dinamice:
consultare:
parcurgere:
inserare:
tergere:
17
modicare:
min/max:
Capitolul
Liste liniare
6.1
Aspecte generale
(ultimul; capul) 2= R
Rezult urmtoarele:
6.2
a1
a2
...
ai
ai
ai+1
...
///////
19
Inserarea i tergerea unui element din list sunt operaii care necesit detaliere:
Inserarea
Inserarea unui element ntr-o list ordonat se face astfel:
spre stnga pentru a face astfel loc noului element. Conform cu gura urmtoare,
face nspre zona de memorie liber (cea haurat).
a1
a2
...
ai
a1
a2
...
ai
ai
ai+1
ai
...
ai+1
///////
...
///
a1
a2
...
ai
ai
ai+1
a
...
///
pe poziia
i:
dup un element
b:
deplasarea
se
20
stnga.
a1
a2
...
ai
ai
a1
a2
...
ai
ai+1
ai+1
...
...
//////
//////////
a:
6.3
6.4
O list liniar simplu nlnuit este caracterizat prin includere n compoziia elementului de list
numai a informaiilor necesare calculrii succesorului unui element.
(val; succ);
unde
val
succ
permite s identicm un elementului urmtor din list nlnuit. Pentru nlnuire se pot folosi i valori
21
de tip adres de memorie sau de tip poziie. Informaia de nluire de tip poziie corespunde noiunii
de
index
pointer.
n domeniul limbajelor de programare, indexul ind caracteristic tablourilor (alocate static) iar pointerul
alocrii dinamice acesta din urm ind o variabil care conine o adres de memorie.
O list poate reprezentat astfel:
cap de lista
l,
static (tablouri) i NULL n C++ n cazul implementrii listei prin tehnici de alocare dinamic (care
utilizeaz pointeri).
Notaii
data(p) :
succ(p) :
p;
p;
bil).
Observaie.
Ultimele dou notaii se refer la cazul utilizrii tehnicilor de alocare dinamic pentru
implementarea listei.
Dac informaiile de nlnuire sunt materializate ca pointeri atunci n C++ un element de list va
o astfel de structur:
struct Element f
Tip_Inf_Continut data;
Element* succ;
g;
Corespunztor cu notiile de mai sus vom avea:
noiunea de adres se
22
succ, n
O parcurgere a listei presupune o prelucrare efectuat asupra ecrui element din list (aadar, nu o
funcie, ci o secven de instruciuni).
Fie
p l;
WHILE p 6= o DO
prelucrare (data(p)) //ex: afiarea indormaiei de coninut
p succ(p) //trece la urmtorul
END_WHILE
Observaie. Consultarea, modicarea unui element al listei i identicarea elementului minim/maxim
sunt operaii care presupun parcurgerea parial sau total a listei.
Un prototip de parcugere parial poate urmtoarea secven de pseudocod:
p l;
WHILE not condiie(p) and p 6= o DO
prelucrare (data(p)) //ex: afiarea indormaiei de coninut
p succ(p) //trece la urmtorul
END_WHILE
Inserarea
Exist trei situii tipice de inserare a unui element ntr-o list liniar simplu nlnuit:
p.
Observaie.
Se presupune c elementul care urmeaz a inserat are adresa coninut ntr-o variabil
n ultimele dou cazuri se presupune c elementul dup care urmeaz a se face inserarea are adresa
p).
q
q
1 : Prima atribuire:
succ(p)
2 : A doua atribuire:
q
p
Inserarea naintea primului element al listei se poate descrie astfel:
23
succ(p)
2 :
--
1 :
Observaie.
rmn valabile:
c
1 :
succ(p)
2 :
1 Prima atribuire:
1
q
p
Inserarea n interiorul listei se poate detalia astfel:
2 A doua atribuire:
succ(p)
succ(q)
succ(q)
p
1 :
succ(p)
succ(q)
2 :
succ(q)
24
succ(p)
succ(q)
succ(q)// succ(q)=o
p
tergerea
tergerea unui element dintr-o list liniar simplu nlnuit comporta urmtoarele situii:
Observaie.
n ultimele dou cazuri se presupune ca elementul dup care urmeaz a se face teregerea
q).
1 : Prima atribuire:
- T
-
TT 3
2 : A doua atribuire:
3 :
Situaia iniial:
l
q
Situaii intermediare:
free_sp(p);
l
succ(l)
25
p
q
1
l
q
1 :
2 :
succ(l)
3 :
p
q
Situaia nal:
p
- SS -S
2 :
succ(p)
3 :
free_sp(q)
1 :
1 :
succ(p)
Situaia iniial:
succ(q)
Situaii intermediare:
q
succ(p)
26
--
2 :
succ(p)
3 :
free_sp(q)
succ(q)
Situaia nal:
q
conine adresa penultimului element dintr-o list liniar simplu nlnuit, atribuirile de
situaia n care poziia de inserat este dat prin numrul de ordine al elementului ce trebuie s e
inserat n list;
situaia n care poziia de inserat este dat prin valoarea elementului dup care sau nainte de care
se face inserarea;
situaia n care poziia de inserat poate dat implicit prin informaia de coninut a elementului
de inserat - cazul listelor sortate.
n consecin inserarea unui element ntr-o list are algoritmi diferii, funcie de datele de nserare de
care se dispune.
INSERT(l,a,b)
27
ELSE
IF data(l)=b THEN // inserare in faa primului element al listei
succ(p) l;
l p;
ELSE // inserare n interior
// caut n list elementul ce conine b
q l;
WHILE succ(q)6=o and data(succ(q))6=b DO
p succ(q);
END_WHILE
IF data(succ(q))6=b THEN
eroare("Elementul ce ar trebui s conin b nu se afl
n list");
ELSE // elementul ce conine b este curent accesibil
// inserare element ce conine a
succ(p) succ(q);
succ(q) p;
END_IF
END_IF
END_IF
END
situaia n care poziia de ters este dat prin numrul de ordine al elementului ce trebuie s e
ters din list;
situaia n care poziia de ters este dat prin informaia de coninut a elementului care urmeaz a
ters sau a elementului dup care sau nainte de care se face tergerea;
n consecin i tergerea unui element dintr-o list are algoritmi diferii, funcie de datele de tergere
de care se dispune.
tergerea elementului din faa unui element specicat prin informaia de coninut a elementului
Pseudocodul pentru o astfel de funcie de tergere poate de forma:
DELETE(l,a)
28
END_WHILE
IF succ(p)=o THEN
eroare ("Elementul ce ar trebui s conin a nu se afl
n list");
ELSE // tergere n interiorul listei sau a ultimului element
q succ(p);
succ(p) succ(q);
free_sp(q);
END_IF
END_IF
END_IF
END
6.4.3 Exerciii
1. Se citete, prin intermediul intrrii standard, un ir de numere ntregi.
S se plaseze numerele citite ntr-o list liniar simplu nlnuit, prin inserri repetate n faa
listei;
2. Fie
C/C++ care:
= (x ; x ; ::; x
1
Z
Z
= (x ; y ; x ; y ; :::; x
= (x ; y ; x ; y ; :::; x
1
; y1 ; y2 ; :::; ym
);
parcurgerea unei liste liniare simplu nluite n ambele sensuri (dus-intors) utiliznd O(1)
memorie suplimentar;
testarea situaiei n care o list liniar simplu nlnuita are bucle;
determinare mijlocul unei liste liniare simplu nlnuite (poziia elementului situat n mijlocul
listei).
6.5
O list liniar dublu nlnuit este caracterizat prin includerea n compoziia elementului de list att
a informaiilor necesare calculrii succesorului ct i predecesorului elementului respectiv.
element
Astfel, un
29
val este informaia de coninit al unui element al listei nlnuite, iar pred i succ sunt informaii
de nlnuire care permit identicarea elementului precedent i respectiv urmtor din lista liniar dublu
nlnuit.
Dac informaiile de nlnuire sunt materializate ca pointeri, o list liniar dublu nlnuit poate
reprezentat astfel:
-
q
q
-
q
q
-
cap de lista
Notaii
pred(p) :
list indicat de
succ(p) :
p,
list indicat de
p,
struct Element f
Tip_Inf_Continut data;
Element *pred,*succ;
g;
Corespunztor cu notiile de mai sus vom avea:
pred(p) p!pred
succ(p) p!succ
Parcurgere nainte
p l;
WHILE p6=o DO
prelucrare(data(p)); //ex: afiarea elementului
p succ(p) //trece la urmtorul
END_WHILE
Parcurgere nainte i napoi
p l;
WHILE p6=o DO
succ i pred.
30
Observaie.
p l;
WHILE not condiie(p) and p6=o DO
prelucrare(data(p)); //ex: afiarea elementului
p succ(p); //trece la urmtorul
END_WHILE
Inserarea
Exist trei situaii tipice de inserare a unui element ntr-o list liniar dublu nlnuit:
p.
ultimele dou cazuri se presupune ca elementul dup care urmeaz a se face teregerea are adresa (poziia)
cunoscut (coninut ntr-o variabil
q).
-q
1 :
2 :
3 :
4 :
q
r
-
q
q
-
q
q
-
pred(p) o
succ(p) l
pred(l) p
l p
q).
z
3
4
1
2
q
JJ -q
q
1 :
2 :
3 :
4 :
31
q
q
-
q
q
-
succ(p) q
succ(pred(q)) p
pred(p) pred(q)
pred(q) p
1 :
3 :
4 :
-:
q
2 :
q
q
J
-q
q
q
-
q
q
-
pred(p) q
pred(succ(q)) p
succ(p) succ(q)
succ(q) p
q).
-
-
q
q
q
q
1 :
3 :
O
2
?
-
2 :
32
pred(p) q;
succ(q)) p;
succ(p) o;
tergerea
tergerea unui element dintr-o list liniar dublu nlnuit comporta urmtoarele situii:
Observaie.
n ultimul caz se presupune c elementul dup sau naintea cruia urmeaz a se face
p).
-* AA H - A
4
c
q
-
q
q
1 :
2 :
3 :
4 :
p l
l succ(l)
pred(l) o
free_sp(p)
-
p
1 :
2 :
3 :
4 :
j
- @@ -~
@
}
- @@ -~
@
}
-
j
~
- @@ @
}
4
q
q
3 :
4 :
-
q pred(p);
succ(q) succ(p);
pred(succ(p)) q;
free_sp(p);
Variabila
2 :
1 :
-
j
-
3 :
4 :
-
2 :
q
q
q succ(p);
succ(p) succ(q);
pred(succ(q)) p;
free_sp(q);
Variabila
1 :
33
q pred(p);
pred(p) pred(q);
succ(pred(q)) p;
free_sp(q);
-
q
q
-
1 :
q
c
QQ - TT
T
q
c
H - TT
T
2 :
free_sp(succ(p));
succ(p) o;
Variabila
-
q
q
-
1 :
2 :
34
succ(pred(p)) o;
free_sp(p);
Algoritmii difer ns de cei din cazul listelor liniare simplu nlntuite. Aceast se datoreaz faptului c
operaia de inserare trebuie s actualizeze dou informaii de nlnuire (pred i
succ) i nu
una (succ).
De exemplu pentru inserarea n faa unui element specicat prin informaia de coninut, un prototip
de pseudocod este urmtorul:
INSERT(l,a,b)
35
IF data(succ(q))6=b THEN
eroare("Elementul ce ar trebui s conin b nu se afl
n list");
ELSE // elementul ce conine b este curent accesibil
// inserare element ce conine a
pred(p) q;
pred(succ(q)) p;
succ(p) succ(q);
succ(q) p;
END_IF
END_IF
END_IF
END
DELETE(l,a)
END
36
6.5.3 Exerciii
1. Se citete, prin intermediul intrrii standard, un ir de numere ntregi.
2. Fie
S se plaseze numerele citite ntr-o list liniar dublu nlnuit, prin inserri repetate n faa
listei;
S se aeze lista creat;
Se citete un numr. S se determine dac acesta se a printre elementele listei create;
S se insereze un numr ntr-o poziie n list, numrul i poziia ind introduse (citite) prin
intermediul intrrii standard;
S se stearg un element din list, poziia de tergere ind dat la intrarea standard;
C/C++ care:
= (x ; x ; ::; x
1
Z
Z
= (x ; y ; x ; y ; :::; x
= (x ; y ; x ; y ; :::; x
1
; y1 ; y2 ; :::; ym
);
Capitolul
Liste circulare
7.1
Aspecte generale
(ultimul; capul) 2 R
Rezult urmtoarele:
tranzitiv a lui
1
O list circular poate ordonat dar aceasta presupune denirea pe mulimea poziiilor a unei relaii
de tipul lui
circulare. In consecin listele circulare vor analizate n cele ce urmeaz doar ca structuri nlnuite.
7.2
Un element al unei liste circulare simplu nlnuite are aceai structur ca i elementele unei liste liniare
simplu nlnuite.
succ, n
38
Situiile tipice de inserare a unui element ntr-o list circular simplu nlnuit sunt aceleai ca la
liste liniare simplu nlnuite:
-
>
-q
>
>
q q q
-~ i
1
parcurgere lista
q conine adresa ultim element
2
succ(q)
3
succ(p)
4
-
-
-~
rrr
1
succ(p)
succ(q)
2
succ(q)
39
Inserarea n interiorul unei liste circulare simplu nlnuite nu difer cu nimic de inserarea
-
-
-~
rrr
1
succ(p)
succ(q)
2
succ(q)
Observaie.
Dei inserarea dup ultimul element al listei ar putea asimilat cu inserarea naintea
capului listei prima difer de a doua prin aceea ca adresa ultimului element este cunoscut iar capul listei
nu se schimb.
tergerea
tergerea unui element dintr-o list circular simplu nlnuit comport urmtoarele situaii:
-- T
- -
TT >
I
5
succ(q)
succ(c);
p
c;
c
succ(c);
free_sp(p);
1
qqq q
--
40
q
Observaie.
-- SS S *
1
q q q
2
succ(p)
3
free_sp(q)
1
succ(p)
succ(q)
Nici tergerea n interiorul unei liste circulare simplu nlnuite nu difer de tergerea n
p
-- AA
A
3
1
q
OBSERVAIE.
1
2
3
q
succ(p)
succ(p)
c
free_sp(q)
O list circular simplu nlnuit poate specicat ntr-un mai protabil prin
ultimul element (predecesorul capului listei). Acest mod de identicare a unei astfel de liste ar elimina
necesitatea parcurgerii listei atunci cnd urmeaz o inserie n faa listei sau tergerea capului listei.
situaia n care poziia de inserat este dat prin numrul de ordine al elementului ce trebuie s e
inserat n list;
situaia n care poziia de inserat este dat prin valoarea elementului dup care sau nainte de care
se face inserarea;
situaia n care poziia de inserat poate dat implicit prin valoarea elementului de inserat - cazul
listelor sortate.
n consecin inserarea unui element ntr-o list are algoritmi diferii, funcie de datele de nserare de
care se dispune.
insert nscrie un
INSERT(c,a,b)
c:
41
END
situaia n care poziia de ters este dat prin numrul de ordine al elementului ce trebuie s e
ters din list;
situaia n care poziia de ters este dat prin informaia de coninut a elementului de ters sau prin
informaia de coninut a elementului dup care sau nainte de care se face tergerea.
n consecin i tergerea unui element ntr-o list circular simplu nlnuit are algoritmi diferii,
funcie de datele de tergere de care se dispune.
tergerea elementului din faa unui element specicat prin valoarea elementului
Pseudocodul pentru o astfel de funcie de tergere poate de forma:
DELETE(c,a)
42
END
7.2.3 Exerciii
1. Se citete, prin intermediul intrrii standard, un ir de numere ntregi.
S se plaseze numerele citite ntr-o list circular simplu nlnuit, prin inserri repetate n
faa listei;
S se aeze lista creat;
Se citete un numr. S se determine dac acesta se a printre elementele listei create;
S se insereze un numr ntr-o poziie n list, numrul i poziia ind citite introduse prin
intermediul intrrii standard;
S se stearg un element din list, poziia
de tergere ind dat la intrarea standard;
2. S se scrie un algoritm care inverseaz legturile ntr-o list circular simplu nlnuit.
3. Fie
= (x ; x ; ::; x
Z
= (x ; y ; x ; y ; :::; x
1
; ym ; xm+1 ; :::; xn
; y1 ; y2 ; :::; ym
) dac m <= n,
);
Scriei un
= (x ; y ; x ; y ; :::; x
1
; yn ; yn+1 ; :::; ym
43
) dac n <= m.
p0
m-a persoan; cer-
cul se inchide dup eliminarea unei persoane. Execuia se termin cnd rmne o singur persoan;
aceasta va rmne n via.
S scrie o funcie C/C++ care s aeze persoanele n ordinea n care au fost executate;
Presupunnd c se dorete salvarea unei anume persoane, s se scrie o funcie C/C++ care s
determine pozitia
p0
i0 ,
e cea dorit.
7.3
Elementele unei liste circulare dublu nlnuite au aceai structur ca i elementele unei liste liniare dublu
nlnuite.
Parcurgere nainte
44
p.
O
p
i
1
4
-q
1 :
2 :
3 :
4 :
5 :
6
r
-
q
q
%
q q q
q
-
pred(p) pred(c)
succ(p) c
succ(pred(c)) p
pred(c) p
c
p
q).
z
3
4
1
2
q
JJ -q
q
1 :
2 :
3 :
4 :
45
q
q
-
-
-
succ(p) q
succ(pred(q)) p
pred(p) pred(q)
pred(q) p
1 :
3 :
4 :
z
1
2 :
2
3
4
q
JJ -q
pred(p) q
pred(succ(q)) p
succ(p) succ(q)
succ(q) p
q
q
-
46
Se presupune c ultimul element al listei dup care urmeaz a se face inserarea are adresa cunoscut
(coninut ntr-o variabil
q).
- q
OM
2
?
--
4
-
q q q
3
1 :
2 :
3 :
4 :
pred(p)
succ(q))
pred(c)
succ(p)
q;
p;
p;
c;
tergerea
tergerea unui element dintr-o list circular dublu nlnuit comporta urmtoarele situaii:
Observaie.
n ultimul caz se presupune c elementul dup sau naintea cruaia urmeaz a se face
p).
!!
!
>
"
"
"
2
9
--* A
AA H -
3
q
q
pq pq pq
1 :
2 :
p c
succ(pred(c)) succ(c)
47
pred(succ(c)) pred(c)
c succ(c)
free_sp(p)
-
1 :
2 :
3 :
4 :
c
p
j
- @@ -~
@
}
- *
j
-
- @@ -~
@
}
4
q
q
3 :
2 :
- *
q succ(p);
succ(p) succ(q);
pred(succ(q)) p;
free_sp(q);
Variabila
1 :
q
q
q pred(p);
succ(q) succ(p);
pred(succ(p)) q;
free_sp(p);
Variabila
-
j
- @@ -~
@
}
4
q
q
1 :
2 :
3 :
4 :
48
q
q
-
q pred(p);
pred(p) pred(q);
succ(pred(q)) p;
free_sp(q);
- q
q
q
:
pq qp pq
c
1 :
2 :
3 :
free_sp(succ(p));
succ(p) c;
pred(c) p;
Variabila
q
q
-- AA
A
q
49
- q
q
q
!!!
2
:
pq pq pq
1 :
2 :
3 :
q
q
- AA
A
succ(pred(p)) c;
pred(c) pred(p);
free_sp(p);
succ) i nu
una (succ).
De exemplu pentru inserarea n faa unui element specicat prin informaia de coninut, un prototip
de pseudocod este urmtorul:
INSERT(c,a,b)
50
pred(succ(q)) p;
succ(p) succ(q);
succ(q) p;
END_IF
END_IF
END_IF
END
DELETE(c,a)
END
7.3.3 Exerciii
1. Se citete, prin intermediul intrrii standard, un ir de numere intregi.
S se plaseze numerele citite ntr-o list circular dublu nlnuit, prin inserri repetate n
faa listei;
S se aeze lista creat;
Se citete un numr. S se determine dac acesta se a printre elementele listei create;
2. Fie
51
S se insereze un numr ntr-o poziie n list, numrul i poziia ind citite (introduse) prin
intermediul intrrii standard;
S se stearg un element din list, pozii de tergere ind dat la intrarea standard;
C/C++ care:
Z
Z
= (x ; y ; x ; y ; :::; x
= (x ; y ; x ; y ; :::; x
1
= (x ; x ; ::; x
1
n ; yn ; yn+1 ; :::; ym
; y1 ; y2 ; :::; ym
) dac m <= n,
) dac n <= m.
; ym ; xm+1 ; :::; xn
);
Capitolul
Stive i Cozi
8.1
Stive
Deniie.
O stiv este o structur de date de tip container (depoziteaz obiecte de un anumit tip),
pop.
Captul
Aadar:
push
O stiv poate implementat ca o list liniar pentru care operaiile de acces (inserare, tergere,
accesare element) sunt restricionate astfel:
Dac STACK este o structur de tip stiv i ATOM este tipul obiectelor coninute n stiv, atunci
operaiile care denesc o structur de tip stiv sunt urmtoarele:
CREATE()
! STACK
Operaia CREATE nu primete parametri, creeaz o stiv care pentru nceput este vid (nu conine
nici un obiect).
! STACK
Operaia PUSH primete ca parametri o stiv i un obiect i produce stiva modicat prin adugarea
obiectului n stiv.
52
POP (STACK)
53
! STACK, ATOM
Operaia POP primete ca parametri o stiv pe care o modic scond un obiect. De asemenea,
produce ca rezultat obiectul scos din stiv.
TOP (STACK)
! ATOM
Operaia TOP ntoarce ca rezultat obiectul din vrful stivei pe care o primete ca parametru.
! boolean
ISEMPTY (STACK)
Operaia ISEMPTY este folosit pentru a testa dac stiva este vid.
8.2
Cozi
Deniie. O coad este o structur dinamic care inserarea se face la un capt (la sfrit), iar tergerea
se face la cellalt capt al cozii (la nceput). Partea din fa a cozii (primul element) se numete
iar partea din spate (ultimul element) se numete
end.
front,
Deci:
- del
O coad poate implementat ca o list liniar n care operaiile de acces sunt restricionate astfel:
Dac QUEUE este o structur de tip coad i ATOM este tipul obiectelor coninute n coad, atunci
operaiile caracteristice unei structuri de tip coad sunt urmtoarele:
PUT(QUEUE, ATOM)
! QUEUE
GET(QUEUE)
! QUEUE, ATOM
FRONT(QUEUE)
! ATOM
ISEMPTY(QUEUE)
! boolean
8.3
Implementri de stive
Notaii:
S : stiva;
S:vect : vectorul n care se reprezint
S:top : indicele vrfului stivei.
elementele stivei
S;
54
Elementele sunt memorate, aadar, unul dup altul n vectori, neind neaprat n ordine cresctoare.
Zona de memorat trebuie s conin aceste dou informaii:
Condiia de stiv vid este:
S.top =
S.top i S.vect.
0.
struct Stack{
int top; // "top of stack"
atom vect[DIMSTACK];
};
Operaiile care denesc structura de stiv ordonat n C++ vor implementate prin urmtoarele
funcii:
PUSH(S,a)
END
POP(S)
IF S.top = 0 THEN
eroare (Stiv vid);
ELSE
S.top S.top-1;
END_IF
END
Observaie.
din list.
TOP(S)
IF S.top = 0 THEN
eroare (Stiv vid);
ELSE
return(S.vect[S.top]);
END_IF
END
ISEMPTY(S)
return(S.top=0);
END
55
din
= 0.
Fie
Dac informaiile de nlnuire sunt materializate ca pointeri atunci n C++ un declaraiile vor
urmtoarele:
struct Element{
Atom data;
Element* succ;
};
typedef Element* Stack;
void initStack(Stack& S);
void push(Stack& S, Atom val);
Atom pop(Stack& S);
Atom top(Stack S);
int isEmpty(Stack S);
Funciile care implementeaz operaiile de acces vor avea prototipuri similare cu cele date pentru
stivele ordonate:
PUSH(S,a)
p get_sp();
data(p) a;
succ(p) S;
S p;
END
POP(S)
IF S=0 THEN
eroare (Stiv vid);
ELSE
p S;
S succ(S);
free_sp(p);
END_IF
END
TOP(S)
IF S=0 THEN
eroare (Stiv vis);
ELSE
return(data(S));
END_IF
END
ISEMPTY(S)
return(S=0);
END
56
Exerciii
1. Forma polonez (notaia posxat) a unei expresii aritmetice se caracterizezaz prin aceea c operatorii apar n ordinea n care se execut operaiile la evaluarea expresiei. De aceea evaluarea unei
expresii n forma polonez se face parcurgnd ntr-un singur sens expresia i executnd operaiile
innd seama de paritatea lor.
Denirea recursiv a expresiilor n forma polonez (f.p.) este urmtoarea:
1) Pentru orice operand (constant sau variabil)
2) Dac
E opE
1 i E 2
2 , f.p.
E, E
0 0
0
a expresiei este E 1 E 2 op unde E 1
20 sunt
Obs.
0;
Scrieti un program C (C++) care s rezolve problema evalurii unei expresii date n forma
prexat.
57
Implementri de cozi
head :
tail :
head = tail.
put
nseamn:
get
nseamn:
ntoarce V[head];
incrementeaz head.
Se observ c adugri i tergeri repetate n coad deplaseaz coninutul cozii la dreapta, fa de
nceputul vectorului. Pentru a evita acest lucru ar trebui ca operaia
cozii cu o poziie. Primul element care urmeaz a eliminat din coad va ntotdeauna pe prima poziie,
indicatorul
head
pierzndu-i utilitatea.
Notaii:
Q : coada;
Q.vect : vectorul n care sunt memorate elementele cozii;
Q.head : indicele elementului ce va scos din coad la urmtoarea operaie get;
Q.tail : indicele (poziia) n care va memorat urmtorul element adugat la coad.
Condiia coad vid este Q.head=Q.tail.
Declaraiile in C++ pentru o astfel de coad vor urmtoarele:
struct Queue{
int head,tail;
Atom vect[DIMMAX]; };
void initQueue(Queue& Q);
void put(Queue& Q, Atom a);
Atom get(Queue& Q);
Atom front(Queue& Q);
int isEmpty(Queue& Q);
Operaiile specice cozilor ordonate liniare pot descrise n pseudocod astfel:
PUT(Q,a)
END
GET(Q)
IF Q.head=Q.tail THEN
eroare (Coad vid);
ELSE
Q.head Q.head+1;
get
58
return Q.vect[Q.head-1];
END_IF
END
FRONT(Q)
IF Q.head=0 THEN
eroare(Coad vid);
ELSE
return data(Q.head);
END_IF
END
ISEMPTY(Q)
return (Q.head=c.tail);
END
head
tail,
NextPoz(int index)
END
unde
DimVector este
head
tail
sau aa:
5
head
head=tail.
head
sau, dac:
tail
tail=DimVector.
q
tail
tail+1=head
q
head
tail
head=1
59
NextPoz(tail)=head
DimMax pot
memorate
Q.head=1 i Q.tail=DImMax;
Q.tail+1=Q.head.
Condiia Q.head=inc(Q.tail) reunete
a)
b)
situaiile a) i b).
PUT
GET:
PUT(Q,a)
IF Q.head=inc(Q.tail) THEN
eroare(Coad plin);
ELSE
Q.vect[Q.tail] a;
Q.tail inc(Q.tail);
END_IF
END
GET(Q)
IF Q.head=Q.tail THEN
eroare(Coad vid);
ELSE
a Q.vect[Q.head];
Q.head inc(Q.head);
return(a)
END_IF
END
restricionate corespunztor.
a
head
tail
nil
indicatori
(pointeri):
head :
tail :
head=tail=nil.
head.
iniial: head=tail=nil;
nal: coad cu un element.
tail,
nil
tail
q
Notaii:
Q.head : pointer
Q.tail : pointer
Q : coada.
head, ct
tail.
head=0.
struct Element{
Atom data;
Element* succ;
};
struct Queue{
Element* head,tail;
};
struct Queue{
int head,tail;
Atom vect[DIMMAX]; };
void initQueue(Queue& Q);
void put(Queue& Q, Atom a);
Atom get(Queue& Q);
Atom front(Queue Q);
int isEmpty(Queue Q);
Operaiile cozii nlnuite vor urmtoarele:
PUT(Q,a)
p get_sp();
data(p) a;
succ(p) 0;
IF Q.head=0 THEN
Q.head p;
Q.tail p;
ELSE
succ(Q.tail) p;
Q.tail p;
END_IF
END
GET(Q,a)
IF Q.head=0 THEN
eroare(Coad vid);
ELSE
p Q.head;
Q.head succ(Q.head);
60
61
free_sp(p);
return(a);
END_IF
END
FRONT(Q)
IF Q.head=0 THEN
eroare(Coad vid);
ELSE
return data(Q.head);
END_IF
END
ISEMPTY(Q)
return(Q.head=0);
END
Exist aici un element de redundan: ar convenabil s nu mai avem spaiu suplimentar de memorare, ci s avem un singur pointer ca s putem manevra coada. De aceea, apar utile cozile nlnuite
circulare.
primul
q
...
tail
ultimul
q
Fie:
succ(Q) :
PUT(Q,a)
p get_sp();
data(p) a;
IF Q=0 THEN
Q p;
succ(Q) p;
ELSE
succ(p) succ(Q);
succ(Q) p;
Q p;
END_IF
END
GET(Q)
62
return(a);
ELSE
p succ(Q);
succ(Q) succ(p);
a data(p);
free_sp(p);
return(a);
END_IF
END_IF
END
FRONT(Q)
IF Q=0 THEN
eroare(Coad vid);
ELSE
return data(succ(Q));
END_IF
END
ISEMPTY(Q)
return(Q=0);
END
8.6
Exerciiu
Denim domeniu ca ind o zon din ecranul grac care conine pixeli nvecinai direct sau indirect, pe
vertical sau orizontal i care au aceeai culoare.
S se scrie un program C/C++ care schimb culoarea unui domeniu, pornind de la un pixel oarecare
din acel domeniu.