Sunteți pe pagina 1din 191

Cuprins volumul II

Teme de specialitate pentru concursuri in informatica si


grade didactice
CONŢINUTUL PROGRAMEI
5.Programare dinamica……………………………………………….3
6. Implementarea metodelor numerice
- rezolvarea ecuaţiilor algebrice şi transcendente (metodele bisecţiei, coardei şi
tangentei) ……………………………………………………………….13
- rezolvarea sistemelor de ecuaţii liniare (Gauss, Jacobi)
…………………………………………………………………………..9
7. Alocarea dinamică a memoriei
- tipuri specifice alocării dinamice a
memoriei……………………………………………………………….21
- structuri de date implementate dinamic (lista simplu şi dublu înlănţuită, stiva, coada,
arbore binar, arbore binar de căutare, operaţii specifice – creare, inserare, ştergere,
parcurgere, căutare) …………………………………………………….23
8. Teoria grafurilor
- definiţie, metode de
reprezentare………………………………………………………………62
- noţiunea de graf parţial, subgraf, lanţ, drum, ciclu,
circuit…………………………………………………………………….64
- parcurgerea grafurilor (parcurgerea în lăţime şi în adâncime)
……………………………………………………………………………81
- conexitate/tare conexitate, determinarea componentelor conexe/tare
conexe……………………………………………………………………83
- drumuri minime şi maxime (algoritmii Dijkstra şi Roy-Floyd)
……………………………………………………………………………88
- grafuri euleriene şi
hamiltoniene………………………………………………………………97
- arbori, arbori parţiali de cost
minim…………………………………………………………………….100
- arbori cu rădăcină: metode specifice de reprezentare în memorie. Arbori
binari…………………………………………………………………….105
9. Baze de date
- definirea bazei de date………………………………………………….122
- clasificarea bazelor de date (modelul relaţional, modelul reţea, modelul ierarhic)
……………………………………………………………………………124
- prezentarea conceptelor de bază ale unui sistem de gestiune a bazelor de
date……………………………………………………………………….126
- operaţii specifice prelucrării bazelor de date (creare, adăugare, modificare, ştergere,
sortare, căutare, vizualizare, interogare)
…………………………………………………………………………….140
- relaţii între baze de date…………………………………………………..174
10. Noţiuni de birotică
- editor de text (Microsoft Word)
- editor de foi de calcul (Microsoft Excel)
- editor prezentări (Microsoft PowerPoint)
11. Reţele. Internet

1
- reţele de calculatoare, clasificarea reţelelor, protocoale de reţea (noţiuni generale)
………………………………………………………………………..178
- reţeaua Internet – descriere generală, adresarea în
Internet………………………………………………………………..180
- (*) serviciile reţelei Internet (transferarea fişierelor prin ftp, poşta electronică, www,
telnet) …………………………………………………………………182
- (*) căutarea informaţiei pe Internet – motoare de
căutare…………………………………………………………………188

Recenzie,
Cartea este destinată concursurilor de titularizare si grade didactice din
invatamânt,management educational cu sectiunea IT dar si elevilor sau
studenţilor din perspectiva examenului de bacalaureat sau olimpiadelor
scolare,respectând in totalitate programa şcolara in acest sens.Salutăm aparitia
celui de al doilea volum ,care prin completitudinea expunerii matematice si
informatice este un suficient material pentru concursurile scolare.Cartea a fost
perfect conceputa cu multa trudă in prelucrarea materialului de oameni cu
experienta cum ar fi prof.Bogdan P.Constantin,Col.Nat.”Tudor
Vladimirescu”,Tg-Jiu,prof. Ion Săceanu,director adj.Colegiu Tehnic Matasari.
05.01.2007
Prof.univ.dr Octavian Dogaru,Universitatea din Timisoara

Referenti ştiintifici:
Prof.univ.dr Ion Vladimirescu Rector ,Universitatea din Craiova
Prof.univ.dr Octavian Dogaru,Universitatea din Timisoara
Prof.univ.dr Udrişte Constantin ,Universitatea PolitehnicaBucuresti
Conf.univ.dr Constantin Lupşoiu ,Universitatea din Craiova
Prof.Drd.Dan Dorin Taşcău,Director Colegiul National “Tudor
Vladimirescu”,TG-JIu
Prof.Tăculescu Violeta, Colegiul National “Tudor Vladimirescu”,TG-JIu

PROGRAMARE DINAMICA(pentru Gradul II)

2
Alături de Greedy,programarea dinamica este o tehnica ce conduce, de cele mai
multe ori, la un timp de calcul polinomial.Mai mult, ea furnizează in totdeauna soluţia
optima .Din nefericire, programarea dinamica nu se poate aplica tuturor problemelor, ci
numai care îndeplinesc anumite condiţii.
Se considera o problema in care rezultatul se obţine ca urmare a unui sir de decizii D1,
D2,......Dn. In urma deciziei D1 sistemul evoluează din starea S0 in starea S1,in urma
deciziei D2 sistemul evoluează din starea S1 in starea S2,....,in urma deciziei Dn
sistemul evoluează din starea Sn-1 in starea Sn.
Daca D1, D2,....Dn este un sir de decizii care conduce sistemul in mod optim din S0 in
Sn,atunci trebuie îndeplinita una din condiţiile următoare (principiul de optimalitate):
1)Dk...Dn este un sir de decizii ce conduce optim sistemul din starea Sk-1 in starea
Sn,Ak,1<=k<=n;
2)D1....Dk este un sir de decizii ce conduce optim sistemul din starea S0 in starea
Dk,Ak,1<=K<=n;
3)Dk+1...Dn,D1...Dk sunt şiruri de decizii care conduc optim sistemul starea Sk in starea
Sn, respectiv din starea D0 in starea Sk,Ak,1<=k<=n.
=>Daca principiul de optimalitate se verifica in forma 1,spunem ca se aplica programarea
dinamica metoda înainte.
=>Daca principul de oplimalitate se verifica in forma 2, spunem ca se aplica programarea
dinamica înapoi.
=>Daca principiul de optimalitate se verifica in forma 3, spunem ca se aplica programarea
dinamica metoda mixta.
Programarea dinamica se poate aplica problemelor la care optimul general implica optimul
parţial.
Faptul ca optimul general determina optimul parţial, nu înseamnă ca optimul parţial determina
optimul general.
cu toate acestea, faptul ca optimul general impune optimul parţial ne este de mare
ajutor:căutam optimul general,intre optimele parţiale, pe care le reţinem la fiecare pas.
Oricum,căutarea se reduce considerabil.
Problema triunghiului. Se considera un triunghi de numere naturale format din n linii.
Prima linie conţine un număr,a doua numere,........ultima n numere naturale. Cu ajutorul
acestui triunghi se pot forma sume de numere naturale in felul următor:
-se porneşte cu numărul din linia unu;
-succesorul unui număr se afla pe linia următoare plasat sub el(acees coloana) sau pe
diagonala la dreapta(coloana creste cu 1).
Care este cea mai mare suma care se poate forma astfel si care sunt numerele care o
alcătuiesc:
Exemplu:n=4;
2
3 5
6 3 4
5 6 1 4
Se pot forma mai multe sume:
S1=2+3+6+5=16;
S2=2+5+4+1=12;
Sk=2+3+6+6=17 (care sete[i suma maxim').
Sa observam ca se pot forma 2 la puterea n-1 sume de acest fel.A le lua in considerare pe
toate pentru a găsi valoarea maxima nu este eficient.
Pentru etapa i se tratează linia i a triunghiului. Fie un sir de n numere care respecta condiţiile
problemei si care formează suma maxima. In acest sir,consideram numărul care a fost preluat
de pe linia i. Numerele intre i+1 si n,formează o suma maxima in raport cu sumele care se pot
forma începând cu numărul preluat de pe linia i,contrar,se contrazice ipoteza. In aceasta
situaţie se poate aplica programarea dinamica,metoda înainte.

3
Vom forma un triunghi,de la baza către vârf,cu sumele maxime care se pot forma cu fiecare
numar.Daca am citit triunghiul de numere intr-o matrice T si calculam sumele intr-o matrice C
vom avea relaţiile următoare:
C[n][1]:=T[n][1];
C[n][2]:=T[n][2];
C[n][n]:=T[n][n];
Pentru linia i (i<n), cele i sume maxime care se obţin astfel:
C[i][j]=max{T[i][j]+C[i+1][j],T[i][j]+C[i+1][j+1]},i apartine mulţimii {1,2,....,n-1) iar j aparţine
mulţimii {1,.....,i}.
Sa rezolvam problema propusa ca exemplu:
Linia 4 a matricei C va fi linia n a matricei T:5 6 1 4;
Linia 3 se calculează astfel:
C[3][1]=max{6+5,6+6}=12;
C[3][2]=max{3+6,3+1}=9;
C[3][3]=max{4+1,4+4}=8;
Linia 2:
C[2][1]=max{3+12,3+9}=15;
C[2][3]=max{5+9,5+8}=14;
Linia 1
C[1][1]=max{2+15,2+14}=17.
Aceasta este si cea mai mare suma care se poate forma.
Pentru a tipări numerele luate in calcul se foloseşte o matrice numita DRUM in care pentru
fiecare i aparţinând mulţimii mai sus menţionate si j la fel aparţinând mulţimii menţionate mai
sus se retine coloana in care se găseşte succesorul lui T[i][j].

{Fie un triunghi care are pe prima linie un număr pe a doua doua ....
Sa se calculeze cea mai mare dintre sumele ce apare drumurile ce pleacă
din vârf si ajung la baza}
const dimmax=100;
type numar=0..9;
var c:array[1..dimmax,1..dimmax] of numar;
t,cc:array[1..dimmax,1..dimmax] of numar;
d,n,i,j:integer;
begin
writeln('cite linii avem in triunghi ');readln(n);
for i:=1 to n do
for j:=1 to i do
begin
writeln('t[',i,',',j,' ]=');
readln(t[i,j]);
end;
for i:=1 to n do
begin
cc[n,j]:=j;
c[n,j]:=t[n,j];
end;
for i:=n-1 downto 1 do
for j:=1 to i do
if c[i+1,j]+t[i,j]>c[i+1,j+1]+t[i,j]
then
begin
cc[i,j]:=j;
c[i,j]:=c[i+1,j]+t[i,j];
end
else
begin
cc[i,j]:=j+1;
c[i,j]:=c[i+1,j+1]+t[i,j] ;

4
end;
writeln('suma este ',c[1,1]);
d:=cc[1,1];
writeln(1);
for i:=1 to n-1 do
begin
writeln(cc[i,d]);
d:=cc[i,d];
end;
readln;
end.

Subsir crescător de lungime maxima. Se considera un vector cu n elementeintregi.Se cere


sa se tipărească cel mai lung subsir crescător al acestuia.
Exemplu:Pentru n=5 se da V=(4,1,7,6,7).In acest caz subsirul tipărit va fi :4,7,7.
Problema se poate rezolva pornind de la idee a de a calcula ,pentru fiecare element al
vectorului lungimea celui mai lung subsir crescător care se poate forma începând cu el. In final
este selectat elementul din vector cu care se poate forma cel mai lung subsir crescător si
acesta este listat,
L(k)={1+max L{i}/V{i}>=V(k). i aparţine mulţimii {k+1,...,n} iar k apartine mulţimii {1,2,....,n}.
In practica,folosim un vector L cu n componente,unde L(k) are semnificaţia explicata. Pentru
examenul nostru vom avea:
L=(3,3,2,2,1).
Componentele vectorului L au fost calculate astfel:
-cel mai lung subsir care se poate forma cu elementul 7,aflat pe ultima poziţie,are lungimea 1;
-cel mai lung subsir care se poate forma cu elementul 6 aflat pe poziţia 4 are lungimea
(1+L(5)), pentru ca pe poziţia 5 se găseşte elementul 7 care este mai mare decât 6;
-cel mai lung subsir care se poate forma cu elementul aflat pe poziţia 3 are lungimea2(1+L(5))
pentru ca 7 este egal cu 7;
-algoritmul continua in acest mod pana se completeaza L(1).
După aceasta se calculează maximul dintre componentele lui L,iar cel mai lung subsir
crescator format din elementele vectorului V va avea lungimea data pe acest maxim. Pentru a
lista efectiv acel subsir de lungime maximala se procedează astfel:
-se caută maximul din vectorul L precum si indicele t,la care se găseşte acest maxim;
-se afişează V(t);
-se găseşte si se listează primul element care este mai mare sau egal cu V(t) si are lungimea
mai mica cu 1(max-1), se actualizează valoarea max cu max-1;
-algoritmul continua pana când se epuizeaza toate elementele subsirului.

{Sa se calculeze cit e lungimea unui subsir crescator al unui sir initial
in cazul in care este maxima}
var v:array[0..20] of integer;
n,i:integer;
function lungime(k:integer):integer;
var max,i:integer;
begin
if k=n then lungime:=1 else
begin
max:=0;
for i:=K+1 to n do
if (max<lungime(i)) and (v[i]>=v[k]) then
max:=lungime(i);
Lungime:=max+1;
end;
end;

5
begin
write('cite elemente are sirul ');readln(n);
v[0]:=0;
for i:=1 to n do
begin
writeln('v[',i,']=');
readln(v[i]);
end;
writeln(' lungimea maxima este ',lungime(0)-1);
readln;
end.

Înmulţirea optima a unui sir de matrice


Presupunem ca avem inmultiti doua matrice:An,p cu Bp,m.In mod evident, rezultatul
va fi o matrice Cn,m.Se pune problema de a afla cate înmulţiri au fost făcute pentru a obţine
matricea C. Prin înmulţirea liniei 1 cu coloana 1 se fac p înmulţiri, întrucât au p elemente. Dar
linia 1 se inmulteste cu toate cele m coloane, deci se fac m*p inmultiri.In mod analog se
procedează cu toate cele n linii ale matricei A,deci se fac n*m*p inmultiri.Retinem acest
rezultat.

Sa consideram produsul de matrice A1xA2x....xAn (A1(d1,d2),A2(d2,d3)...,An(dn,dn+1)).Se


cunoaşte ca legea de compoziţie produs de matrice nu este comutativa in schimb este
asociativa. De exemplu ,daca avem de înmulţit trei matrice A,B,C produsul se poate face in
doua moduri:(A x B) x C; A x(B x C).Este interesant de observat ca nu este indiferent modul de
înmulţire a celor n matrice. Sa considera ca avem de înmulţit patru matrice
A1(10,1),A2(1,10),A3(10,1),A4(1,10).
Pentru înmulţirea lui A1 cu A2 se fac 100 de înmulţiri si se obţine o matrice cu 10 lini si 10
coloane. Prin înmulţirea acesteia cu A3 se fac 100 de înmulţiri si se obţine o matrice cu 10 linii
si o coloana.Daca aceasta matrice se inmulteste cu A4 se fac 100 înmulţiri. In concluzie, daca
acest produs se efectuează in ordine naturala,se efectuează 300 înmulţiri.
Sa efectuam acelaşi produs in ordinea care rezulta din expresia A1x((A2XA3) x A4).Efectuând
produsul A2 cu A3 se efectuează 10 înmulţiri si se obţine o matrice cu o linie si cu o coloana.
Aceasta matrice se inmulteste cu A4 se fac 10 înmulţiri si se obţine o matrice cu 1 linie si 10
coloane. Daca o înmulţim pe aceasta cu prima, efectuam 100 inmultiri , obţinând rezultatul
final cu numai 120 de înmulţiri.
In concluzie,apare o problema foarte interesanta si anume de a afla modul in care trebuie sa
se inmulteasca cele n matrice,astfel incat nr de înmulţiri sa fie minim.Pt rezolvare vom aplica
principiul 3 al programări dinamice.

In vederea rezolvării problemei,reţinem o matrice A cu n linii si n coloane. Elementul A(i,j)


i<j,reprezinta nr minim de înmulţiri pt. efectuarea produsului Ai x Ai + 1 x....x Aj.De
asemenea,nr. liniilor si al coloanelor celor n matrice sunt reţinute intr-un vector DIM cu n+1
componente.Pt exemplu nostru DIM retine următoarele valori:10,1,10,1,10.
Pt. rezolvare se tine cont de următoarele relaţii existente intre componentele matricei A:
1)A(i,i)=0;
2)A(i,i+1)=DIM(i) x DIM (i+1) x DIM(i+2);
3)A(i,j)=min { A(i,k)+A(k+1,j)+DIM(i) x DIM(k+1)x DIM(j+1)}.
i<=k<j
Justificarea acestor relatii este următoarea:
1)o matrice nu se inmulteste cu ea insasi,deci se efectuează 0 înmulţiri;
2)liniile si coloanele matricei A1 se găsesc in vectorul DIM pe poziţiile i si i+1, iar ale matricei
Ai+1-pe poziţiile i+1 si i+2;
3)
-inmultind matricele Ai x Ai+1 x Ak se obţine o matrice cu un nr. de linii egal cu acela al
matricei Ai (DIM(i)) si cu un nr. de coloane egal cu acela al matricei Ak (DIM(k+1));

6
-inmultind matricele Ak+1 x.....x Aj se obţine o matrice cu un nr. de linii egal cu acela al
matricei Ak+1 (DIM(k+1)) si cu un nr. de coloane egal cu acela al matricei Aj (DIM(j+1));
-prin înmulţirea celor doua matrice se obţine matricea rezultat al înmulţirii Ai x....x Aj, iar pt.
aceasta înmulţire de matrice se efectuează DIM(i) x DIM(k+1) x DIM(j+1) înmulţiri;
~Relaţia sintetizează faptul ca pt. a obţine nr. de înmulţiri optim pt. produsul Ai x....x Aj se
înmulţesc doua matrice, una obţinuta ca produs optim intre Ai x....x Ak si cealalalta obţinuta ca
produs optim intre Ak+1 x....x Aj, in ipoteza in care cunoaştem nr. de înmulţiri necesar
efectuării acestor doua produse oricare ar fi k, cuprins intre limitele date.
~Aceasta observaţie este o consecinţa directa a programării dinamice si anume ca produsul
efectuat optim intre matricele prezentate se reduce in ultima instanţa la a efectua un produs
intre 2 matrice cu condiţia ca acestea sa fie calculate optim(produsul lor sa aiba un număr
minim de înmulţiri).
Se pune problema cum putem efectua acest calcul utilizând relaţiile prezentate. Pentru
exemplificare vom utiliza exemplul dat la începutul acestui capitol. Datorita relaţiei 1, diagonala
pricipala a maricei A( cu 4 lini si 4 coloane) va fi alcătuita numai din elemente având valoarea
0. s
Iniţial se pot calcula numai elemente A(i,i+1),adică A(1,2),A(2,3),A(3,4)-elemente situate pe o
paralela la digonala principala a matricei A.Este cazul sa observam ca porţiunea din matrice
situata sub diagonala principala este neutilizata.In concluzie,avem
A(1,2)=100,A(2,3)=10,A(3,4)=100.Matricea A va arata astfel:

0 100 x x
x 0 10 x
A= x x 0 100
x x x 0

In continuare calculam:
A(1,3)=min{A(1,k)+A(k+1,3)+DIM(1)*DIM(k+1)*DIM(4)}=min{0+10+10*1*1,100+0+10*10*1}=20
A(2,4)=min{A(2,k)+A(k+1,4)+DIM(2)*DIM(k+1)*DIM(5)}=min{0+100+1*10*10,10+0+1*1*10}=20
A(1,4)=min{A(1,k)
+A(k+1,4)+DIM(1)*DIM(K+1)*DIM(5)}=min{0+20+10*1*10,100+100+10*10,20+0+10*1*10}=12
0;

.
0 100 20 120
x 0 10 20
A= x x 0 100
x x x 0

In concluzie,pt. exemplul nostru, se fac minim 120 de înmulţiri,rezultat luat din matricea A si
anume A(1,4).
var k:integer;
{Prin programare dinamica sa se determine numarul begin
minim de inmultiri care sa se faca if i<j then begin
cind se dau dimensiunile matricelor k:=m[j,i];
ex:n=4 if i<>k then begin
10 1 10 1 10} write('(');
paranteze(i,k);
program inm_optima; write(')');
const nmax=20; end
type vector=array[1..nmax] of word; else paranteze(i,k);
tabl=array[1..nmax,1..nmax] of word; write('x');
var p:vector; if k+1<>j then begin
m:tabl;n,i,j,k,imin:integer;min,v:word; write('(');
procedure paranteze(i,j:integer); paranteze(k+1,j);

7
write(')') begin
end v:=m[i,k]+m[k+1,j]+p[i]*p[k+1]*p[j+1];
else paranteze(k+1,j); if min>v then begin
end min:=v;
else write('A',i) imin:=k
end; end;
begin end;
write('Nr. de matrici:'); m[i,j]:=min;
readln(n); m[j,i]:=imin;
writeln('Dimensiuni matricelor:'); end;
for i:=1 to n+1 do read(p[i]); writeln('Numarul minim de inmultiri este:',m[1,n]);
for i:=n downto 1 do writeln('Aceasta se obtine pentru urmatoarea ordine
for j:=i+1 to n do a inmultirilor');
begin paranteze(1,n);
min:=m[i,i]+m[i+1,j]+p[i]*p[i+1]*p[j+1]; readln;
imin:=i; end.
for k:=i+1 to j-1 do

6.Implementarea metodelor numerice


6.2 Rezolvarea sistemelor de ecuatii
liniare

6.2.1 Metoda Jacobi


Fie sistemul A x=b ,n ecuatii cu n necunoscute , compatibil determinat A=aij € Mn (R)
B=bi.
Fie

( )
a11……………..0

( )
. . . 0……………0
N=D= , L= a12 .
. . . . .
. . .
0……….....ann an1……..ann-1.0

)
0 a12…………a1n

(
. . .
R= . . .
. an-1n
0………………0

P=N-A=-(L+R)=>A=N-P
Ax=b => Nx(K+1)=Px (K) +b , dorind sa aploximam solutia sistemului printr-un
termen al lui xk.

X(k+1)=N -1 * P * x(k)+N -1 *b deci xi (k+1) =1/aii *(bi- ∑a xij j (k)


) ,i=1..n, k€N.
J=1
J<>i

OBS :

( ) -( )
A=L+D+R a11……………..0 a11……………..a1n
P=N-A= . . . . . .
. . .
. . . . . .
. . . an1……….....ann
0……….....ann
-(aij) , j<>i

8
=
aii=0

Fie G=N -1 *P=D-1*(L+R)

G=N -1 *(N-A)=N -1 *N- N -1 * A rezulta gij=√ij - aij/aii , i,j=1,n


OBS :

X (k+1) =N -1 *P*x (k) +N -1 *b, G, ma intereseaza norma lui si pun conditiile |g ij|<1 rezulta
n
∑aij >1 <= >∑|aii/aij|<1 = >||G||=max ∑|gij|=max ∑|aij/aii|<1
=>|aij|/
j=1 j=1 1≤i≤n ; j=1 j=1
j<>i j<>i j<>i

p→∞
Cum||G||<1=>||G||p 0

||x (m+1) -x (m) ||=||G(x (m) -x (m-1) ||=…=||G (m) || || (x (1) -x(0) )||
si deci cum
||x (k+p) -x (k) ||=|x (k+p) -x (k+p-1) +x (k+p-1) -x (k+p-2) +...-x (k) ||≤
≤||x (k+p) -x (k+p-1) ||+||x (k+p-1) -x (k+p-2) ||+...+)||+||x (k+p-1) -x (k+p-2) ||+...+||x (k+1) -
-x ( k) || ≤||G|| k+p-1 *||x (1) -x^ (0) ||+...||G|| k *||x (-1) -x (0) ||=
=(||G|| k+p-1 +...||G|| k )*||x (1) -x (0) ||=||G|| k *(1-||G|| p /(1-||G||)*||x (1) -x (0) ||
deci , cand p→∞ ||x (k+p) -x (k) || ≤ ||G|| (k) * (1-||G|| (p) )/1-||G||) * ||x (1) -x (0) || rezulta
||x-x (k) ||<||G|| k * 1 / (1-||G||)*||x (1 ) -x (0) ||

PROGRAM JACOBI ;
Const max=10 ;
Type vector=array[1..10] of real;
Var x,b:vector; a:array[1..10,1..10]of real;
n,i:integer;
function rezolva (nit:integer :boolean;
var y:vector;c,j,k:integer; v:real; g:boolean;
function ZERO:Boolean;
var L,m:integer ; t:real;
begin
zero:=false;
L:=j;
While (l<n) and (a[I,j]=0 do L:=L+1
If (a[L,j]<>0 then zero:=true;
end;

begin
g:=true;i:=0;
repeat
for j:=1 to n do
if zero and g then
begin
y[j]:=x[j];v:=0;
for k:=1 to n do
if j<>k thenn v:=v +a[i,k]*y[k];
x[j]:=(=b[j]-v)/a[I,j]);
end
else g:=false;
v:=0;
i:=i+1;

9
for k:=1 to n do
v:=v + sqr(x[k]-y[k]);
until (sqrt(v),1.e-6) or (i>nit) or not g;
end;
rezolva:=g and (i<= nit);
end;
begin
citesc pe n, a[i,j], b[i]
for i:=1 to n do x[i]:=1;
if NOT rezolva (200) then writeln (‘incompatibil’)
else
begin writeln(‘solutia sistemului este’)
write(‘x=c’);
for i:=1 to n-1 do write (x[i]);
end;
end.

6.2.2 Metode directe de rezolvare a sistemelor de ecuatii liniare


(GAUSS)
Ax=b , A€R (nxn) , b €r^n
Etapa1)triangularizarea marticei asociate sistemului (sub diagonala principala am 0)
Etapa2)rezolvam sistemul asociat matrice rerultate

ETAPA1
Triangulizarea se face la randul ei intr-un numar finit de etape optinand de sirul martice
( 1) (2) (n)

A =A ; A ,...,A unde

( )
(k) (k) (k) (k) (k)
a11 a12…………….a1 k-1 a 1 k………………….a 1n
(k) (k) (k) (k)
0 a22…… ……....a 2 k-1 a 2 k…………………..a 2 n
………………………………………………………………………….
A= (k) (k) (k)
( k)
0 0………….ak-1k-1 ak-1k………………….ak-1n
akk≠0 (k) (k)
0 0……………..0 akk …………………….akn
…………………………………………………………………………
(k) (k)
0 0……………..0 ank…………………….ann

( )
1 0………0 0…………0
0 1………0 0…………0
Fie M= ……………………….………..
0 0………-mk+1 k 1…………0
………………………………..
0 0………-mn k 0…………1

(k) (k)
Mik=aik/akk , k+1≤i≤n
(k+1) (k)
A =Mk * A

10
(K+1) (k)
aij = aij ,1≤j≤n ,i≤j≤n =>primele k linii raman necunoscute in matrice
0 ,i≤j≤k , j+1≤i≤n=>primele j coloane de sub diagonala principala sub zero
(k) (k) (k) (k) (k) (k) (k) (k) (k) (k) (k)
aij -mik * akj = aij-aik / akk* akj=(aij * akk- akk * aik)/akk , i≥k+1

j≤n
j>i≥k+1
elementele situate in liniile
si coloanele k+1,k+2,k+3
….n se schimba dupa regula
dreptunghiului
(k) (k)
k……akk………akj………….
(k) (k)
i…….aik………aij…………..

( )
1 -1 2
2 1 1 (1) (1) (1) (1)
A= 1 2 -1 ,A=A , a 11=1 , m2 1=(a2 1)/a11=2/1=2
(1)
m31=a31=1/1=1

ETAPA2 forma matricei : diagonale care se va obtine va arata astfel :

c1

( ) ( )
r11 r12 r13…….r1n .
0 r22 r23………..r2n .
R= ………………………… ,,, ,termenii liberi c = .
0 0 0………….rnn .
.
cn

( )
Y1
Sistemul devine Ry=c ,y= .
.
.
OBS : yn

R se obtine din prelucrarea matricei extrase (A,b) unde coloana n+1 care este ocupata de b sei
prelucreaza la fel ca celelalte componente.
Vectorul de solutii finale ale sistemului adica y se obtine dupa formele :
-yn=c / rnn
n
-yi=(ci - ∑ r ik * y k)/r ii, i=n-1,n-2,...,1.
k=i+1

Program sistem ;
Type matrice=array[1..10,1..10] of real ;
Var a:matrice;
b,x:vector;
i,iv,j,k,l:integer;
temp:real;

11
t:boolean;
BEGIN
Citesc pe n,aij,bi
For j:1 to n-1 do begin
iv:=j;
t:=true;
while (iv<=n) and t do
if a[iv,j]=0 then iv:=iv+1
else t:=false;
if t then begin
writeln(‘determinatul sistemului nul’);
end;
if (j<>iv) then begin
for k:=j to ndo begin
temp:=a[j,k];
a[[j,k]:=a[iv,k];
a[iv,k]:=Temp;
end;
temp:=b[j];
b[j]:=b[iv];
b[iv]:=temp;
end;
for l:=j+1 to n do begin
for k:=j+1 to n do
a[l,k]:=a[l,k]-a[j,k]*a[l,j]/a[j,j];
b[l]:=b[l]-b[j]*a[l,j]/z[j,j];
end;
end;
if a[n,n]=0 then begin
writeln)’determinantul principal nul’);
exit;
end;
x[n]:=b[n]/a[n,n];
for i:=n-1 downto 1do begin
temp:=b[i];
for j:=i+1 to n do temp:=temp-a[I,j]*x[j];
x[i]:=temp/a[i,i];
nd;
for i:=1 to n do
writeln(x[i]);
readln;
end.

6.1 Rezolvarea ecuatiilor transcendente si algebrice


Ecuatiile algebrice sunt de forma
n n-1
a0 x +a1 x +…+an-1 x + an=0, ai€R

Fie P un polinom si polinoamele :


P0=P,P1=P1,...,PK-1=PK-1*QK-PK+1.1≤k≤m-1,Pk+1este restul impartirii lui Pk-1 la Pk cu semn schimbat.
DEFINITIE :Sunt P0,P1,...,Pm se numeste sirul lui Sturm.
N(c)=numarul variatiilor de semn pentru x=c din sirul lui Sturm ,elementele nule fiind eliminate.
TEOREMA
Fie a,b ,din R,a<b.Daca Pm are radacini multiple si a,b nu sunt radacini ale plinomului P, atunci numarul
radacinilor ecuatiei P(x)=0 situate in intervalul (a,) este N(a)-N(b).

Fie N-numarul variatiilor de semn din subsirul obtinut prin eliminarea elementelor nule

12
N-numarul variatiilor de semn din subsirul obtinut prin inlocuirea elementelor nule dupa
algoritmul :
Ck-1≠0, Ck=Ck+1=...=Ck+L-1=0,Ck+L≠0
Inlocuit cu
l+i
C* k+i=(-1) sgn(Ck+l),i€[0,L-1];
Teorema Budan Founci,a<b€R,care nu sunt radacini ale lui P .
,Numarul radacinilor reale ale lui P din intervalul (a,b) este N(a)- N(b) sau interior acestuia cu un numar
par .

APROXIMAREA FUNCTIILOR PRIN INTERPOLARE

DEFINITIE
 
Se numeste polinom de interpolare al functiei f pe nodurile x1,...xn, un polinom P cu
proprietatile :gr(p)≤n-1,p(xi)=yi,1≤i≤n unde f :[a,b]→R, f(xi)=yi ,xi€[a,b],1≤i≤n.

Teorema : Polinomul de interpolare al functiei f pe nodurile x1,..,xn exista si este unic.


Demonstrati :
x x
Gr(p) ≤n-1, p(x)=a0+a1 +...+an-1 n-1, p(xi)=yi,1≤i≤n
Sistemul n ecuatii cu n necunoscute ai ,1≤i≤n, ai unuc determinanti neomogen cu

n-1
1 x1......x1
D= .................. =∏(xi-xj)≠0,1≤j≤i≤n are solutii unice
n-1
1 xn.......xn n-1

n-1 n-1
a0+a1 xk+…an-1 * xk =f(xk) a0+a1 xk+…+an-1 xk +an f(xn)=0
n-1 n-1
a0+a1 x +…+an-1 * x =P(x) a0+a1 x+…+an-1 x +an-1 P(x)=0

system liniar omogen ,an≠0 are n+1 ecuatii si n+1 necunoscute =>determinantul e nul.

n- 1 n-1 n-1
1 x1…..x1 f(x1) 1 x1.....x1 0 1 x 1.....x1 f(x1)
n-1 ................................ ...............................
1 x2…...x2 f(x2) n-1 n-1
……………….. =0 1 xn......xn 0 + 1 xn.....xn f(xn) =0
n-1 n-1 n-1
1 xn……xn f(xn) 1 x......x P(x) 1 x .......x 0
n-1
1 x……x P(x)

n-1 n-1
1 x1......x1 1 x1......x1 f(x1)
P(x)* ..................... + .................... =0 => p(x)=D2/D1.
n-1 n-1
1 xn.......xn 1 xn.......xn f(xn)
n-1
1 x.......x 0

D1
D2

Interpolare Langrange

Fie gk 1≤k≤n polinoame de gradul n-1 pentru care g k(xk)=1,gk(xi)=0,1≤k≤n,i≠k

13
N n

gk(x)=C ∏(x-xi)== ∏(x-xi)/(xk-xi),1≤l≤n


i=1 i=1
i≠k i≠k
n n n

Fie Ln(x)= ∑f(xk)g (x),Ln9xi)= ∑f(xk)*g (xi)= ∑f(xk)* ∂ xi=f(xi)


k k

polinom de interpolare Lagrange


n n
Ln(x)= ∑f(xk)* ∏(x-xi)/(xk-xi)
K=1 i=1

ω(x)= ∏(x-xi)
j=1

program lagrange;
type sir=array[1..100] of real;
var fx,vp,bk:real;
x,y:sir;
n,I,j,m:integer;
begin
readln(n);
n:=n+1;
readln(fx);
for i:=1 to n do
begin
readnl(x[i],y[i]);end;
for i:=1 to n do
begin
bk:=1;
for j:=1 to n do
if i<>j then
bk:=bk *(fx-x[i])/(x[j]-x[i]);
vp:=vp+b[k]*y[i];
end;
write(vp);
end.
Interpolare Newton
Stiu
F<x1,…xn>=(f<X1,…,X m-1>-< f<X2,…,X m>)/(X1-Xm)
P(x)=f(X1)+f(x1,x2) * (x-x1)+…
Program newton;
Var x,y:array[1..100] of integer;
S:real;
Xx,I,j,m:integer;
Begin
Readln(m);
For i:=1 to m do
Read(x[i],y[i]);
For j:=1 to m-1 do
For i:=m downto j+1 do
Y[i]:=(y[i-1]-y[i])/(x[i-j]-x[i]);
For j:=0 to m do
Begin
S:=y[m];

14
For i:=y[i]+(j-x[i]) *s;
Write(s);
End.
METODA BISECTIEI
(INJUMATATIRII),COARDEI,TANGENTEI
METODA INJUMATATIRII

TEOREMA LUI DARBOUX:fie I un interval,f:IR,apre proprietatea


lui Darboux pe intervalul I daca oricare ar fi x1<x2 din intervalul
I,oricare ar fi c din intervalul (f(x1),f(x2)),exista cel putin un
punct x din intevalul (x1,x2) astfel incat f(x)=c
Orice functie continua are proprietatea lui Darboux
F:[a,b]R ,f(x)=0,f continua cu f(a)<0 si f(b)>0.Fie c=(a+b)/2
Definim
-daca f( c )>0 atunci
a1=a
b1=c
sau
-daca f( c )<0 atunci
a1=c
b1=b
Analog construiesc
F:[a1,b1]R, f continua cu f(a1)<0 si f(b1)>0, c1=(a1+b1)/2

Deci cream niste siruri date prin
a0=a,b0=b, c0=(a0+b0)/2
pentru n>0
-daca f( cn )>0 atunci
an=cn-1
bn=bn-1
sau
-daca f( cn )<0 atunci
an=an-1
bn=cn-1
unde cn=( an + bn)/2
oricare ar fi m>=n daca f( cn )=0 atunci

15
am=an-1 bm=bn-1 cm=cn-1
siruri convergente
an -->a bn -->b cn -->c
METODA COARDEI

F:[a,b]R ,f(x)=0,f continua cu f(a)<0 si f(b)>0.Fie c=(a+b)/2


Scriem dreapta care trece prin (a,f(a),(b,f(b))

((y-f(a) )/( f(b)-f(a)=( x-a)) / (b-a)


Ca sa intersecteze OX avem y=0 rezulta

Prin notatia x=c ca avem c=( a*f(b)-b*f(a))/(f(b)-f(a))


Deci construim
A0=a,b0=b, c0=( a0*f(b0)-b0*f(a0))/(f(b0)-f(a0))
Pentru n>0
-daca f( cn-1 )>0 atunci
an=cn-1
bn=bn-1
sau
-daca f( cn-1 )<0 atunci
an=an-1
bn=cn-1
unde cn= cn =( an *f(bn)- bn *f(an))/(f(bn)-f(an))
oricare ar fi m>=n daca f( cn )=0 atunci
am=an-1 bm=bn-1 cm=cn-1

siruri convergente
an -->a bn -->b cn -->c

METODA TANGENTEI(NEWTON)

16
f(x)=0,f ( z-r,z+r)R,exista a>0,b>0 si |f’(x)|>=a, |f’(x)|>=a,x
apartine de I ,f de doua ori derivabila
Tangenta in (xn ,f(xn ) ) este xn+1 = xn + f(xn )/f’(xn )
Pentru ca:
y-f( xn ) =f’( ‫() ع‬x- xn )
cum y=0  xn -x= f(xn )/f’(xn )  x = xn+1 + f(xn )/f’(xn )
{Folosind parametrii de tip functie si procedura sa se rezolve o ecuatie
prin metoda injumatatirii,tangentei si coardei pe un interval dat}
{$f+}
type functie=function(x:real):real;
procedura=procedure(var a,b,x,y:real;f:functie);
var car:char; a,b:real;
function f(x:real):real;
begin
f:=sin(x)-x;end;
procedure injumat(var a,b,x,y:real;f:functie);
begin
x:=(a+b)/2;y:=f(x);end;
procedure coarda(var a,b,x,y:real;f:functie);
begin
x:=a-(b-a)/(f(b)-f(a))*f(a);y:=f(x);end;
procedure tangenta(var a,b,x,y:real;f:functie);
function derivata(f:functie;x0:real):real;
const h=1.e-6;
begin
derivata:=(f(x0+h)-f(x0))/h;end;
begin
x:=x-f(x)/derivata(f,x);y:=f(x);
end;
procedure radacina(f:functie;p:procedura);
const eps=1.e-10;
var epsa,b,x,y:real;i:integer;
begin
write('inceputul intervalui a=');readln(a);
write('sfirsitul intervalui b=');readln(b);
i:=0;
repeat
p(a,b,x,y,f);i:=i+1;
if (f(a)<0)=(y<0) then a:=x else b:=x;
until (abs(a-b)<eps) or (y=0) or (i>200);
if i>200 then write('solutia nu afost gasita in 200 de pasi')
else
writeln('solutia ',x:12:7);
end;

17
begin
writeln('alegeti metoda de rezolvare a ecuatiei ');
write('a=metoda injumatairii intervalului ');
write('b=metoda coardei ');
write('c=metoda tangentei ');
writeln;
write('optiunea');readln(car);
case car of
'a':radacina(f,injumat);
'b':radacina(f,coarda);
'c':radacina(f,tangenta);
else
writeln('varianta eronata ');
end;
readln;
end.

METODE DE CALCUL A INTEGRALELOR(PENTRU


GRADUL II)
{Cu functii pe intervalul[0,1] calculam cu metoda trapezelor,metoda
simpson
si metoda recurenta, integrala din functia f(x,m)=e-x *(x-1)m}
var m,n,i,semn,k:integer;
a,b,h,sum,integr,s1,s2:real;
function f(x:real):real;
var prod:real;
k:integer;
begin
prod:=1;
for k:=1 to m do
prod:=prod*(x-1);
f:=exp(-x)*prod;
end;
begin
write('dati parametrul functiei m=');
readln(m);
write('cate subintervale aveti m=');
readln(n);
a:=0;
b:=1;
h:=(b-a)/n;
sum:=0;
for i:=1 to n-1 do
sum:=sum+f(i*h);
integr:=h*(0.5*(f(a)+f(b))+sum);
writeln('integrala PRIN METODA TRAPEZELOR este ',integr:20:11);
writeln('prin metoda simpson avem integrala ');
if odd(n) then n:=n+1;
s1:=0;
s2:=0;
for i:=1 to n do begin
if i mod 2=0 then s1:=s1+f(i*h) else s2:=s2+f(i*h);
end;
integr:=h*(f(a)+4*s1+2*s2-f(b))/3;
writeln(integr:20:11);
integr:=1-exp(-1);
semn:=1;
for k:=1 to m do begin

18
semn:=-semn;
integr:=semn+k*integr;
end;
writeln('recurent integrala este ',integr:20:11);
readln;
end.
{Sa se calculeze prin formula trapezelor o integrala dintr-o functie}
{$f+}
type ff=function(x:real):real;
var a,b,int:real;n:integer;
function f1(x:real):real;
begin
f1:=sin(ln(x))/x;
end;
procedure tr(a,b:real;f:ff;n:integer;var s:real);
var h:real;i:integer;
begin
h:=(b-a)/n;
s:=(f(a)+f(b))/2;
for i:=1 to n-1 do
s:=s+f(a+i*h);
s:=s*h;
end;
begin
write('a=');readln(a); write('b=');readln(b);write('n=');readln(n);
tr(a,b,f1,n,int);
writeln('integrala este ',int:8:2);
readln;
end.

{Cu functii sa se caculeze pe intervalul [0,pi/2] integrala din


f(x)=(sin(x))^m
cu metoda Simpson}
const n=100;
h:real=1/100;
function ss(m:integer;x:real):real;
var re,si:real;i:integer;
begin
si:=sin(x);
if m=0 then
si:=1
else
if m>0 then
begin
re:=1;
for i:=1 to m do
re:=re*si;
ss:=re
end
else
begin
re:=1;
for i:=m to -1 do
re:=re/si;
ss:=re;
end;
end;
function sim(m:integer):real;
var i:1..n;

19
s1,s2:real;
begin
s1:=0;
s2:=0;
for i:=1 to n div 2 do
begin
s1:=s1+ss(m,(2*i-1)*h);
s2:=s2+ss(m ,2*i*h);end;
sim:=h/3*(ss(m,0)-ss(m,pi/2)+4*s1+2*s2);
end;
var m:integer;
begin
write(' m=');
readln(m);
writeln(' integrala este ',sim(m):20:11);
readln;
end.

7.Alocare dinamica
7.1 Tipuri specifice alocării dinamice a memoriei
Memoria interna poate fi privita ca o succesiune de octeti.Numarul de ordine al unui octet se
numeşte adresa lui. Adresa unei variabile nu trebuie confundata cu valoarea pe care aceasta o
memorează.
Definiţie: Adresa primului octet al variabilei se numeşte adresa variabilei.
Adresele variabilelor se memorează cu ajutorul variabilelor de tip pointer.
Noţiunea de variabila dinamica

Am invatat inca din clasa a IX-a ca o variabila este o entitate caracterizata prin trei
atribute:tip, valoare si adresa .Primele doua
atribute au fost foarte des întâlnite pana acum. Atributul adresa va face obiectul noţiunilor in acest
capitol.
Pentru început ,consideram un exemplu foarte simplu , o variabila x de tipul integer.Declaratia ei
va este cunoscuta:
var x: integer;

Variabila x de mai sus se numeşte variabila statica. O variabila statica se caracterizează prin
faptul ca in momentul declarări ,
compilatorul ii un anumit spaţiu de memorie. Mărimea spaţiului rezervat unei variabile depinde de tipul
acesteia . De exemplu ,pentru
o variabila de tipul integer se aloca 2 octeţi, pentru una de tipul real 6 octeţi .
Variabila x se numeşte “pointer către un întreg” sau”referinţa către un întreg”.Fireşte ca tipul de
date al variabilei x nu va mai
fi integer ci ,un tip de date nou , numit “tipul pointer către un întreg” sau “tipul referinţa către un
întreg “, notat integer .
Declaraţia necesara este: var x:^integer:Pe scurt vom spune ca x este un pointer către un
intreg.Caracterul “ ^ ” se numeşte operatorul
De adresare “săgeata”.
Tipurile de date “pointer către ….” sunt anonime .Un tip pointer poate fi insa denumit ,ca
orice tip anonim, cu cuvântul cheie type.
Exemplu :
Pentru a declare trei pointeri către numere reale ,putem scrie: var x,y,z:^real;

Alocarea si eliberarea dinamica a memoriei


Fie următoarea declaraţie a tipului “pointer către întreg ” : type pint=^integer ;
Alocarea memoriei pentru o variabila dinamica , sau pe scurt alocarea dinamica a memoriei , se
realizează in program ,in

20
momentul utilizării variabilei .Pentru aceasta folosim procedura new, care are doua forme:
new (<pointer>)
<pointer>:=new(<tip>);
unde: - <pointer>→numele (identificatorului) pointerului ;
- <tip>→ tipul pointerului;
Pentru eliberarea memoriei alocate unei variabile dinamice ,apelam procedura dispose , cu
sintaxa:
dispose(<pointer>);

Exemplu:
Memoria alocata anterior pentru variabila dinamica x^ alocata anterior, poate fi eliberata cu
dispose(x);

Pointerul NIL

In general ,un pointer conţine adresa unei variabile dinamice ,mai exact adresa zonei de
memorie unde este depozitata valoarea
variabilei dinamice. Este insa posibil ca in timpul execuţiei unui program ,un pointer sa primească
drept valoare adresa unei locaţii
de memorie “goala” ,in care nu se găseşte nici o valoare. In acest caz vom spune ca poianterul este “in
vânt” si ca valoarea sa este NIL.
Acest NIL reprezintă de fapt o constanta redefinita a limbajului cu sens de “nimic” (nul) ,si
poate fi atribuit numai variabilelor
de un tip pointer.

Atribuiri de pointeri

Un pointer poate fi atribuit altui pointer ,printr-o instrucţiune de genul


<dest> :=<sursa>,unde <sursa> si <dest> sunt pointeri de
acelaşi tip . Astfel, pointerul <dest> va primi ca valoare adresa memorata in pointerul <sursa>.Cu alte
cuvinte ,cei doi pointeri vor adresa aceeaşi locaţie de memorie , motiv pentru care are loc automat si
atribuire intre valorile referite de pointeri: <dest>^:=<sursa>^. Nu este necesara
alocarea alocarea memoriei pentru pointerul destinaţie <dest>, aceasta având loc automat in urma
atribuirii de pointeri.

Transmiterea pointerilor ca parametri

Un pointer poate fi transmis ca parametru unei proceduri sau funcţii, dar pentru aceasta este
obligatoriu sa denumim tipul anonim al
pointerului respectiv (ştim ca in antetul unui subprogram nu putem folosi tipuri anonime).
Exemplu :
Ne propunem sa declaram o procedura P care sa primească drept parametri doi pointeri x si y
către întreg. Aşadar x si y vor fi de
tipul ^ integer.
Este incorect sa scriem antetul procedurii astfel :
procedure P(x,y:^ integer);
Trebuie sa denumim tipul ^integer dandu-I de exemplu numele pint ;
type pint =^integer;
Acum putem scrie antetul procedurii in felul următor :
procedure P(x,y :pint);

TIPUL DE DATE POINTER

Type nume_pointer= ^ tip;


Var v:nume_pointer;
Exemplu:
Type adr=^integer;
Var a1,a2:adr;

21
Begin
a1:=a2;
End.
Adresa pentru tipul pointer
Var x:integer;
A:^integer;
Begin
X:=10;
A=@x;
Write(a^);
End.
Alocarea spatiului pentru variabila poiter p si elberarea lui
Procedure new(var p:pointer);
Procedure dispose (var p :pointer);
Ex:
Var adr1:^integer;
New(adr1);adr^:=7;
Writeln(adr1);dispose(adr1);
End;
7.2 Structuri de date implementate dinamic

7.2.2 Structura de tip stivă


Stiva este o listă pentru care singurele operaţii permise sunt:

● Adăugarea unui element în stivă;


● Eliminarea, consultarea, sau modificarea ultimului element introdus în stivă.

Stiva funcţionează pe principiul LIFO (Last In First Out) – “ultimul intrat, primul ieşit”.

Pentru a înţelege modul de lucru cu stiva, ne imaginăm un număr n de farfurii identice, aşezate una peste
alta (o “stivă” de farfurii). Adăugarea sau scoaterea unei farfurii se face, cu uşurinţă, numai în vârful stivei. Oricât
ar părea de simplu principiul stivei, el are consecinţe uriaşe în programare.

Stivele se pot aloca secvenţial (ca vectori). Fie ST[i] un vector. ST[1], ST[2], … , ST[n] pot reţine numai litere sau
numai cifre. O variabilă k indică în permanenţă vârful stivei, adică ultimul element introdus.

În stivă iniţial vidă se introduce litera A, vârful stivei va fi la nivelul 1,


(k=1);
A
B
A
Introducem în stivă litera B, deci k va lua valoarea 2.

Scoatem din stivă pe B (A nu poate fi scos deocamdată); k=1

Scoatem din stivă pe A; stiva rămâne vidă k=0

22
Observaţii:

În mod practic, la scoaterea unei variabile din stivă, valoarea variabilei ce indică vârful stivei scade cu 1, iar atunci
când scriem ceva în stivă, o eventuală valoare reziduală se pierde.

Pe un anumit nivel se reţine, de regulă, o singură informaţie (literă sau cifră), însă este posibil, aşa cum va rezulta
din exemplele prezentate în lucrare, să avem mai multe informaţii, caz în care avem stive duble, triple, etc.

În cazul stivei, alocarea secvenţială nu prezintă mari dezavantaje, ca în cazul mai general, al listelor, pentru că nu
se fac operaţii de inserare sau ştergere în interiorul stivei. Singurul dezavantaj, în comparaţie cu alocarea dinamică
înlănţuită este dat de faptul că numărul de noduri care pot fi memorate la un moment dat este mai mic – depinde de
gradul de ocupare al segmentului de date.

În literatura de specialitate veţi întâlni termenul PUSH pentru operaţia de adăugare în stivă a unei înregistrări şi
POP, pentru extragere.

Exemple:

□ Funcţia Manna-Pnueli. Se citeşte xЄZ. Se cere programul pentru calculul funcţiei:

F(x)= x-1, x≥12


F(F(x+2)), x<12

Vom începe prin a studia modul de calcul al funcţiei pentru x=15 şi x=8.

f(15)=14;
f(8)=f(f(10))=f(f(f(12)))=f(f(11))=f(f(f(13)))=f(f(12))=f(11)=f(f(13))= f(12)=11.
Algoritmul va folosi o stivă ST şi o variabilă k, ce indică în permanenţă vârful stivei. Algoritmul se
bazează pe următoarele considerente:
■ la o nouă autoapelare a funcţiei f, se urcă în stivă (k se incrementează cu 1) şi se pune noua valoare.

■ în situaţia în care pentru valoarea aflată pe nivelul k se poate calcula funcţia, se coboară în stivă, punându-se pe
acest nivel noua valoare.

■ algoritmul se încheie când se ajunge în stivă la nivelul 0.

Pentru exemplul dat, prezentăm schematic funcţionarea sa:

12 13

10 10 11 11
8 8
8 8 8

12 13
11 12
8 11
f=11

23
□ Programul următor calculează funcţia Manna-Pnueli, utilizând stiva alocată dinamic. Lucrul
cu stiva se face prin utilizarea funcţiilor PUSH (PUNE) şi POP (SCOATE).

Etapa1)elemental din varful stivei

punerea unui element in stiva

scoaterea unui element din stiva

{ Functia lui MaNa-Pnueli.calculati ex:x=8


f(x)=x-1 daca x>=12 =>11}
alfel f(x)=f(f(x+2)) daca x<12 program stiva1;

24
const nmax=5; DINAMIC
type stiva=array[1..nmax] of {Sa se simuleze formula lui manna pnueli cu
byte; stive pentru a se pune
var a: stiva; in evidenta operatiile in stiva f(x)=x-1
dim,n,i:byte; dacax>=12 alfel f(x)=f(f(x+2))
x,y:byte; ex:n=8}
function program stiva;
vida(x:stiva;dim:byte):boolean; type adresa=^nod;
begin nod=record
if dim >0 then vida:=false else info:integer;
vida:=true; adr_inap:adresa;
end; end;
var v:adresa;
function n,man:integer;
plina(x:stiva;dim:byte):boolean procedure push(var v:adresa;n:integer);
; var c:adresa;
begin begin
if dim <nmax then plina:=false if v=nil then
else plina:=true; begin
end; new(v);
procedure adaug(var x:stiva;var v^.info:=n;
dim:byte;y:byte);
v^.adr_inap:=nil;
begin
end
inc(dim);
else
x[dim]:=y;
begin
end;
new(c);
c^.info:=n;
function elimin(var x:stiva;var
c^.adr_inap:=v;
dim:byte):byte;
begin v:=c;
elimin:=x[dim] ; end;
dec(dim); end;
end; procedure pop(var v:adresa);
var c:adresa;
begin begin
write('x=');readln(x); if v=nil then writeln('stiva este vida')
adaug(a,dim,x); else
while not vida(a,dim) do begin
begin c:=v;
y:=elimin(a,dim); v:=v^.adr_inap;
for i:=1 to dim do dispose(c)
writeln(a[i]);writeln; end;
if y>=12 then end;
{writeln('valoarea functiei se procedure tipar(v:adresa);
poate calcula direct') } var c:adresa;
if not vida(a,dim) then begin
a[dim]:=y-1 c:=v;
else while c<> nil do
else begin
begin writeln(c^.info);c:=c^.adr_inap;
adaug(a,dim,y); end;
for i:=1 to dim do end;
writeln(a[i]); writeln; begin
adaug(a,dim,y+2); write('n=');
for i:=1 to dim do readln(n);
writeln(a[i]); push(v,n);
end; while v<>nil do
end; if v^.info <12 then
write('manna pnueli(',x,')=',y- begin
1); push(v,v^.info+2);
end. tipar(v); readln;

25
end procedure s(var p:ref);
else var c:ref;
begin begin
man:=v^.info; if p=nil then
pop(v); writeln(' goala ')
tipar(v); else
readln; begin
writeln(' scot din stiva pe');
if v<>nil then writeln(p^.nr);
v^.info:=man-1; c:=p;
end; p:=p^.urm;
writeln('f=',man-1) ; dispose(c);
readln; end;
end. end;
DINAMIC IN GENERAL procedure s1(var p:ref);
{Sa se creeze o stiva. var q:ref;
Scrieti doua proceduri diferite begin
care elimina elemente in stiva} q:=p;
type ref=^inr; p:=q^.urm;
inr=record dispose(q);
nr:integer; end;
urm:ref;
end; begin
var p:ref; write('dati un numar n>=3 ');
i,n:integer; readln(n);
procedure b(var p:ref); for i:=1 to n do
var c:ref; b(p);
begin writeln('-----------elimin
new(c); elementul din virful stivei');
writeln(' pe cine pui in stiva s1(p);
');readln(c^.nr); for i:=1 to n do
c^.urm:=p; s(p);
p:=c;
end; readln;
end.

□ Funcţia lui Ackermann. Se dă funcţia următoare, definită pe produsul cartezian N x N.. Se citesc m
şi n. Să se calculeze Ack(m, n).

n+1, m=0
Ack(m,n)= Ack(m-1, 1), n=0
Ack(m-1, Ack(m, n-1)), altfel

Pentru a elabora algoritmul, studiem un exemplu numeric:

ack(2,1)=ack(1,ack(2,0))=ack(1, ack(1,1))=ack(1, ack(0, ack(1,0))= ack(1, ack(0, ack(0,1))=ack(1,


ack(0,2))=ack(1,3)=ack(0, ack(1,2))= ack(0, ack(0, ack(1,1))=ack(0, ack(0, ack(0, ack(1,0))))= ack(0,
ack(0, ack(0, ack(0,1))))=ack(0, ack(0, ack(0,2)))=ack(0,,ack(0,3))= ack(0,4)=5.

Pentru calculul acestei funcţii, folosim o stivă dublă, ST. Iniţial, valorile m şi n se reţin la nivelul 1. Pe
nivelul k al stivei se reţin valorile curente m şi n. În funcţie de valorile acestora se procedează astfel:

■ pentru m şi n diferite de 0, este necesar un nou calcul de funcţie, caz în care se urcă în stivă şi pe noul
nivel se pun argumente m şi n-1.

■ pentru cazul n=0, se rămâne pe acelaşi nivel în stivă, punând în locul lui m valoarea m-1, iar în locul
lui n valoarea 1.

26
■ în situaţia în care m=0, funcţia se poate calcula; se coboară în stivă şi se înlocuieşte valoarea lui m cu
m-1, valoarea lui n cu valoarea calculată anterior.

În continuare, prezentăm grafic modul de funcţionare a algoritmului pentru exemplul ack(2,1):

10 01
20 11 11 11
21 21 21 21 21

10
01 11 11
11
02 02 13 12 12
12
21 12 03
12 13 13
13 13 13 04

ack(2,1)=5.

VAR ST:ARRAY[0..1000,0..2] OF INTEGER; begin


M,n,k:integer; st[k,0] =st[k,0] – 1;
Begin st[k,1] = 1;
Readln(m,n); end
K:=1;
st[k,0]: =m; st[k,1] :=n; else
while (k>0) do begin
if (st[k,0]>0 and st[k,1]>0) k:=k-1;
begin if (k>0)
k:=k+1; { st[k,0] =st[k,0] – 1;
st[k,0] =st[k-1,0]; st[k,1] =st[k+1,1] +1;
st[k,1] =st[k-1,1] – 1; end;
end end;
else write(”ac(“m, n”) = ”,st[1,1] +1);
if (st[k,1]<>0) end.

7.2.3 Structura de tip coadă


 O coadă este o listă pentru care toate inserările sunt făcute la unul din capete, toate ştergerile
(consultările, modificările) la celălalt capăt.

Coada funcţionează pe principiul FIFO (First In First Out) – “primul intrat, primul ieşit”.

Este cu totul nerecomandabilă alocarea secvenţială a cozii, deoarece în această situaţie, are loc
un fenomen de migraţie a datelor către ultimele componente ale vectorului (cele de indice mare).

27
Să presupunem că simulăm o coadă cu ajutorul unui vector cu zece componente, care reţin
numere întregi. Introducem în coadă, pe rând, numerele 1, 2, 3, 4.

1 2 3 4

Dacă scoatem din coadă pe 1 şi introducem în coadă pe 5, coada va arăta astfel:

2 3 4 5

Scoatem din coadă pe 2 şi introducem pe 6:

3 4 5 6

Se observă acest fenomen de “migraţie”.

Alocarea dinamică înlănţuită a cozii. O variabilă v va reţine adresa elementului care urmează a
fi scos (servit). O alta, numită sf, va reţine adresa elementului introdus în coadă. Figura următoare
prezintă o coadă în care primul element care urmează a fi scos are adresa în v, iar ultimul introdus are
adresa sf.

v sf

7 3 5 2
Etapa 1)

punerea unui element

28
stergerea unui element

varful cozii este acum numarul 982

{Considerind in doua fisiere niste p:=nil;


numere ordonate crescator in fiecare assign(f,'f1.pas');
assign(g,'f2.pas');
sa se preia numarele in ordine reset(f);
descrescatoare si sa se puna intr-o lista reset(g);
simplu read(f,a);read(g,b);
inlantuita care sa fie COADA pentru ca while (not eof(f) and not eof(g)) do
la listare sa fie afisate in begin
new(q);
ordine crescatoare if a<b then begin
Sa se puna datele ordonate in alt fisier q^.info:=a;read(f,a);
din lista creata anterior} end
type po=^nod; else
nod=record if (a=b) then begin
info:integer; q^.info:=a;
leg:po; read(f,a);read(g,b);
end; end
var p,q,d,u:po; else
f,g:text; begin
procedure o; q^.info:=b;
var a,b:integer; read(g,b);
begin end;

29
IF (P=NIL) THEN BEGIN end;
begin
q^.leg:=p; o; {L;
p:=q; writeln;}
u:=p; Li;
end readln;
else end.
begin CU LISTE DUBLU INLANTUITE
q^.leg:=nil;u^.leg:=q;u:=q; { Sa se creeze o structura de coada}
end; type ref=^inr;
end; inr=record
while (not eof(f)) do begin nr:integer;
new(q);q^.info:=a;q^.leg:=nil; as,ad:ref;
u^.leg:=q;u:=q; end;
read(f,a); var p,u:ref;i,n:integer;
end; procedure b(var u:ref);
var c:ref;
while (not eof(g)) do begin
begin new(c);
new(q);q^.info:=b;q^.leg:=nil;u^.leg:=q; writeln(' pe cine pui in coada ');readln(c^.nr);
u:=q; c^.ad:=nil;
read(g,b); c^.as:=nil;
end; if u<>nil then u^.ad:=c else
close(f);close(g); p:=c;
end; u:=c;
procedure L; end;
var c:po; procedure s(var p:ref);
begin var c:ref;
c:=p; begin
while(c<>nil) do if p=nil then writeln(' e goala ') else
begin begin
write(c^.info, ' '); writeln(' pe cine scot ');
c:=c^.leg; writeln(p^.nr);
end; c:=p;p:=p^.ad;
end; p^.as:=nil;
procedure li; dispose(c);
var H:text; end;
var c:integer; end;
begin
assign(h,'ff.pas');rewrite(h); begin
d:=p;c:=0; writeln(' cite elemente dai n>=3');readln(n);
while d<>nil do for i:=1 to n do
begin b(u);
writeln(d^.info);writeln(h,d^.info); for i:=1 to n do
inc(c);d:=d^.leg; s(p);
end;
writeln(' am atitea inregistrari',c); readln;
end.
close(h);

7.2.1 Listă liniară simplu inlantuita si dublu inlantuita


Prezentarea structurii

 O listă liniară este o colecţie de n≥0 noduri, X₁, X₂, … , Xn aflate într-o relaţie de ordine. Astfel,
X₁ este primul nod al listei, X₂ este al doilea nod al listei … Xn este ultimul nod. Operaţiile
permise sunt:

□ Accesul la oricare nod al listei în scopul citirii sau modificării informaţiei conţinute de acesta.

30
□ Adăugarea unui nod, indiferent de poziţia pe care o ocupă în listă.

□ Ştergerea unui nod, indiferent de poziţia pe care o ocupă în listă.

□ Schimbarea poziţiei unui nod în cadrul listei.

Există două metode de alocare a unei liste liniare: alocarea secvenţială şi alocarea înlănţuită.

Liste alocate secvenţial

Nodurile listei ocupă poziţii succesive în memorie. Acest tip de alocare l-am întâlnit des, de
câte ori am utilizat vectori.

Exemplu: un vector are n componente de tip real. Se cere să se sorteze vectorul crescător. Algoritmul
are ca dată de intrare o listă liniară, cu n noduri de tip real. Ieşirea este tot o listă liniară, cu aceleaşi
noduri, dar în altă ordine. Să presupunem că utilizăm sortarea prin interschimbare. O interschimbare a
nodurilor i şi j se reduce la următoarele operaţii, premise în listă:

■ man = v[i]; - se citeşte nodul i şi se memorează – accesez nodul i în vederea citirii;

■ v[i] v[i+1]; - accesez nodul i+1 în vederea citirii (operaţie permisă) şi accesez nodul i în vederea
modificării informaţiei reţinute (operaţie permisă).

■ v[i+1] = man; - accesez nodul i+1 în vederea modificării informaţiei reţinute de el.

În concluzie, sortarea se realizează prin utilizarea operaţiilor permise asupra unei liste liniare.

 Avantajul alocării secvenţiale este dat de faptul că programatorul are acces direct la oricare din
nodurile listei, la fel ca la componentele unui vector.

 Dezavantajul alocării secvenţiale este dat de faptul că operaţiile de adăugare, eliminare sau schimbare
de poziţie a unui nod necesită un efort mare de calcul, ca în exemplul următor, în care se elimină un
nod:

Fie lista alocată secvenţial:


7 3 1 2 8 9 5 8 3 2 6 ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙

Eliminăm al doilea nod –conţinut 3.


7 1 2 8 9 5 8 3 2 6 ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙
◄▬▬▬▬▬▬▬▬▬▬▬▬
Este obligatoriu ca nodurile următoare să fie deplasate către stânga:
7 1 2 8 9 5 8 3 2 6 ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙ ∙∙∙
Liste alocate înlănţuit
Există două feluri de alocare înlănţuită: alocare simplu înlănţuită şi alocare înlănţuită. În
acest paragraf prezentăm principiile alocării înlănţuite, urmând ca în paragraful următor să arătăm
modul în care implementăm listele alocate înlănţuit.

1. O listă liniară simplu înlănţuită este o structură de forma:

in₂ adr₃ inn nil

31
in₁ adr₂
adr₁ adr₂ adrn

Semnificaţia notaţiilor folosite este următoarea:

■ adr₁, adr₂, adr₃, … , adrn reprezintă adresele celor n înregistrări;

■ in₁, in₂, in₃, … , inn reprezintă informaţiile conţinute de noduri, de altă natură decât cele de adresă;

■ nil – are semnificaţia “nici o adresă” – elementul este ultimul în listă.

După cum observăm, fiecare nod, cu excepţia ultimului, reţine adresa nodului următor.

2. Alocarea dublu înlănţuită. Alocarea simplu înlănţuită permite parcurgerea listei într-un singur sens
(de la stânga la dreapta). În cazul în care se doreşte ca lista să poată fi parcursă în ambele sensuri
se utilizează alocarea dublu înlănţuită. Aici fiecare nod reţine adresele predecesorului şi
succesorului său, aşa cum se vede în figura următoare:

nil in₁ adr₂ adr₁ in₂ adr₃ adrn-1 inn nil


adr₁ adr₂ adrn

 Dezavantajele alocării înlănţuite sunt:

1. Accesul la un nod al listei se face prin parcurgerea nodurilor care în preced. Aceasta necesită un
efort de calcul.
2. Informaţiile de adresă, prezente în cadrul fiecărui nod, ocupă memorie.

 Avantajele alocării înlănţuite sunt date de faptul că operaţiile de adăugare sau eliminare a unui nod se
fac rapid. Exemplele sunt date pentru lista liniară simplu înlănţuită, dar bine înţelese, ne permit să
deducem singuri modul de efectuare a operaţiilor respective pentru liste dublu înlănţuite.

a) Adăugarea unui nod.

Fie lista:

3 adr₂
7 adr₃ 9 nil

adr₁ adr₂ adrn

Dorim să adăugăm după nodul cu informaţia 3, un altul cu informaţia 5.


Etapele sunt:
□ Se alocă spaţiu în memorie pentru un nou nod – indiferent unde:

7 adr₃ 32
9 nil
3 adr₂
adr₁ adr₂ adrn
adrt

□ Se completează informaţiile pentru nodul creat – câmpul de adresă trebuie să conţină adresa nodului
care trebuie să-i urmeze în listă:

3 adr₂
7 adr₃
9 nil

5 adr₂
adrt

□ Se modifică adresa nodului care precede nodul nou creat. Adresa trebuie să fie a nodului nou creat:

adrt

3 adrt 7 adr₃ 9 nil

5 adr₂

De acum, putem “privi” lista aşa cum am fost obişnuiţi:

5 adr₂ 7 adr₃ 9 nil

33
3 adrt
adr₁ adrt adr₂ adrn

b) Ştergerea unui nod. Pentru a exemplifica operaţiile efectuate în acest caz vom folosi a de mai sus,
la care ştergem al doilea nod (cel cu informaţia 5). Iată etapele:

□ Informaţia de adresă a nodului care îl precede trebuie să reţină adresa nodului următor:

3 adr₂ 5 adr₂ 7 adr₃ 9 nil


adr₁ adrt adr₂ adrn

□ Memoria ocupată de nodul care urmează a fi şters este eliberată:

3 adr₂ 7 adr₃ 9 nil


adr₁ adr₂ adrn

De acum, putem privi lista aşa cum am fost obişnuiţi.

3 adr₂ 7 adr₃ 9 nil

adr₁ adr₂ adrn

Observaţii:
În cazul alocării înlănţuite, adresele de memorare ale nodurilor consecutive nu sunt neapărat
consecutive. Pentru a realiza acest lucru este suficient să analizaţi cazul ştergerii unui nod (sau acela al
adăugării unui nod).

 Prin alocarea memoriei pentru un nod înţelegem rezervarea spaţiului necesar memorării informaţiilor
conţinute de acesta. Evident, se poate aloca memorie doar dacă există memorie disponibilă, adică nu
este ocupată de alte variabile.

 Pentru eliberarea memoriei ocupate de un nod înţelegem că spaţiul ocupat de acesta devine disponibil
– este pus la dispoziţia programatorului, pentru ca, eventual, acesta să fie din nou alocat.

 Este important să folosim termenii corect. De exemplu, nu putem folosi în loc de “alocarea
memoriei” termenul “crearea memoriei”, tot aşa cum nu este corect să folosim în loc de “eliberarea
memoriei” termenul “ştergere a memoriei”.

 Noţiunile care privesc alocarea şi eliberarea memoriei sunt prezentate în paragraful următor.

34
Liste liniare alocate simplu inlantuit
Definitia listelor
Def.:O lista liniara este o colectie de n>=0 noduri, X1,X2,…,Xn, aflate intr-o relatie de
ordine.Astfel, X1 este primul nod al listei, X2 este al doilea nod al listei,…, Xn este ultimul
nod.Operatiile permise sunt:
 Accesul la oricare nod al listei in scopul citirii sau modificarii informatiei continute de acesta.
 Adaugarea unui nod, indiferent de pozitia pe care o ocupa in lista.
 Stergerea unui nod,indiferent de pozitia pe care o ocupa in lista.
 Schimbarea pozitiei unui nod in cadrul listei.

Liste liniare alocate simplu inlantuit


Prezentare generala

O lista liniara simplu inlantuita este o structura de forma:

in1 adr1 in2 adr2 inn 0


adr1 adr2 adrn
Dupa cum se observa, fiecare nod, cu exceptia ultimului, retine adresa nodului
urmator.
1. Accesul la un nod al listei se face parcurgand nodurile care il preced.
2. Informatiile ocupa memorie, fiind prezente in cadrul fiecarui nod.
3. Avantajele alocarii inlantuite sunt date de rapiditatea operatiilor de adaugare si eliminare.
In cadrul unei astfel de liste, zona de memorie rezervata fiecarui elev se numeste nod sau celula.
Definitie.Numim cod (celula) o unitate informationala de sine statatoare (elementara) care contine
informatii utile si date de legatura.Se numeste lista un ansamblu de noduri (celule).
Exista mai multe tipuri de liste, dintre care:listele liniare simplu inlantuite, listeel liniare dublu inlantuite,
listele circulare, stivele si cozile.
Liste liniare simplu inlantuite cu numere intregi
Reprezentare
O astfel de lista va memora elementele unui sir de numere intregi si este alcatuita fireste din
noduri.Fiecare nod contine doua campuri: un numar al sirului(informatia utila) si adresa la care se
gaseste numarul urmator din sir(pointer catre nodul urmator).
Numerele memorate in noduri se mai numesc si cheile listei.
Pentru ultimul nod, pointerul catre nodul urmator marcheaza sfarsitul listei si are valoarea NIL.
Etapa1)

inserarea nui element

35
stergerea unui element

gasirea unui element

36
CREAREA SI AFISAREA LISTELOR SIMPLU INLANTUITE
type ref=^inr; u:=c;
inr=record end;
nr:integer;
urm:ref; end;
end;
var qq,p,c,u:ref; a:array[1..15] of ref; procedure afisare(p:ref);
nn,n,i:integer; var c:ref;
procedure init(var p:ref); begin
begin c:=p;
writeln(' cite inregistrari vreti sa introduceti while (c <>nil) do
');readln(n); begin
new(c); writeln('introduceti inregistrarea prima writeln(c^.nr:6);
'); c:=c^.urm;
readln(c^.nr); end;
c^.urm:=nil; end;
p:=c;u:=c; begin
for i:=2 to n do init(p);
begin afisare(p);
writeln('introduceti inregistrarea ',i); readln;
new(c);readln(c^.nr);c^.urm:=nil;u^.urm:=c; end.

Operatii asupra unei liste liniare


{
Sa se scrie toate operatiile cu o lista simplu new(c);readln(c^.nr);c^.urm:=nil;u^.urm:=c;
inlantuita} u:=c;
type ref=^inr; end;
inr=record end;
nr:integer; procedure inserareinaintedepa;
urm:ref;
end; begin
var p,c,u:ref; new(c);
n,i:integer; writeln('pe cine inserati inaite de pa inreg.(dati
procedure init; un numar ');readln(c^.nr);
begin c^.urm:=p;
writeln(' cite inregistrari vreti sa introduceti p:=c;
');readln(n); end;
new(c); writeln('introduceti inregistrarea pa ');
readln(c^.nr); procedure inserareinaintedepamaimulte;
c^.urm:=nil; var multe:integer;
p:=c;u:=c; begin
for i:=2 to n do writeln('cite inregisrari vreti sa inserati inainte
begin de pa ');readln(multe);
writeln('introduceti inregistrarea ',i); for i:=1 to multe do

37
begin while potadauga do
new(c); begin
writeln('pe cine inserati inaite de pa i(dati un while (c<>nil) and(c^.nr<>cecaut) do
numar ',i);readln(c^.nr); c:=c^.urm;
c^.urm:=p;
p:=c; end; if (c=nil) then potadauga:=false
end; else
procedure adaugunlasfirsit; begin
begin new(pecinepun);
new(c); writeln(' pe cine vrei sa pui ');
writeln('dati numarul care-l puneti dupa ua readln(pecinepun^.nr);
inregistrare '); pecinepun^.urm:=c^.urm;
readln(c^.nr); c^.urm:=pecinepun ;
c^.urm:=nil; c:=c^.urm;
u^.urm:=c; end;
u:=c; end;end;
end; procedure pununadupamaimulte;
procedure adaugunlasfirsitmaimulte; var cecaut:integer; pecinepun :ref;
var multe:integer; begin
begin
writeln('cite inregistrari vreti sa mai puneti dupa writeln('introduceti dupa a cit -a inregistrare
ua ');readln(multe); vreti sa faceti adaugarea ');readln(cecaut);
for i:=1 to multe do c:=p;
begin for i:=1 to cecaut-1 do
new(c); c:=c^.urm;
writeln('dati numarul care-l puneti dupa ua begin
inregistrare ',i); new(pecinepun);
readln(c^.nr); writeln(' pe cine vrei sa pui ');
c^.urm:=nil; readln(pecinepun^.nr);
u^.urm:=c; pecinepun^.urm:=c^.urm;
u:=c; c^.urm:=pecinepun ;
end;end; c:=c^.urm;
end;
procedure pununadupacecaut; end;
var cecaut:integer; pecinepun :ref; procedure pununainaintedemaimulte;
begin var cecaut:integer; pecinepun :ref;
writeln('introduceti valoarea inainte de care begin
vreti sa faceti adaugarea ');readln(cecaut);
c:=p; writeln('introduceti inainte de a cit -a
while(c<>nil) and (c^.nr<>cecaut) do inregistrare vreti sa faceti inseararea
c:=c^.urm; ');readln(cecaut);
if (c=nil) then writeln(' nu este ce cauti in lista ') c:=p;
else for i:=1 to cecaut-2 do
begin c:=c^.urm;
new(pecinepun); begin
writeln(' pe cine vrei sa pui '); new(pecinepun);
readln(pecinepun^.nr); writeln(' pe cine vrei sa pui ');
pecinepun^.urm:=c^.urm; readln(pecinepun^.nr);
c^.urm:=pecinepun ; pecinepun^.urm:=c^.urm;
end; c^.urm:=pecinepun ;
end; c:=c^.urm;
end;
procedure punmaimulteinaintedececaut; end;
var cecaut:integer; pecinepun :ref; procedure stergpa;
potadauga:boolean; var desters:ref;
begin begin
potadauga :=true; desters :=p;
writeln('introduceti valoarea inainte de care p:=p^.urm;
vreti sa faceti adaugarea ');readln(cecaut); dispose( desters);
c:=p; end;

38
procedure stergua; begin
var oretinpepenua,desters:ref; writeln('cite vreti sa stergeti incepind de la pa
begin ');readln(multe);
c:=p; for i:=1 to multe do
while (c<>u) do begin
desters :=p;
begin p:=p^.urm;
oretinpepenua :=c; dispose( desters);
c:=c^.urm; end;
end; end;
desters :=c;
oretinpepenua^.urm :=nil; procedure stergdupacecaut;
u:=oretinpepenua ; var osterg:ref;cecaut:integer;
dispose( desters); begin
end;
c:=p;
procedure stergdupaunacareocaut; writeln(' dupa ce valoare vrei sa stergi');
var oretinpepenua,desters:ref;cecaut:integer; readln(cecaut);
begin while (c<>nil) and (c^.nr<>cecaut) do
writeln('dupa a cit-a intergistrare vreti sa c:=c^.urm;
stergeti ');readln(cecaut); if c=nil then writeln(' nu este in lista ')
c:=p; else
for i:=1 to cecaut do begin
osterg:=c^.urm;
begin c^.urm:=c^.urm^.urm;
oretinpepenua :=c; {dispose(osterg); }
c:=c^.urm; end;
end; end;
desters :=c;
oretinpepenua^.urm :=c^.urm; procedure stergcecaut;
var oretin,osterg:ref;cecaut:integer;
dispose( desters); begin
end;
c:=p;
writeln(' ce valoare vrei sa stergi');
readln(cecaut);
procedure sterguele; while (c<>nil) and (c^.nr<>cecaut) do
var oretinpepenua,desters:ref;multe:integer; begin
begin oretin:=c;
writeln('cite vreti sa stergeti incepind de la c:=c^.urm;end;
sfirsit spre inceput ');readln(multe); if c=nil then writeln(' nu este in lista ')
for i:=1 to multe do else
begin begin
c:=p; osterg:=c;
while (c<>u) do oretin^.urm:=c^.urm;
dispose(osterg);
begin end;
oretinpepenua :=c; end;
c:=c^.urm;
end; procedure stergcecautdeciteoriapare;
desters :=c; var
oretinpepenua^.urm :=nil; oretin,osterg:ref;cecaut:integer;potsterge:boole
u:=oretinpepenua ; an;
dispose( desters); begin
end; writeln(' ce valoare vrei sa stergi');
end; readln(cecaut);
potsterge:=true;

procedure stergdelapamaimulte; while potsterge do


var desters:ref;multe:integer; begin

39
c:=c^.urm;
c:=p; writeln(' cu cine o modifici');
readln(c^.nr);
while (c<>nil) and (c^.nr<>cecaut) do end;
begin
oretin:=c;
c:=c^.urm;end; begin
if c=nil then potsterge :=false init;
else afisare;
begin inserareinaintedepa;
osterg:=c; afisare;
oretin^.urm:=c^.urm; inserareinaintedepamaimulte;
dispose(osterg); afisare;
end; adaugunlasfirsit;
end;end; afisare;
procedure afisare; adaugunlasfirsitmaimulte;
begin afisare;
c:=p;
while (c <>nil) do pununadupamaimulte;
begin afisare;
writeln(c^.nr:6); pununainaintedemaimulte;
c:=c^.urm; afisare; writeln('o sterg pe pa ');
end; stergpa ;afisare;
end; stergdelapamaimulte; afisare;
procedure modificpa; stergua;
begin writeln('o sterg pe ua ');
c:=p; afisare;
writeln('cu cine modifici pe pa');readln(c^.nr); sterguele;afisare;
stergdupaunacareocaut;
end; afisare;
procedure modificua; pununadupacecaut;afisare;
begin stergdupacecaut;
c:=u; afisare;
writeln('cu cine modifici pe ua');readln(c^.nr); stergcecaut;
afisare;
end; stergcecautdeciteoriapare; afisare;
procedure modificcepozitiecaut; modificpa;
var cecaut:integer; afisare;
begin modificua; afisare;
c:=p; modificcepozitiecaut; afisare;
writeln(' a cit-a inregistrare vrei sa o modifici'); readln;
readln(cecaut); end.
for i:=1 to cecaut-1 do

Liste alocate dublu inlantuit


O lista alocata dublu inlantuit este o structura de date de forma:

0 in1 adr2 adr1 in2 adr3 adrn-1 inn 0 0


0000adr3
adr1 adr2
adrn

Operatiile posibile asupra unei liste dublu inlantuite sunt:

40
1) creare;
2) adaugare la dreapta;
3) adaugare la stanga;
4) adaugare in interiorul listei;
5) stergere din interiorul listei;
6) stergere la stanga listei;
7) stergere la dreapta listei;
8) listare de la stanga la dreapta;
9) listare de la dreapta la stanga.

1) Creare

O lista dublu inlantuita se creeaza cu o singura inregistrare.Pentru a ajunge la numarul de inregistrari


dorit, utilizam functii de adaugare la stanga si la dreapta.Functia creare realizeaza citirea informatiei
numerice, alocarea de spatiu pentru inregistrare, completarea inregistrarii cu informatia si completarea
adreselor la dreapta si la stanga cu 0.

2) Adaugare la dreapta

Functia add citeste informatia numerica, aloca spatiu pentru inregistrare, completeaza adresele,
modifica adresa la dreapta a inregistrarii din s cu adresa noii inregistrari si ii atribuie
lui s valoarea noii inregistrari.

3) Adaugare la stanga

4) Adaugare in interiorul listei

Functia includ parcurge lista pentru a gasi inregistrarea cu informatia m, in dreapta careia urmeaza sa
introducem noua inregistrare, citeste informatia, aloca spatiu, completeaza informatia, completeaza
adresa stanga a noii inregistrari cu valoarea adresei inregistrarii de informatie m, si completeaza adresa
dreapta a noii inregistrari cu valoarea adresei dreapta a inregistrarii cu informatia utila m.

5) Stergere in interiorul listei

Functia Sterg parcurge lista pentru a gasi informatia care va fi stearsa, atribuie inregistrarii precedente
campul de adresa dreapta al inregistrarii care va fi stearsa, iar inregistrarii care urmeaza celei care va fi
stearsa i se atribuie campul de adresa stanga al inregistrarii pe care o stergem, dupa care se elibereaza
spatiul de memorie rezervat inregistrarii care se sterge.

6)-7) Stergere la stanga si la dreapta listei

8) Listare de la stanga la dreapta

Functia listare porneste din stanga listei si tipareste informatia numerica a fiecarei inregistrari, atata
timp cat nu s-a ajuns la capatul listei.
OPERATII CU LISTE DUBLU INLANTUITE
{Cu liste dublu inlantuite sa se simuleze procedure creare;
crearea ,listarea in ambele sensuri si stergerea begin
ultimului,primului element ,inserarea dupa un writeln('n=');readln(n);
anumit numar de inregistrari new(c);
sau stergerea elementui care are un anumit writeln(' primul element ');readln(c^.nr);
numar de inregistrare} c^.ad:=nil;
type ref=^inr; c^.as:=nil;
inr=record p:=c;
as:ref; u:=c;
nr:integer; for i:=2 to n do
ad:ref; begin
end; new(c);
var p,c,u:ref; writeln(' dati integistrarea ',i);
n,i:integer; readln(c^.nr);

41
c^.ad:=nil; procedure stergA_p1_componenta;
c^.as:=u; var p1:integer;q:ref;
u^.ad:=c; begin
u:=c; c:=p;
end; writeln(' dati componenta care o stergeti din
end; lista ');readln(p1);
procedure adauginaintedeprima; writeln('------------------');
begin for i:=1 to p1-1 do
new(c); c:=c^.ad;
writeln('pe cine adaug inainte de prima '); q:=c;
readln(c^.nr); c^.as^.ad:=c^.ad;
c^.ad:=p; c^.ad^.as:=c^.as;
p^.as:=c; dispose(q)
c^.as:=nil; end;
p:=c; procedure ins1;
end; var i:integer;d,q:ref;
procedure adugadupaultima; begin
begin writeln(' in fata cui inserati ');readln(i);
new(c); writeln('------------------');
writeln(' pe cine adugi dupa ultima '); d:=p;
readln(c^.nr); writeln('------------------'); while(i<>d^.nr) and (d<>nil) do
c^.ad:=nil; d:=d^.ad;
c^.as:=u; if d= nil then writeln(' nu ')
u^.ad:=c; else
u:=c; begin
end; new(q);
procedure adaugadupaa_p1_acomponenta; writeln('informatia care o inserati ');
var p1:integer;q:ref; readln(q^.nr);
begin q^.ad:=d;
c:=p; q^.as:=d^.as;
writeln(' dupa a cita componenta d^.as^.ad:=q;
adaugi(inserezi '); d^.as:=q;
readln(p1); writeln('------------------'); end;
for i:=1 to p1-1 do end;
c:=c^.ad;
new(q); procedure listare;
writeln(' dati componenta care o inserati '); var c:ref;
readln(q^.nr); writeln('------------------'); begin
q^.ad:=c^.ad; c:=p;
c^.ad^.as:=q; while(c<>nil) do
q^.as:=c; begin
c^.ad:=q; writeln(c^.nr,' ');
end; c:=c^.ad;
procedure stegultima; end;
var q:ref; end;
begin
q:=u; procedure listare1;
u:=u^.as; var c:ref;
u^.ad:=nil; begin
dispose(q); c:=u;
end; while(c<>nil) do
begin
procedure stegprima; writeln(c^.nr,' ');
var q:ref; c:=c^.as;
begin end;
q:=p; end;
p:=p^.ad;
p^.as:=nil; begin
dispose(q); creare;
end; writeln('------------------');

42
listare; writeln('sterg pe ultima adugadupaultima; listare;
------------------'); writeln('------------------');
stegultima; adaugadupaa_p1_acomponenta; listare;
writeln('o listez de la sfirsit spre writeln(' sterg prima ------------------');
inceput------------------'); stegprima;listare; writeln('------------------');
listare1; stergA_p1_componenta; listare;
adauginaintedeprima; writeln('------------------');
writeln('------------------'); ins1; listare;
listare; writeln('------------------'); readln;
end.

7.2.4 Arbore binar


Arbori

Definitie : Un graf conex si fara cicluri se numeste arbore .


Teorema
Fie un graf G=(X,U) . Urmatoarele afirmatii sunt echivalente :
1. G este arbore .
2. G este un graf conex ,minimal in raport cu aceasta propietate (eliminand o muchie oarecare
se obtine un graf ne-conex).
3. G este un graf fara cicluri,maximal in raport cu aceasta proprietate (adaugand o muchie
oarecare, se obtine un graf care are cel putin un ciclu).
In cazul arborilor ,in loc de “varfuri” si “muchii”,se folosesc cu precadere termenii sinonimi “noduri”
respectiv “arce”.
Teorema : Un arbore cu n varfuri are n-1 muchii.

Detaliem si sistematizam in continuare cateva propietati care caracterizeaza un arbore :


● exista un nod in care nu intra nici un arc, numit radacina arborelui.
● cu exceptia radacinii, fiecare nod are propietatea ca in el intra un singur arc. Aceasta leaga nodul
respectiv de un alt nod numit predecesor sau parinte.
● dintr-un nod pot iesi unul sau mai multe arce. Fiecare astfel de arc , leaga nodul rsepectiv de un
alt nod numit succesor sau fiu al nodului.
● nodurile sunt organizate pe nivele , primul nivel fiind ocupat de nodul-radacina. Nodurile de pe
ultimul nivel se caracterizeaza prin faptul ca din ele nu mai iese nici un arc , si se numesc noduri
terminale sau frunze.
● nodurile pot contine o asa-numita informatie utila care poate fi de orice tip . De obicei aceste
informatii se mai numesc si chei ale arborelui.

Arbori binari

Definitie
Un arbore cu propietatea ca fiecare nod cu exceptia frunzelor , are cel mult doi descendenti
(succesori ) se numeste arbore binar.
Intr-un arbore binar ,cei doi succesori ai unui nod (daca exista), se numeste succesor stang
respectiv arbore drept.
Definitie
Un arbore cu proprietatea ca fiecare nod ,cu exceptia frunzelor , are exact doi descendenti
(succesori) se numeste arbore binar complet .
Etapa 1)

43
nod radacina e 58,nod terminal(frunza) e 7

tatal nodului cu cheia de valoare zero este nodul cu valoare 15


nodul cu valoarea doi are doi fii(descendenti) cu valoarea cheilor de 0 (descendent stang) si
11(descendent drept)
nivelul 0 contine nodul cu valoarea cheii 15
nivelul 1 contine nodurile cu valoarea cheilor 2 76
nivelul 2 contine nodurile cu valoarea cheilor 0 11 56 90
nivelul 3 contine nodurile cu valoarea cheilor 38 63
nivelul 4 contine nodurile cu valoarea cheilor 75
deci AVEM 5 niveluri
Arborele este dezechilibrat pentru ca nodurile terminal ear trebui sa fie pe nivelurile 3 sau 4 dar la noi
avem noduri terminale si pe nivelul 2 (adica pe 0 si 90)
Exemplu de mai jos este de arbore echilibrat

44
etepa 2)parcurgerea in inordine

45
46
{ Creati un arbore cu chei var x:integer;nou:arbore;
intregi.Parcurgeti in begin
write('Info:');read(x);
postordine,inordine,preordine if x<>0 then
arborele creat.} begin
new(nou);
{ Rezolvare : 1 nou^.info:=x;
2 write('Stanga lui ',x,':');
0 nou^.st:=radacina;
0 write('Dreapta lui ',x,':');
3 nou^.dr:=radacina;
0 radacina:=nou
0 end
} else radacina:=nil;
end;
program ParcurgereArb; procedure preordine(p:arbore);
type arbore=^nod; begin
nod=record if p<>nil then
info:integer; begin
st,dr:arbore write(p^.info:4);
end; preordine(p^.st);
var rad:arbore; preordine(p^.dr);
function radacina:arbore; end

47
end; postordine(p^.st);
procedure inordine(p:arbore); postordine(p^.dr);
begin write(p^.info:4);
if p<>nil then end
begin end;
inordine(p^.st); begin
write(p^.info:4); rad:=radacina;
inordine(p^.dr); preordine(rad);
end writeln;
end; inordine(rad);
procedure postordine(p:arbore); writeln;
begin postordine(rad);
if p<>nil then end.
begin
7.2.5 Arbore binar de cautare
Definitie. Se numeste arbore de cautare un arbore binar ale carui noduri au o cheie de
identificare,iar pentru fiecare nod avem proprietatiile urmatoare:

 orice cheie asociata unui nod al subbarborelui stang este mai mica decat cheia asociata
nodului;
 orice cheie asociata unui nod al subarborelui drept este mai mare decat cheia asociata
nodului.

Cheile de identificare sunt distincte !

Alaturat observati un arbore de cautare.

1. INSERAREA

Crearea arborilor de cautare se face aplicand de un nr de ori operatia de inserare. Regula de inserare
este urmatoarea:

 Se compara cheia asociata unui nod cu cheia inregistrarii care se insereaza. Avem trei posibilitati:

 cheia coincide cu nr – se renunta la inserarea acelui numar;


 cheia este mai mare decat numarul – se incearca inserarea in subarborele stang;
 cheia este mai mica decat numarul – se incearca inserarea in subarborele drept.

 Inserarea propriu-zisa se realizeaza atunci cand subarborele stang,respectiv


drept,este vid,astfel se reia.

Vezi procedura INSERARE.

2. CAUTAREA

Se face in mod asemanatorcu inserarea motiv pentru care nu o mai comentam.

3. LISTAREA

48
Informatia se poate lista utilizand oricare din metodele cunoscute pentru parcurgerea arborilor. Daca
dorim listarea informatiilor in ordinea strict crescatoare a cheilor,se utilizeaza metoda stang-varf-dreapta
(inordine), intrucat pentru orice nod avem urmatoarele:

 cheile nodurilor din subarborele stang sunt mai mici decat cheia asociata
nodului;
 cheile nodurilor din subarborele drept sunt mai mari decat cheia asociata
nodului.

Vezi procedura SVD.

4. STERGEREA

Dupa stergerea unui nod care are o anumita cheie, arborele ramas trebuie sa fie de cautare.

Se disting 4 situatii posibile:

a) nodul care urmeaza sa fie sters este nod terminal – in acest caz se face stergerea
avand grija ca la parintele lui sa inlocuim adresa catre el cu nil;
b) nodul care urmeaza a fi sters subordoneaza un singur subarbor – cel drept – caz in
care parintelui se va inlocui adresa catre el cu adresa subarborelui drept,iar nodul
respectiv se sterge;
c) nodul care urmeaza a fi sters subordoneaza un singur subarbore – cel stang – caz in
care parintelui i se va inlocui adresa catre el cu adresa subarborelui stang, iar nodul
respectiv se sterge;
d) nodul care urmeaza a fi sters( dupa cum vom vedea, acesta se va sterge numai logic)
subordoneaza doi subarbori, caz in care se fac operatiile:

 se indentifica cel mai din dreapta nod al subarborelui stang coorespunzator nodului care
urmeaza a fi sters (acesta va fi sters in mod efectiv, nu inainte de a muta informatiile sale la
nodul care se sterge logic);
 cheia acestuia si alte informatii utile continute de el se muta la nodul care urmeaza a fi sters
 subarborele stang al nodului care se va sterge fizic se leaga:
 in stanga nodului care se sterge logic (daca nodul indentificat ca cel mai din dreapta din
subarborele stang este descendent direct al nodului care se sterge logic)
 in dreapta tatalui nodului care se sterge fizic( in caz contrar);

Exemple de stergere:

1. Arborelui din stanga i se sterge nodul 8. acesta nu subordoneaza nici un alt arbore.

2. Arborelui din stanga i se sterge nodul 9. acesta subordoneaza un singur subarbore, cel
drept.

49
3. Arborelui din stanga i se sterge nodul 3. Cel mai din dreapta nod al subarborelui stang este 1.
se obtine:

4. Arborelui din stanga i se sterge nodul 7. cel mai din dreapta nod al subarborelui stang este 6.
tatal nodului care se sterge fizic este 3. in dreapta sa se leaga subarborele 5 4 . se obtine:

Vezi procedura STERG. In situatia in care nodul care urmeaza a fi sters subordoneaza doi arbori,se
apeleaza procedura CMMD.

 Intrebarea la care trebuie sa raspundem in continuare este urmatoarea:de ece daca


se sterge in acest mod un nod,arborele ramane de cautare? Stergerea unui nod se
face in mod dinstinct pentru fiecare din cele 4 cazuriaratate. Datorita simplitati

50
prelucrarii primele tri cazuri nu necesita comentarii. In cazul 4 se indentifica nodul cel
mai din dreaptadin arborele stang. Cheia acestuia trece in locul cheii nodului care se
sterge. Aceasta este mai mica decat cheia initiala,este in acelasi timp cea mai mare
din subarborele stang,deci este cea mai mare cheie mai mica decat cheia care se
sterge. Iata motivul pentru care aceasta trece in locul cheii sterse logic.
 Transmiterea parametrului c se face prin referinta. Adresa de alocare va fi trimisa
automat parintelui,caadresa de subarbore stang sau drept (duopa caz).
 Altgoritmul are complexitatea in cazul cel mai defavorabil 0(n 2). In cazul in care, de
exemplu cheile inserate sunt in ordine crescatoare, arborele va degenera intr-o lista
liniara –orice nod are numai un descendent drept,iar
 inserarea unui nod inseamna parcurgerea tuturor nodurilor deja inserate in pasul
anterior.

Teoria regasirii informatiei este deosebit de importanta pentru viata practica. Aceasta conduce la o
cautare rapida (putine comparatii).

Etapa 1)

inserez noduri

51
stergerea unui nod care nu are fii de exemplu nodul cu cheia 90

52
stergerea unui nod care are un fiu stang

stergerea unui nod care are mai multe niveluri sub el de exemplu o sa stergem de mai jos elemental cu cheia 27

53
stergerea unui nod cu 2 descendenti de exemplu de mai jos pe valoarea cheii 43

54
cautarea unui element de exemplu caut pe valoarea cheii 29

{Sa se creeze un arbore binar de cautare.}


program creare_arbore_de_cautare;
type adr=^nod;
nod=record
v:integer;
st,dr:adr;
end;
var rad:adr;
i,n:byte;
x:integer;
procedure adauga(var r:adr; x:integer);
begin
if r=nil then begin
new(r);
r^.v:=x;
r^.st:=nil; r^.dr:=nil;
end
else if x<=r^.v then adauga(r^.st,x)
else adauga(r^.dr,x);
end;
procedure inord(r:adr);
begin
if r<>nil then begin
inord(r^.st);
write(' ',r^.v);

55
inord(r^.dr);
end;
end;
begin
write('n='); readln(n);
new(rad);
write('dati sirul:');
writeln(' primul nod ');
read(rad^.v);
rad^.st:=nil; rad^.dr:=nil;
for i:=2 to n do
begin
writeln(' nodul al ',i,'lea');
read(x);
adauga(rad,x);
end;
writeln('inord:');
inord(rad);
readln;
end.

7.2.6 Operatii specifice referitoare la arbori de cautare


program cautare; parcurg(c^.ad);
uses crt; end;
type ref=^inr; end;
inr=record procedure cmmd(var c,f:ref);
nr:integer; begin
as,ad:ref; if f^.ad<>nil then cmmd(c,f^.ad)
end; else begin
var v,man:ref; c^.nr:=f^.nr;
k:integer; man:=f;
opt:char; f:=f^.as;
procedure inserare(var c:ref;k:integer); dispose(man);
var d:ref; end;
begin end;
if c<>nil then procedure sterg(var c:ref;k:integer);
if c^.nr=k then writeln('nr deja inserat') var f:ref;
else begin
if c^.nr<k then inserare(c^.ad,k) if c<>nil then if c^.nr=k then
else inserare(c^.as,k) if (c^.as=nil)and(c^.ad=nil)
else begin then begin
new(c); dispose(c);
c^.as:=nil; c:=nil;
c^.ad:=nil; end
c^.nr:=k; else
end; if c^.as=nil
end; then begin
procedure caut(var c,adr:ref;k:integer); f:=c^.ad;
begin dispose(c);
if c<>nil then if c^.nr<k then caut(c^.ad,adr,k) c:=f;
else if c^.nr>k then end
caut(c^.as,adr,k) else
else adr:=c if c^.ad=nil
else adr:=nil; then begin
end; f:=c^.as;
procedure parcurg(c:ref); dispose(c);
begin c:=f;
if c<>nil then begin end
parcurg(c^.as); else
writeln(c^.nr); cmmd(c,c^.as)

56
else inserare(v,k)
if c^.nr<k then end;
sterg(c^.ad,k) 'l':parcurg(v);
else 'c':begin
sterg(c^.as,k) write ('k=');readln(k);
else caut(v,man,k);
writeln('numar absent -tentativa if (man<>nil) then writeln(k)
esuata') else writeln('nu exista acest nod');
end; end;
begin 's':begin
v:=nil; write('se sterge numarul');readln(k);
repeat sterg(v,k);
write('optiunea'); end;
readln(opt); end;
case opt of until opt='t'
'i':begin end.
write('k=');readln(k);
Forma poloneza –aplicatii-la coada

Se da o expresie aritmetica ce foloseste operatorii `=`,`-`,`*`,`/` precum si `(`, `)`. Fiecare operand
este o litera. Se cere sa se converteasca aceasta expresie intr-o expresie in forma
poloneza(postfixata).

Definim expresia in forma poloneza recursiv,astfel:

 un operand este o expresie in forma poloneza


 daca E1 si E2 sunt doua expresii in poloneza si # un operator, E1 E2 # este o expresie in
forma poloneza;
 orice expresie in forma poloneza se obtine aplicand regulile de mai sus de un numar finit de
ori.

Exemple:
EXPRESIE ARITMETICA EXPREIE IN FORMA POLONEZA
A+b Ab+
A*(b+c) Abc+*
A*(b+c)-e/(a+d)+h Abc+*ead+/-h+
 Forma poloneza este o forma de scriere a expresiilor aritmetice in care parantezele
nu mai sunt puse (din acest motiv o expresie scrisa in forma poloneza se mai
numeste expresie scrisa fara paranteze), dar aceasta nu duce la calculul eronat al
exp.

Expresiili aritmetice pot fi reprezentate utilizand arbori binari,respectand urmatoarele reguli:

- fiecare operatie corespunde unui nod terminal, avand ca informatie


utila operatia respectiva;
- fiecare nod terminal este etichetat cu o variabila sau o constanta;
- pentru fiecare nod neterminal subarborele din stanga si cel din
dreapta reprezita,in aceasta ordine,cei doi operanzi;
- radacina corespunde ultimei operatiiexecutate la evacuarea
expresiei.

Exemplu: expresiei (a+b)*c-d/e i se asociaza arborele binar din figura de mai jos. Parcurgerea acestui
arbore in postordine va da chiar forma poloneza:ab+c*de/-. Utilizand cele spise pentru rezolvarea
problemei, vom proceda in felul urmator:

57
 construim arborele binar asociat expresiei
aritmetice;
 il parcurgem in postrdine pentru a obtine forma
poloneza.

Pentru constructia arborelui vom acorda prioriati operatorilor si operanzilor(mai putin parantezelor),dupa
cum urmeaza:

- prioritatea initiala a operatorilor `x`, `-`, este 1;


- prioritatea initiala a operatorilor `*`, `/` este 10;
- la prioritatea unui operator se aduna 10 pentru fiecare pereche de
paranteze intre care se gaseste;
- prioritatea unui operand este 1000.

Inprogram acest lucru se realizeaza astfel:

- se citeste expresia aritmetica in variabila e;


- se utilizeaza o variabila j care indica ce numar se adauga la
prioritatea initiala unui operator(la intalnirea unei paranteze descise
j creste cu 10, iar la intalnirea unei paranteze inchise j scade cu 10);
- se parcurge expresia caracter cu caracter si se pun in vector p
pioritatile acestor operatori si operanzi (mai putin ale parantezelor);
- in eft se construieste expresia fara paranteze ( la expresia
aritmetica initiala lipsesc parantezele), iar in pfp se obtine vectorul,
prioritatilor dincare, spre deosebire de p,lipsesccomponentele
corespunzatoare parantezelor (acestea nu aveau nici o valoare).

Utilizand efp si pfp cu ajutorul functieiarb se construieste arborele atasat expresiei aritmetice. Un nod al
acestui arbore are ca informatie utila un operator sau un operand.

Conform tehnicii DIVIDE ET IMPERA, functia arb procedeaza in felul urmator:

 de la limita superioara catre limita inferioara cauta operatorul sau


operandul cu prioritate minima, retinand pozitia acestuia. Acesta constitue
informatia utila din nord,care va fi completata;
 in situatia in care limita inferioara este diferita de limita superioara,pentru
completarea adresei subarborelui din stanga si a subarborelui din dreapta
se reapeleaza functia , iar in caz contrar aceste campuri capata valoarea
nil.

Pentru listarea in postordine se utilizeaza procedura PARC.

Program fp; Op:char


Type ref =^inr; End;
Sir :array[1..30] of char; Var e,efp:sir;
Vector=array[1..30] of integer; Pfp,p:vector;
Inr=record I,j,n:integer;
As,ad:ref; C:ref;

58
A:char Parc(c^.as);
Function arb (li,ls:integer;var efp:sir:var Parc(c^.ad);
pfp:vector);ref; Write(c^.op)
Var c:ref End
I,j,min:integer; End;
Begin
Min:=pfp[ls]; Begin
I:=ls; J:=0;read( a); n:=1;
For j:=ls downto li do Whilea<>`.` do
If pfp[j]<min Begin
Then E[n]:=a;n:=n+1;read( a);
Begin End;
min:=pfp[j]; N:=n-1;
I:=j; For i:=1 to n do
End; Case e[i] of
New( c);arb:=c; arb^.op:=efp[i]; `)`:j:=j-10;
If li=ls `(`:j:=j+10;
Then `+`,`-`:p[i]:=j+1;
Begin `*`,`/`:p[i]:j+10
Arb^.as:=nil;arb^.ad:=nil; else p[i]:=1000
End end;
Else j:=1;
Begin for i:=1 to n do
Arb^.as:=arb(li,i-1,efp,pfp); if(e[i]<>`)`) and(e[i]<>`(`)
Arb^.ad:=arb(i+1,ls,efp,pfp) then begin
End efp[j]:=e[i];
End; pfp[j]:=p[i];
j:=j+1
Procedure parc (c:ref); end;
Begin c:=arb(1,j-1,efp,pfp);
Ifc<>nil parc( c );
Then writeln;
Begin end.

Aplicatie. Dandu-se o expresie in forma poloneza postfixata,sa se scrie un program care sa genereze
programul de calcul al expresiei utilizand numai instructiuni de atribuire cu un singur operator. Se vor
introduce variabelele auxiliare x0,x1,…,xn.

Exemplu. Pentru expresia aritmetica a*(b+c)-e/(a+d)+h forma poloneza este abc+*ead+/-h+. Se


genereaza urmatorul program de calcul:

X0=b+c
X1=a*x0
X2=a+d
X3=e/x2
X4=x1-x3
X5=x4+h.

Pentru realizarea scopului propus procedam astfel:

a) folosim o stiva dbla ST,care permite memorarea variabilelor x0,x1,…,xn,a,b,..,z.


b) Forma poloneza se gaseste in fp;
c) Din fp se citeste caracter cu caracter iar rezultatul citirii se trateaza diferential astfel:

- in cazul in care caracterul citit este operand, se incarca in stiva;

59
- in cazul in care caracterul citit este operator,se scot din stiva
continuturile ultimelor doua niveluri si se face tiparirea sub forma:-
xj=variabila penultima in stiva,operator,variabila ultima in stiva, iar
variabila tiparita se retine i stiva.

Procedeul se repeta ata timp cat nu au fost citite toate caracterele. Pe exemplul considerat, rularea
decurge astfel:

A,b,c se incarca in stiva; C


B
A
X0 La citirea opeatorului ``+``se tipareste x0=b+c si xo se pune in stiva.
A

X1 Citirea operatorului ``*`` determina tiparirea x1=a*x0 si se pune in stiva.

D
A
E E,a,d se incarca in stiva;

X1

X2
E Se tipareste x2=a+d;

X1

X3 Se citeste ``/``, se tipareste X3=e/X2;


X1

Se citeste ``-``, se tipareste X4=X1-X3


X4

h Caracterul ``h`` se pune in stiva;


X4

La citirea peratorului ``+`` se tipareste x5=x4+h


X5

Intrucat au fost citite toate caracterel, altgoritmul se incheie.

Program fp_pc;
Type stiva=array[1..100,1..2] of char;
Var st:stiva;
Fp:string[100];
I,j,k:integer;

60
C:string[1];
Begin
Write( ` forma poloneza este=`);
Readln( fp);
K:=0;j:=0;
For i:=1 to lenght(fp) do
Case fp[i] of
`a`..`z`:begin
k:=k+1;
st[k,2]:=fp[i];
st[k,1]:=` `
end;
`+`,`-`,`*`,`/`,:
begin
writeln(`x`,j,`=`,st[k-1,1],st[k-1,2],fp[i],st[k,1],st[k,2]);
k:=k+1;
st[k,1]:=`x`;str(j:1,c);st[k,2]:=c[1];
j:=j+1
end
end{case}
end.
 procedeul indicat este utilizt pentru compilarea expresiilor. Se cunoaste faptul ca procesorul are
instructiuni care permit o singura operatie si doi operanzi. O expresie trbuie adusa sub forma
prezenta,pentru obtinerea codului masina. Altgoritmii utilizati sunt de acest tip (evident,acestia sunt si
optimizanti).
8.Teoria grafurilor
8.1 Definitie.Metode de reprezentare
Notiunea de graf neorientat , adiacente , incidenta, grad
Se numeste graf neorientat , o pereghe ordonata de multimi (X,U)unde:
-X este multimea finita si nevida de elemente numite varfuri sau noduri;
-U este o multime de perechi neordonate de cate doua elemete din X, numite muchii sau arce .
Pentru o muchie uk=(a,b), vom spune ca :
-varfurile a si b sunt adiacente si se numesc extremitatile muchiei u k;
-muchia uk si varfurile a sunt incidente in graf .La fel , muchia u k si varful b ;
-muchia (a,b) este totuna cu (b,a)
Gradul unui varf x , notat d(x) , reprezinta numarul muchiilor care trec prin nodul x
Un varf care are gradul 0 , se numeste varf izolat
Un varf care are gradul 1 , se numeste varf terminal .
Aplicatie
Construirea matricei de adiacenta prin “citirea muchiilor “de la tastatura :
Procedure citire_graf;
Var I,j,k,x,y:integer;
Begin
Readln(n);
Readln(M);
For I:=1 to n do
For j:=1 to n do
A[I,j]:=0;
For k:=1 to m do
Begin
Write(‘dati muchia”);
Repeat
Readln(x,y);
Until (x>=1)and (x<=n)and(y>=1) and (y<=n) ;
A[x,y]:=1;
A[y,x]:=1;
End;
Listele vecinilor

61
Pt fiecare nod I formam lista vecinilor lui I .Asta cuprinde toate nodurile care sunt extremitati ale
muchiilor care trec prin nodul I .

Reprezentarea grafului ca un vector de muchii

Fiecare muchie a grafului poate fi privita ca o inregistrare cu doua componente :cele doua varfuri care
constituie extremitatile muchiei .Notam aceste extremitati cu nod 1 si nod 2 , putem defini tipul de date
TMUCHIE, astfel :
Type tmuchie =record
Nod1 ,nod2:integer;
End;
Reprezentarea grafurilor neorientate
Consideram un graf neorientat g=(X,U) cu m muchii si n varfuri numerotate 1,2,3,4,….,n.
Matricea de adiacenta
Este o matrice a cu n linii si n coloane , in care elementele a[I,j]se definesc astfel :
a[i,j]= 1 , daca exista muchia iI,j] cu i<>j
0 in caz contrar

8.2 Notiunea de graf


partial,subgraf,lant,drum,ciclu,circuit
Grafuri orientate –notiuni de baza
Noţiunea de graf orientat.
Un exemplu de graf orientat este: reţeaua de străzi a unui oraş. Străzile sunt muchii în graf, iar
intersecţiile reprezintă vârfurile grafului. Întrucât mergând pe jos ne putem deplasa pe orice stradă în
ambele sensuri, vom spune că din punctul de vedere al pietonilor, „graful unui oraş” este neorientat.
Cu totul altfel stau lucrurile în ceea ce priveşte conducătorii auto, pentru că în orice oraş există străzi cu
sens unic. Pentru un şofer străzile trebuie să primească în graf o anumită orientare. Desigur că acele
străzi pe care se poate circula în ambele sensuri vor primi orientare dublă. Am ajuns astfel la noţiunea
de graf orientat.
Numim graf orientat, o pereche ordonată de mulţimi G=(X,U), unde:
X este o mulţime finită şi nevidă numită mulţimea nodurilor (vârfurilor);
U este o mulţime formată din perechi ordonate de elemente ale lui X, numită mulţimea arcelor
(muchiilor)
observaţii:
Prin noţiunea de perechi ordonate nu trebuie să
înţelegem că o muchie este mai mare decât alta, ci pur
U1
şi simplu că facem deosebire între o muchie de forma
(x,z) şi o alta de forma (y,x). Cu alte cuvinte muchiile
1
sunt diferenţiate prin ordinea de scriere a simbolurilor.
Arcul (x,y) nu este tot una cu arcul (y,x).
Exemplu: U2
Pentru graful G=(X,U) din figura 1. avem: X={1, 2, 3, 4}
2
şi U={u1, u2, u3, u4, u5, u6, u7,}= {(1,1), (2,1), (3,2),
(2,3), (2,4), (3,4), (3,4)} U3
arc va fi de forma u= (x,y), unde x se numeşte U5
extremitate iniţială, iar y se numeşte extremitate finală a U4
arcului. Cu alte cuvinte, “arcul iese din nodul x şi intră în
nodul y”. La fel ca la grafurile neorientate, vom spune că 3
nodurile x şi y sunt adiacente, iar arcul u şi nodul x sunt U6
incidente (la fel arcul x şi nodul y). Nodul y se numeşte 4
succesor al lui x, iar nodul x se numeşte predecesor al
U7
lui y. Un arc de forma (x,x), care iese din nodul x şi intră
tot x, se numeşte buclă.
Exemplu: Figura1
În graful din figura 1, avem bucla (1,1).
Într-un graf putem avea două sau mai multe arce identice.
Exemplu:
În graful din figura 1, există două arce identice, u6 = u7 = (3,4)
Definiţie

62
Se numeşte p-graf, un graf orientat în care numărul arcelor identice este mai mic sau egal cu o valoare
dată p.
În cele ce urmează vom analiza numai 1-grafuri fără bucle.
Graful unui vârf. Mulţimile Γ şi ω
Gradul exterior al unui vârf x, notat d*(x), reprezintă numărul arcelor care ies din nodul x, adică numărul
arcelor de forma (x,z) ε U.
Analog, se defineşte gradul interior al unui vârf x, notat d-(x), ca fiind numărul arcelor care intră în nodul
x (de forma (y,x) ε U).
Exemplu:
În graful reprezentat în figura 1, pentru nodul x=2, avem:
d*(2) =3 → există trei arce care ies din nodul 2, şi anume : u2=(2,1), u4=(2,3) şi u5 = (2,4).
d-(2) =1 → în nodul 2 intră un singur arc, în speţă arcul u3=(3,2).
Se mai definesc următoarele mulţimi:
  x   y  X x, y  U 
→ mulţimea nodurilor ce constituie extremităţi finale ale arcelor care
pleacă din nodul x. Pe scurt, mulţimea succesorilor lui x;
  x   y  X  y, x  U 
→ mulţimea nodurilor ce constituie extremităţi iniţiale ale arcelor care
pleacă din nodul x. Pe scurt, mulţimea predecesorilor lui x;
Exemplu:
În graful din figura 1, pentru nodul x=2, avem:
- Γ+(2) = {1,3,4} → urmare a faptului că muchiile care pleacă din nodul 2 sunt (2,1), (2,3) şi (2,4), putem
spune că mulţimea succesorilor nodului 2 este {1,3,4}.
- Γ-(2) = {3} → în nodul 2 intră doar muchia (3,2), deci mulţimea predecesorilor lui 2 conţine doar nodul
3. ω+(x) = {u = (x,y)| u ε U} → mulţimea arcelor care ies din nodul x;
ω-(x) = {u = (y,x)| u ε U} → mulţimea arcelor care intră în nodul x;
Exemplu:
În graful din figura 1, pentru nodul 2, avem:
ω+(x) = {(2,1), (2,3), (2,4)}, ω-(x) = {(3,2)}
Graf parţial şi subgraf
Fie graful G = (X,U). Un graf parţial al lui G, este un graf G 1= (X,V), cu V  U . Altfel spus, un graf
parţial G1 al lui G, este chiar G, sau se obţine din G păstrând toate vârfurile şi suprimând nişte muchii.
Fie graful G = (X,U). Un graf parţial al lui G, este un graf G 1= (Y,T), unde V  X şi T  U , iar T va
conţine numai muchiile care au ambele extremităţi în Y. Altfel spus, un graf parţial G 1 al lui G, se obţine
din G eliminând nişte vârfuri şi păstrând doar acele muchii care au ambele extremităţi în mulţimea
vârfurilor rămase.
Exemplu:
Se consideră graful G = (X,U) din figura 2, în care X = {1,2,3,4,5,6} şi U={u1, u2, u3, u4, u5, u6, u7}.
- Construim graful parţial G1 = (X,V), unde X = {1,2,3,4,5,6} şi V = { u2, u3, u4, u6, u7} (figura 3)
din graful G au fost eliminate arcele u1 şi u5.
- Construim subgraful G2 = (Y,T), unde Y = {3,4,5,6} şi T = {u4, u5, u6, u7} (figura 4) din graful G
au fost eliminate nodurile 1 şi 2 precum şi arcele u1, u2 şi u3 care au o extremitate în afara
mulţimii nodurilor rămase.
Reprezentarea grafurilor orientate
Considerăm un graf orientat G= (X,U) cu m arce şi n noduri.
Cele mai cunoscute forme de reprezentare sunt: matricea de adiacenţă, matricea vârfuri – arce,
matricea drumurilor şi listele vecinilor.
Matricea de adiacenţă

u2 u2
1 2 1 2
u1
u3 u3
u4 u5 u4 u4
3 3 3 u5
4 4 4
5 5 5
u7 u6 u7 u7
u6 u6

6 6 6
Figura 2 Figura
63 3 Figura 4
Are aceeaşi semnificaţie ca în cazul grafurilor neorientate: fiecare element a[i,j], cu i,j ε {1,2,...,n}, este: 1
dacă există arcul (i,j), respectiv 0 în caz contrar.
Datorită orientării, aşa cum am mai spus, arcul (i,j) nu este totuna cu arcul (j,i). Prin urmare, a[i,j] ≠ a[j,i].
Aşadar matricea de adiacenţă nu mai este simetrică faţă de diagonala principală, aşa cum se întâmpla
în cazul grafurilor neorientate.
Exemplu:
Pentru graful G=(X,U) din figura 5, matricea de adiacenţă este:
coloana 1 2 3 4

0 0 0 0 1

1 0 1 1 2
A=
0 0 0 1 3

0 1 0 0 4

2
3

1
4

Figura 5

Continuăm cu câteva aplicaţii.


Aplicaţie:
Citirea de la tastatură şi afişarea matricei de adiacenţă
Prin citirea matricei de adiacenţă de la tastatură, putem memora arcele existente între nodurile unui
graf. În cazul grafurilor neorientate, citeam doar “porţiunea” de deasupra diagonalei principale în
matrice, deoarece matricea este simetrică. Acum trebuie să citim toate elementele matricei. Avem de-a
face cu algoritmii banali de citire şi afişare a unei matrice cu n linii şi n coloane (unde n este numărul de
noduri) în două cicluri for, deci nu considerăm că mai sunt necesare alte explicaţii. Prezentăm în
continuare procedurile citire_matrice şi afişare_matrice.
Procedure citire_matrice;
{citeşte matricea de adiacenţă a de la tastatură}
var i,j: integer;
begin
writeln('Nr. Noduri: '); readln(n);
for i:=1 to n do
for j:=1 to n do
begin
write('[',i,',',j,']=');
readln(a[i,j]);
end;
end;

Procedure afişare_matrice;
{afişează matricea de adiacenţă a}
var i,j: integer;
begin
for i:=1 to n do
begin
for j:=1 to n do

64
write(a[i,j],' ');
writeln();
end;
end;

Aplicaţie:
Citirea matricei de adiacenţă dintr-un fişier text
Aceasta este absolut similară cu cea prezentată la grafuri neorientate, unde a fost explicată pe larg. De
fapt, este vorba despre algoritmul de citire a unei matrice oarecare dintr-un fişier text. Plecăm de la
presupunerea că fişierul conţine pe primul rând valoarea lui n, apoi pe fiecare din următoarele n rânduri
elementele unei linii a matricei separate de spaţii.
Procedure cit_matr_fis;
{citeşte numărul de noduri si matricea de adiacenta a din fişierul text cu descriptorul f}
var i,j: integer; nume_fis: string;
begin
write('Daţi numele fişierului '); readln(nume_fis);
assign(f,nume_fis); reset(f);
readln(f,n);
for i:=1 to n do
begin
for j:=1 to n do read(f,a[i,j]);
readln(f);
end;
close(f);
end;

Aplicaţie:
Construirea matricei de adiacenţă prin citirea “arcelor” de la tastatură
Se citesc de la tastatură m perechi de numere întregi de forma (x,y) reprezentând extremităţile celor m
arce ale grafului, şi se construieşte matricea de adiacenţă a, cu n linii şi n coloane.
Mai întâi citim m şi n (numărul de arce respectiv numărul de noduri), şi iniţializăm toată matricea de
adiacenţă cu 0, în două cicluri for. Apoi, într-un alt ciclu for, cu k de la i la m, citim cele m perechi de
întregi (x,y).
- Citirea fiecărei perechi (x,z) se face cu validare: repetă citirea lui x şi y până când ambele
valori sunt în intervalul [1,n].
repeat
readln(x,y);
until (x>=1) and x(<=n) and (y>=1) and (y<=n) and (x<>y);
- Pentru fiecare (x,y), marcăm în matricea de adiacenţă existenţa arcului (x,y), prin atribuirea
a[x,y]:=1. Spre deosebire de grafurile neorientate, nu se mai face şi atribuirea a[y,x]:=1,
deoarece arcul (x,y) nu e identic cu arcul (y,x).
Algoritmul prezentat a fost inclus în procedura citire_graf.
Procedure citire_graf;
var i, j, k, x, y: integer;
begin
write('Nr. Arce:'); readln(m);
write('Nr. Vârfuri'); readln(n);
{iniţializează cu 0 toata matricea de adiacenta}
for i:=1 to n do
for j:=1 to n do
a[i,j]:=0;
{citeşte m perechi (x,y) reprezentând arcele grafului}
for k:=1 to m do
begin
write('Muchia ',k,': ');
repeat
readln(x,y);
until (x>=1) and x(<=n) and (y>=1) and (y<=n) and (x<>y);
{pentru fiecare pereche, marchează arcul in matricea de adiacenta}
a[x,y]:=1;

65
end;
end;

Aplicaţie:
Determinarea gradului exterior şi a gradului interior ale unui nod oarecare x
Scriem o funcţie {d_plus(x:integer):integer;} care returnează, gradul exterior al nodului x (notat d*(x)).
Gradul exterior al unui nod x este numărul arcelor care ies din nodul x, adică numărul arcelor de forma
(x,j), cu j ε {1, 2, ... , n}. Luăm ca exemplu graful cu n=4 noduri de mai jos, împreună cu matricea sa de
adiacenţă:
1 2 3 4

0 0 0 0 1

A= 1 0 1 1 2

0 0 0 1 3

0 1 0 0 4

2
3

1
4

Analizăm gradul exterior al nodului 2. Arcele care ies din nodul 2 sunt: (2,1), (2,3), (2,4) (nu şi (4,2)).
Urmare a existenţei acestor arce, în matricea de adiacenţă vom avea a[2,1] = a[2,3] = a[2,4] = 1. Unde
se găsesc în matricea de adiacenţă toate valorile de 1 corespunzătoare arcelor ce ies din nodul 2? Pe
linia 2! Pe caz general, valorile de 1 de pe linia x în matricea de adiacenţă, reprezintă arcele care ies din
nodul x. Deci gradul exterior al nodului x, adică numărul arcelor care ies din nodul x este egal cu
numărul valorilor de 1 de pe linia x a matricei.
Aşadar algoritmul implementat în funcţia d_plus este foarte simplu:
Iniţializăm cu 0 o variabilă nr. în care numărăm valorile de 1 de pe linia x a matricei. Într-un ciclu,
parcurgem coloanele j=1, 2, ..., n ale liniei x. Pentru fiecare valoare a lui j, testăm elementul a[x,j] de pe
linia x şi coloana j. Dacă aceasta are valoarea 1, atunci incrementăm nr. În final funcţia va returna ultima
valoare a variabilei nr.
Function d_plus(x:integer):integer;
{returnează gradul exterior d* pentru un nod x; acesta este numărul valorilor de 1 de pe linia x a matricei
de adiacenta}
var nr.,j: integer;
begin
nr.:=0;
for j:=1 to n do
if a[x,j] = 1 then nr:=nr + 1;
d_plus:=nr;
end;

Observaţie:
Destul de asemănător este şi algoritmul pentru determinarea gradului interior al nodului x (d- (x) ).
Acesta reprezintă numărul arcelor care intră în nodul x, adică numărul arcelor de forma (i,x), cu i ε {1,
2, ..., n}. Să vedem unde se regăsesc în matricea de adiacenţă arcele care intră în nodul x, luând ca
exemplu x=4 pentru graful anterior. Arcele care intră în nodul 4 sunt (3,4) şi (2,4). Rezultă că în matrice
avem a[3,4] = a[2,4] = 1. Am “reperat” astfel valorile de 1 de pe coloana 4 a matricei de adiacenţă. În

66
acest moment putem concluziona că gradul interior al unui nod oarecare x reprezintă numărul valorilor
de 1 de pe coloana x a matricei. Se poate scrie o funcţie asemănătoare cu cea de mai sus, care să
returneze câte valori de 1 se găsesc pe coloana x.
function d_minus(x: integer): integer;
{returnează gradul interior d- pentru un nod x; acesta este numărul valorilor de 1 de pe coloana x a
matricei de adiacenta}
var nr, i: integer;
begin
nr:=0;
for i:=1 to n do
if a[i,x]=1 then nr:=nr+1;
d_minus:=nr;
end;

Matricea vârfuri – arce


Este o matrice b cu n linii şi m coloane, în care fiecare element b[i,j] este:
- 1, dacă nodul i este o extremitate iniţială a arcului u j;
- -1, dacă nodul i este o extremitate finală a arcului u j;
- 0, dacă nodul i nu este o extremitate a arcului uj.
Exemplu:
Pentru graful de mai jos cu n=4 noduri şi m=5 arce, matricea vârfuri – arce este:
1 0 0 0 0

-1 -1 -1 0 0

0 1 0 1 -1

0 0 1 -1 1

u1 u3
u2
1
u4
3 4

u5
Figura 6

Pentru a exemplifica construcţia matricei, vom deduce elementele liniei 3:


- a[3,1]= 0 pentru că nodul 3 nu este o extremitate a arcului u1. Analog, a[3,3]= 0 deoarece
nodul 3 nu este extremitate a arcului u3.
- a[3,5]= -1 pentru că nodul 3 este o extremitate finală a arcului u5.
- a[3,2]= 1 şi a[3,4]= 1 întrucât nodul 3 este o extremitate iniţială a arcului u2 respectiv u4.
Observaţii:
Pe fiecare coloană j (aferentă arcului uj), avem exact două elemente nenule: un 1 (linia i pe care se află
reprezintă extremitatea iniţială a arcului uj) şi un -1 (linia i pe care se află reprezintă extremitatea finală a
arcului uj)
Numărul valorilor de 1 de pe linia i, reprezintă gradul exterior al nodului i (numărul arcelor ce au ca
extremitate iniţială pe i), iar numărul valorilor de -1 de pe linia i reprezintă gradul interior al nodului i
(numărul arcelor care au ca extremitate finală pe i).
Listele vecinilor
Pentru fiecare nod x se construiesc două liste ale vecinilor săi:
- L*(x) → lista vecinilor succesori; conţine nodurile ce sunt extremităţi finale ale arcelor care ies
din nodul x.

67
- L-(x) → lista vecinilor predecesori; conţine nodurile ce sunt extremităţi iniţiale ale arcelor care
intră în nodul x.
Exemplu:
În graful din figura 6 de mai sus, pentru nodul x=4 avem:
- arcele care ies din nodul 4 sunt (4,2) şi (4,3). În consecinţă, lista vecinilor succesori L*(4)
conţine nodurile 2 şi 3;
- în nodul 4 intră un singur arc, şi anume (3,4), motiv pentru care lista vecinilor predecesori L-(4)
conţine doar nodul 3.
Prezentăm în continuare aceste liste ale vecinilor pentru graful din figura 6.

Nodul x L*(x) L-(x)


1 2 vidă
2 vidă 1,3,4
3 2,4 4
4 2,3 3

Matricea drumurilor
Această matrice va fi reprezentată în cadrul capitolului “Drumuri şi circuite în grafuri orientate”.
Reprezentarea grafului ca un vector de muchii
Fiecare arc al grafului poate fi privit ca o înregistrare cu două componente, în speţă cele două noduri
care constituie extremităţile arcului:
- nod_in -> nodul din care iese arcul (“nodul de început” al arcului);
- nod_sf -> nodul în care intră arcul (“nodul de sfârşit” al arcului);
Putem defini tipul de date ARC, astfel:
type ARC=record
nod_in, nod_sf: integer;
end;
Graful în ansamblul său, este o mulţime de arce, adică o mulţime de elemente de tipul ARC. În
consecinţă, definim graful ca un “vector de arce”, adică un vector de elemente de tipul ARC:
var v: array [1..25] of ARC;
Numărul real de elemente este numărul de arce m. Astfel, elementele efectiv folosite ale vectorului vor fi
v[1], v[2],..., v[m]. Fiecare element {1, 2, ..., m}) este de tipul ARC şi reprezintă unv[i] (cu i arc al
grafului, având două componente:
v[i].nod_in şi v[i].nod_sf -> nodurile extremităţi ale arcului.

Nodurile izolate într-un graf orientat


Se citesc de la tastatură m perechi de numere întregi (x,y) reprezentând extremităţile arcelor unui graf
orientat cu n noduri şi m arce. Să se stabilească dacă în graful astfel definit există noduri izolate (prin
care să nu treacă nici un arc).

Întreaga rezolvare este cuprinsă în procedura {noduri_izolate;} fără parametri.


Mai întâi citim numărul de noduri n şi numărul de arce m. Definim doi vectori:
- dp va conţine gradele exterioare (d*) ale tuturor nodurilor;
- dm va conţine gradele interioare (d-) ale tuturor nodurilor.
Astfel, dp[i] şi dm[i] vor fi gradul exterior respectiv gradul interior al nodului i, pentru i=1, 2, ..., n.
Iniţializăm cu 0 toate gradele exterioare şi interioare ale tuturor nodurilor: într-un ciclu cu i de la 1 la n,
facem atribuirile dp[i]:=0 şi dm[i]:=0
Pentru a citi cele m arce, parcurgem un ciclu k de la 1 la m, şi la fiecare pas:
- citim o pereche de numere întregi (x,y), cu validarea valorilor introduse: repetă (reia) citirea lui
x şi y, până când ambele valori sunt >= 1 şi >= n. Fiecare pereche va reprezenta care iese din
nodul x şi intră în nodul y.
- întrucât arcul (x,y) iese din nodul x şi intră în nodul y, rezultă că:
- gradul exterior al nodului x (numărul arcelor care ies din nodul x) va creşte cu 1;
- gradul interior al nodului y (numărul arcelor care intră în nodul y) va creşte cu 1.
Deci se fac atribuirile dp[x]:= dp[x]+1 şi dm[y]:= dm[y]+1.
Aşadar la citirea fiecărui arc am actualizat gradele nodurilor – extremităţi ale sale. Astfel, după
încheierea citirii vectorii dp şi dm vor conţine gradele exterioare respectiv interioare ale tuturor nodurilor.

68
Un nod x se numeşte izolat dacă prin el nu trece nici un arc. Altfel spus, nu iese nici un arc din el şi nu
intră nici un arc în el, adică dp[x]=dm[x]=0. În continuare, vom număra nodurile izolate în variabila nr, pe
care o iniţializăm cu 0. Parcurgem “în paralel” cei doi vectori ai gradelor dp şi dm, într-un ciclu cu i=1, 2,
3, ..., n. La fiecare pas, testăm dacă nodul i este izolat, adică dacă dp[i]=0 şi dm[i]=0; în caz afirmativ
afişăm respectivul nod i şi incrementăm numărul nr al nodurilor izolate.
nr:=0;
for i:=1 to n do
if(dp[i]=0) and (dp[i]=0) then
begin
write(i,' ');
nr:=nr+1;
end;
După încheierea acestei parcurgeri, dacă numărul vârfurilor izolate este diferit de 0 atunci îl afişăm, iar
în caz contrar tipărim un mesaj din care să rezulte că graful nu are noduri izolate.
Program XI_7;
type vect =array[1..20] of integer;
var n,m:integer;
a:array[1..20,1..20] of integer;
dp,dm:vect;

procedure noduri_izolate;
var i,j,k,x,y,nr:integer;
begin
write('Nr.arce : '); readln(m);
write('Nr.noduri: '); readln(n);
{iniţializează cu 0 vectorii gradelor dp şi dm}
for i:=1 to n do
begin
dp[i]:=0; dm[i]:=0;
end;
{citeşte m perechi (x,y) reprezentând arcele grafului}
for k:=1 to m do
begin
write('Arcul ',k,': ');
repeat
readln(x,y);
until (x>=1) and (x<=n) and (y>=1) and (y<=n) and (x<>y);
{pentru fiecare arc (x,y), incrementează gradul exterior al lui x şi gradul interior al lui y}
dp[x]:=dp[x]+1; dm[y]:=dm[y]+1;
end;
writeln; nr:=0; {nr=numărul nodurilor izolate}
for i:=1 to n do
{dacă ambele grade ale lui i sunt 0,am găsit un vârf izolat, pe care-l afişăm şi incrementăm nr}
if (dp[i]=0) and (dm[i]=0) then
begin
write(i,' '); nr:=nr+1;
end;
writeln;
if nr<>0 then writeln('Graful are ',nr, ' noduri izolate')
else writeln ('Graful nu are noduri izolate');
end;

begin
noduri_izolate;
end.

Celebritate.
Se dă un grup format din n persoane, care se cunosc sau nu între ele. De la tastatură se introduc m
perechi de numere întregi (x,y) cu semnificaţia ”persoana x cunoaşte pe persoana y”. relaţia de
cunoştinţă nu este neapărat reciprocă. Numim celebritate, o persoană care este cunoscută de către

69
toate celelalte persoane din grup, dar ea nu cunoaşte pe nici un alt membru al grupului. Să se
determine dacă din grup există o astfel de celebritate.

Interpretarea datelor.
Problema poate fi modelată într-un graf orientat, în care nodurile sunt persoanele 1,2,3...n, iar arcele
sunt relaţiile de cunoştinţă între aceste persoane. O relaţie de cunoştinţă este de forma (x,y) cu
semnificaţia “persoana x o cunoaşte pe persoana y”. De exemplu, dacă grupul are n=4 persoane, iar
cele m=5 “relaţii de cunoştinţă” sunt (1,3), (2,3), (4,3), (1,2), (1,4), atunci graful şi matricea sa de
adiacenţă arată astfel:
3
0 1 1 1
 
0 0 1 0
A
0 0 0 0
 
0 0 1 0  4
 1
Să analizăm persoana reprezentată prin nodul 3:
- există relaţiile de cunoştinţă (1,3), (2,3) şi
(4,3), adică persoana 3 este cunoscută de
către 1,2 şi 4. Mai exact, persoana 3 2 este
cunoscută de către toate celelalte
persoane din grup;
- nu există nici o relaţie de cunoştinţă de forma (3,p). Cu alte cuvinte, persoana 3 nu cunoaşte
pe nimeni.
În concluzie, persoana 3 este ceea ce numim celebritate. În graf, existenţa celebrităţii se interpretează
astfel:
- în nodul 3 intră arce “ieşite” din toate celelalte noduri;
- din nodul 3 nu iese nici un arc.
Rezolvare
În procedura citire_graf se citesc de la tastatură m perechi de numere întregi de forma (x,y)
reprezentând extremităţile celor m arce ale grafului, şi se constituie matricea de adiacenţă a, cu n linii *
n coloane.
Algoritmul de căutare a celebrităţii cuprins în procedura celebritate.
Pentru început, vom căuta o persoană pe care o vom numi în continuare candidat la celebritate.
Memorăm acest candidat în variabila candid. Presupunem că iniţial candidatul este persoana 1
(candid:=1). “Cercetăm” celelalte persoane, într-un ciclu cu i de la 2 la n. Pentru fiecare persoană i,
trebuie să facem o testare. În cazul în care candidatul “actual” candid o cunoaşte i (a[candid,i] este 1)
candid nu mai poate fi celebritate (celebritate nu trebuie să cunoască nici o altă persoană din grup !). În
această situaţie, noul candidat la celebritate devine i (candid:=1).
La finele parcurgerii de mai sus, în variabila candid vom avea aşadar un candidat la celebritate. Mai
rămâne să vedem dacă acest candidat este cunoscut de către celelalte persoane. În exemplul de mai
sus, urmare a faptului că persoana 3 este celebritate, avem relaţiile (1,3), (2,3) şi (4,3), adică
a[1,3]=a[2,3]=a[4,3]=0. În consecinţă, pe coloana 3 avem n-1 valori de 1. Pe caz general, trebuie să
numărăm valorile de 1 de pe coloana candid în matricea de adiacenţă, în adiacenţă, iar dacă găsim n-1
valori, atunci persoana candid este într-adevăr celebritate.
Program XI_8;
var n, m: integer; a: array[1..20, 1..20] of integer;
procedure citire_graf;
var i, j, k, x, y: integer;
begin
write('Nr. arce: '); readln(m);
write('Nr. noduri: '); readln(n);
{iniţializează cu 0 toata matricea de adiacenta}
for i:=1 to n do
for j:=1 to m do
a[i,j]:=0;
{citeşte m perechi (x,y) reprezentând arcele grafului}
for k:=1 to m do
begin

70
write('Arcul ',k,': ');
repeat
readln(x,y);
until (x>=1) and (x<=n) and (y>=1) and (y<=n) and (x<>y);
{pentru fiecare pereche marchează arcul in matricea de adiacenta}
a[x,y]:=1;
end;
end;

procedure celebritate;
var i, j, candid, nr : integer;
begin
candid:=1; {candid va reprezenta candidatul la celebritate, care iniţial este persoana 1}
for i:=2 to n do
{daca candidatul îl cunoaşte pe i, el nu mai poate fi celebritate noul candidat devine i}
if a[candid, i]=1 then candid:=i;
nr:=0; {numaram in nr cate persoane îl cunosc pe candidatul candid}
for i:=1 to n do
if a[i, candid]=1 then nr:=nr+1;
{verificam daca intr-adevăr candid este celebritate}
if nr=n-1 then writeln('Persoana ', candid,' este celebritate')
else writeln('Nu exista celebritate in grup');
end;

begin
citire_graf; celebritate;
end.
Drumuri si circuite in grafuri orientate
Se numeşte lanţ intr-un graf orientat, o mulţime de arce L={u 1,u2,...,uk}, cu proprietatea ca oricare doua
arce vecine in mulţime au o extremitate comuna.
Un lanţ este de fapt un traseu care uneşte prin arce doua noduri numite extremităţile lanţului, fără a tine
cont de orientarea arcelor componente.
Se numeşte drum în graful G, un şir de noduri D={z 1, z2, z3, …, zk}, unde z1, z2, z3, …, zk aparţin lui x, cu
proprietatea că oricare două noduri consecutive sunt adiacente, adică există arcele [z 1, z2], [z2, z3], …,
[zk-1,zk] aparţin lui U.
Practic, un drum poate fi privit ca un traseu în care toate arcele au aceeaşi orientare, dată de sensul de
deplasare de la z1 la zk.
Dacă nodurile z1, z2, z3, …, zk sunt distincte două câte două, drumul se numeşte elementar. În caz
contrar, drumul este ne-elementar.
Asemenea uni lanţ într-un graf neorientat, un drum într-un graf orientat este de fapt un traseu pe care l-
am parcurge între două noduri deplasându-ne de-a lungul unor arce şi trecând prin nişte noduri
intermediare. Deosebirea unui drum faţă de un lanţ constă în faptul că de-a lungul unui arc ne putem
deplasa numai în sensul dat de orientarea arcului.
Se numeşte circuit într-un graf, un lanţ L={z 1, z2, z3, …, zk} cu proprietatea că z1=zk şi arcele [z1, z2], [z2,
z3], …, [zk-1,zk] sunt distincte două câte două.
Dacă într-un circuit, toate nodurile cu excepţia primului şi ultimului sunt distincte două câte două, atunci
circuitul se numeşte elementar. În caz contrar, el este ne-elementar.

71
u2
1 2

u1
u3
u4 u5
3
4
5
u7 u6

6
Figura 8

Matricea drumurilor.
Este o matrice d cu n linii şi n coloane, în care fiecare element d[i,j] este :
- 1, dacă există drum de la nodul i la nodul j în graf;
- 0, în caz contrar.
Algoritmul Roy-Warshall de determinare a matricei drumurilor
Matricea drumurilor se obţine aplicând matricei de adiacenţă transformări succesive. Vom spune că
există drum de la nodul i la nodul j, dacă găsim un nod k (diferit de i, j) cu proprietatea că există drum de
la i la k şi drum de la j la k. Astfel:
 un element a[i, j] care este 0, devine 1, dacă există un nod k astfel încât a[i, k]=1 şi a[k, j]=1.
Pentru a găsi arcele nodului k, trebuie parcurse pe rând în varianta k toate nodurile 1, 2, …, n.
for k:=1 to n do
for i:=to n do {i≠k}
for j:=1 to n do {j≠k}
if (a[i, j]=0) and (i<>k) and (j<>k) then
a[i, j]:=a[i,k]*a[k, j];
Atribuirea a[i, j]:=a[i,k]*a[k, j] este o scriere elegantă a regulii de mai sus:
în cazul în care unul din elementele a[i,k], a[k, j] este 0, a[i, j] va rămâne 0;
dacă a[i, k]=1 şi a [k, j]=1, atunci a[i, j] devine 1.

Un CD valoros
Într-un grup sunt n elevi, băieţi şi fete, pe care-i numerotăm 1, 2, … , n. Fiecare elev cunoaşte o parte
dintre ceilalţi elevi. Relaţia de cunoştinţă nu este neapărat reciprocă (dacă x îl cunoaşte pe y, asta nu
înseamnă că şi y trebuie să îl cunoască pe x). Unul dintre elevi are un CD foarte valoros, cu multe
jocuri demonstrative, pe care toţi membri grupului vor să-l aibă fie şi pentru scurt timp, pentru a şi-l
copia pe calculatorul propriu. CD—ul circulă printre membrii grupului în felul următor: fiecare elev după
ce l-a primit de la altcineva îl dă mai departe, dar numai unui elev pe care îl cunoaşte, pentru că nu
doreşte să ajungă în mâna unor persoane în care nu poate avea încredere. Determinaţi o modalitate
(dacă există) prin care CD-ul să circule exact o singură dată pe la fiecare elev, transmiterea lui făcându-
se numai către o cunoştinţă, iar în final CD-ul să ajungă din nou la proprietarul său.
Interpretarea datelor
Relaţiile de cunoştinţă din cadrul grupului pot fi reţinute într-o matrice a cu n linii şi n coloane, în fiecare
element a[i, j] este: 1 dacă elevul i îl cunoaşte pe elevul j, respectiv 0 în caz contrar. Cu datele
problemei putem construi un graf în care nodurile sunt elevii 1, 2, 3,…, n, iar arcele sunt relaţiile de
cunoştinţă din grup. Astfel, va exista arc de la nodul x la nodul y dacă elevul x în cunoaşte pe elevul y.
Întrucât în enunţ se precizează că relaţiile de cunoştinţă nu sunt neapărat reciproce („x cunoaşte pe y”
nu implică „y cunoaşte pe x”), rezultă că avem de-a face cu un graf orientat. Matricea a definită mai
înainte este tocmai matricea de adiacenţă a grafului.
„Traseul” pe care îl parcurge CD-ul pleacă dintr-un nod (proprietarul său), trecând prin fiecare nod (pe la
fiecare elev) o singură dată. Transmiterea se face numai către o cunoştinţă. Astfel, de la elevul x va
ajunge la elevul y numai dacă există arc (cunoştinţă) de la x la y. În final, traseul se încheie în nodul de
unde a plecat (CD-ul se întoarce la proprietarul iniţial). Un traseu care respectă condiţiile de mai sus nu
este altceva decât un circuit elementar care trece prin toate nodurile grafului: drum deoarece poate

72
trece de la un nod la altul numai printr-un arc, elementar deoarece nu trece de două ori prin acelaşi nod,
şi în sfârşit circuit pentru că revine în nodul de plecare.
Rezolvare
Folosim metoda backtracking. Fiecare astfel de circuit elementar care trece prin toate nodurile grafului,
va fi o soluţie memorată în vectorul stivă st. Aşadar elementele vectorului st sunt noduri ale grafului.
O soluţie (st[1], st[2], …, st[p] ) este finală dacă
- conţine n nivele, adică p=n (au fost „puşi pe stivă” toţi cei n elevi, adică toate cele n noduri)
- st[n]=x (pentru a fi ciclu trebui să revină în nodul de plecare, adică „elevul de pe ultimul nivel”, st[n],
trebuie să fie proprietarul memorat iniţial în x).
Procedura {citire_matrice;} citeşte matricea de adiacenţă (relaţiile de cunoştinţă). În două cicluri for,
cu i, j=1, 2, …, n, se citesc toate elementele a[i, j]. Această procedură a fost prezentată ca aplicaţie în
lecţia „Reprezentarea grafurilor orientate”
Procedura {iniţializări;} realizează iniţializarea stivei şi a proprietarului CD-ului.
- într-un ciclu for, se iniţializează cu 0 întreg vectorul-stivă;
- se citeşte numărul de ordine al proprietarului CD-ului în variabila x (nodul de plecare).
Procedura {tipar(p:integer):} afişează o configuraţie (st[1], st[2], …, st[p]) a vectorului-stivă.

Funcţia {valid(p:integer):boolean;} verifică pentru fiecare nivel p dacă st[p]I a generat o soluţie
(st[1], st[2], …, st[p]) validă.
Testarea se face prin intermediul unei variabile booleene ok, iniţializează cu TRUE. În primul rând, din
nodul st[p-1] se poate ajunge în
nodul st[p] numai printr-un arc (orice drum/circuit trece prin arce). Aşadar nodul st[p] este valid numai
dacă există arc de la st[p-1] la st[p], adică a[st[p-1], st[p]]=1 (această condiţie provine din faptul că
fiecare elev va transmite CD-ul numai prin cunoştinţă, ia relaţia de cunoştinţă este marcată în graf printr-
un arc). În caz contrar ok devine FALSE.
ok:=TRUE;
if a [ st[p], st[p-1]]=0 then
ok:=FALSE;
Dacă ok a rămas TRUE, urmează testarea celei de-a doua condiţii. Am spus că soluţia este finală dacă
p=n, iar pe ultimul nivel trebuie să se găsească nodul x. Dar pe ultimul nivel anterior lui n nu putem
avea nodul x (CD-ul revine la proprietar, dar numai după ce a trecut pe la ceilalţi elevi, pe la fiecare o
singură dată).
if ok then
if (p<n) and (st[p]=x)
then
ok:=FALSE
Dacă ok a rămas în continuare TRUE, mai avem şi o a treia condiţie. Nodul st[p] să nu se mai
găsească pe stivă (urmare a faptului că CD-ul trebuie să treacă pe la fiecare elev o singură dată).
Parcurgem într-un ciclu nivelele i=1, 2, …, p-1 anterioare lui p. Dacă găsim un st[i] egal cu st[p],
înseamnă că st[p] se mai găsesc pe un nivel anterior, deci ok devine şi în cazul acesta FALSE.
if ok then
for i:=1 to p-1 do
if st[p]= st[i] then
ok:=FALSE
Procedura recursivă {bktr(p:integer);} “tratează” un nivel oarecare p al stivei.
 prin variabila val vor trece pe rând, într-un ciclu, toate valorile care teoretic ar putea fi puse pe
nivelul p. Pentru fiecare dintre aceste valori:
 dacă respectiva valoare a generat o soluţie validă (dacă funcţia valid(p) a returnat
TRUE), atunci:
- dacă soluţia respectivă e şi finală o tipărim (apelând procedura tipar (p)); în
caz contrar trecem la nivelul următor (pentru a completa soluţia cu un nou
nivel), prin auto-apelul bktr(p+1).
În programul principal, apelăm procedurile iniţializări şi citire_matrice, apoi declanşăm lanţul recursiv
prin apelul bktr(1) (plecăm de la nivelul 1 al stivei).
Program XI_10;
var n,x:integer;
st:array[1..20] of integer;
a:array[1..20,1..20] of integer;

procedure citire_matrice;

73
{citeste matricea de adiacenta a de la tastatura}
var I,j:integer;
begin
write (‘numarul de noduri: ’); readln(n);
for i:=1 to n do
for j:=1 to n do
begin
write (‘[‘, i, ’,’, j, ‘]=’); readln(a[i, j]);
end;
end;

procedure initializari;
{initializeaza stiva si citeste datele problemei}
var i:integer;
begin
write (‘Cine este proprietarul: ’); readln(x);
for i:=1 to 25 do st[i]:=0;
end;

procedure tipar (p:integer);


{tipareste o solutie memorata in vectorul st}
var k:integer;
begin;
write (x, ’ ’);
for k:=1 to p do write (st[k]:4, ‘ ’);
writeln;
end;

function valid (p:integer): boolean;


{testeaza daca valoarea pusa pe nivelul p a generat o solutie valida, returnand TRUE sau FALSE}
var nr, i:integer; ok:boolean;
begin
{CD-il poate circula numai intre elevii care se cunosc, deci elevul st[p-1] trebuie sa il cunoasca pe st[p]
pentru a-i putea da CD-ul mai departe}
ok:=TRUE;
if a[st[p-1], st[p]]=0 then ok:=FALSE;
if ok then
{proprietarul x nu se poate gasi pe un nivel anterior ultimului}
if (p<n) and (st[p]=x) then ok:=FALSE;
if ok then
{elevul st[p] nu trebuie sa se mai gaseasca pe nivelele anterioare}
for i:=1 to p-1 do
if st[p]= st[i] then ok:=FALSE;
valid:=ok;
end;

procedure bktr (p:integer);


{implementeaza algoritmul de backtracking recursiv}
var val:integer;
begin
{in variabila val trec pe rand toate valorile care ar putea fi incercate pe nivelul p al stivei}
for val:=1 to n do
begin
st[p]:=val; {pune o noua valoare pe nivelul p}
if valid(p) then {daca solutia obtinuta e valida}
{o solutie e finala daca CD-ul a trecut pe la n elevi (p=n) si ultimul e proprietarul (st[p]=x)}
if (p=n) and (st[n]=x) then tipar (p) {daca e si finala, tipareste solutia}
else bktr (p+1); {trece la nivelul urmator in stiva, pentru a completa solutia}
end;
end;

74
begin;
initializai; citire_matrice; bktr(1); {plecam de la nivelul 1 pe stiva}
end.

Definitie :
Numim graf orientat ,o pereche ordonata de multimi G=(X,U), unde :
- x este o multime finita si nevida numita miltimea nodurilor (varfurilor);
- U este o multime formata din perechi ordonate de elemente ale lui X,numita multimea
arcelor (muchiilor).

Definitie
Se numeste p-graf ,un graf orientat in care numarul arcelor identice este mai mic sau egal cu o valoare
data p.

Exista mai multe metode de reprezentare in memorie a unui graf orientat:


1-metoda matricei adiacente:
1, pentru[I,j] apartin de g
a[I,j]=
0, pentru[I,j]nu apartinde g

Gradul unui varf . Multimea Γsi ω


Matricea costurilor

Pentru evidentierea costurilor tuturor arcelor unui graf cu n noduri se poate defini o matrice a, cu
n linii * n coloane.Exista doua forme ale acestei matrici:
Forma a): Fiecare element a[i,j] poate fi:
c , daca exista un arc de cost c>0 intre nodurile i si j;
0, daca i=j;
+∞ ,daca nu exista arc intre nodurile i si j .

Forma b): Este absolut similara,cu singura deosebire ca in loc de +∞ avem -∞.
Forma a) se foloseste pentru determinarea drumurilor de cost minim intre doua noduri , iar forma b)
este utilizata in aflarea drumurilor de cost maxim.
Daca dorim sa citim matrice costurilor ,evident ca nu putem introduce de la tastatura “+”! In loc de +
vom da un numar intreg foarte mare.

75
Definitie
Gradul exterior al unui varf x, notat d+(x), reprezinta numarul arcelor care ies din nodul x,adica
numarul arcelor de forma (x,y)
apartine de U.
Analog , se defineste gradul interior al unui varf x, notat d¯(x), ca fiind numarul arcelor care intra
in nodul x (de forma (x,y) apartine U)
Reprezentarea grafurilor orientate

Consideram un graf orientat G=(X,U) cu m arce si n noduri.


Cele mai cunoscute forme de reprezentare sunt : matricea de adiacenta , matricea varfuri-arce,
matricea drumurilor si listele vecinilor.

Matricea de adiacenta

Are aceeasi semnificatie ca in cazul grafurilor neorientate :fiecare element a[I,j] ,cu I,j apartine de
{1, 2,….,n} ,este: 1 daca exista arcul (I,j), respectiv 0 in caz contrar.
Datorita orientarii, asa cum am mai spus , arcul (I,j) nu este totuna cu arcul (j,I).Prin urmare ,
a[I,j]≠a[j,I].Asadar matricea de
adiacenta nu mai este simetrica fata de diagonala principala , asa cum se intampla in cazul grafurilor
neorientate .

Matricea varfuri-arce

Este o matrice b cu n linii si m coloane, in care fiecare element b[I,j] este;


● 1, daca nodul i este o extremitate initiala a arcului uj;
● -1, daca nodul I este o extremitate finala a arcului uj;
● 0, daca nodul I nu este o extremitate a arcului uj;

Listele vecinilor

Pentru fiecare nod x se construiesc doua liste ale vecinilor sai:


► L+(x) → lista vecinilor succesori ; contine nodurile ce sunt extremitati finale ale arcelor care ies
din nodul x.
► L‾ (x) → lista vecinilor predecesori ; contine nodurile ce sunt extremitati initiale ale arcelor care
intra in nodul x.
Matricea drumurilor
procedure formarea_matrice_drumuri;
{formeaza matricea drumurilor (memorata tot in a), cu algoritmul Roy-Warshall}
var i,j,k:integer;
begin
for k:=1 to n do
for i:=1 to n do
for j:=1 to n do
if a[i,j]=0 then a[i,j]:=a[i,k]*a[k,j];
end;
Grafuri neorientate
Definiţie. Se numeşte graf neorientat o pereche ordonată de mulţimi (X, U), X fiind o mulţime
finită şi nevidă de elemente numite noduri sau vârfuri, iar U o mulţime de perechi neordonate
( submulţimi cu două elemente) din X, numite muchii.
Ex.

2 6
1 +8

76
3
5

7
4
Fig.1

Pentru graful de mai sus avem:


X={1, 2, 3, 4, 5, 6, 7, 8}
U={[1,2], [1,4], [1,5], [2,3], [2,5], [3,4], [6,7]}
Dacă u1 şi u2 sunt două muchii care au o extremitate comună ele se vor numi adiacente.
Definiţie. Un graf parţial al grafului G=(X,U) este un graf G 1=(X,V) astfel încât VU, adică G1
are aceeaşi mulţime de vârfuri ca G iar mulţimea de muchii V este chiar U sau o submulţime a acesteia.
Ex. Mai jos avem un graf parţial al grafului de mai sus (Fig.1)
6
2 +8
1
3
5

7
4
Fig.2

Cu alte cuvinte, un graf parţial al unui graf se obţine păstrând aceeaşi mulţime de vârfuri şi
eliminând o parte din muchii.
Definiţie. Un subgraf al unui graf G=(X,U) este un graf H=(Y,V) astfel încât Y  X iar V conţine
toate muchiile din U care au ambele extremităţi în Y. Vom spune că subgraful H este indus sau generat
de mulţimea de vârfuri Y.
Ex. Mai jos avem un subgraf al grafului din Fig.1 obţinut prin eliminarea nodului 3

2 6
+8
1
5

7
4
Definiţie. Gradul unui vârf x este numărul muchiilor incidente cu x.
Gradul vârfului x se notează cu d(x).
Ex. în Fig.1 d(1)=3, d(4)=2, d(8)=0, d(6)=1
Un vârf care are gradul 0 se numeşte vârf izolat.
Un vârf care are gradul 1 se numeşte vârf terminal.
Propoziţia 1. Dacă un graf G=(X,U) are m muchii şi n vârfuri iar X={x 1,x2,..,xn}, atunci
d(x1)+d(x2)+...+d(xn)=2m.
Corolar. În orice graf G există un număr par de vârfuri de grad impar.
Definiţie. Se numeşte graf complet cu n vârfuri un graf care are proprietatea că orice două
noduri diferite sunt adiacente.
Propoziţia 2. Un graf complet Kn are n(n-1)/2 muchii.
Definiţie. Un graf G=(X,U) se numeşte bipartit dacă există două mulţimi nevide A, B astfel
încât X=A U B, A  B = şi orice muchie u a lui G are o extremitate în A iar cealaltă în B.
Definiţie. Un graf bipartit se numeşte complet dacă pentru orice x din A şi orice y din B, există
în G muchia [x,y].

Definitie.Un drum al unui graf orientat L=[x0,x1,x2,…xp] este o succesiune de


varfuri cu proprietatea ca [x0,x1]aparrtine de g, [x1,x2] la fel, s.a.
-x0 si xp = extremitatile drumului;
-p=lungimea drumului;
-daca x0,x1,…,xp sunt distincte doua cate doua drumul=elementar;

77
-daca x0=xp,drumul=circuit
-daca toate varfurile circuitului, cu exceptia primului si ultimului sunt distincte,
circuitul=elementar;
-un circuit elementar care trece prin toate nodurile grafului se numeste circuit
hamiltonian.
Definitie.Daca multimea g are proprietatea de simetrie, graful se numeste neorientat.
Definitie.Un graf partial al unui graf neorientat dat G=(X,G) este un graf G1=(X,g1 unde G1 inclus
sau=cu G.
Definitie.Un subgraf al unui graf neorientat G=(X,g) este un graf H=(Y<G1), unde Y inclus in X, iar
muchiile din G1 sunt toate muchiile din G care au ambele extremitati in multimea Y.
Definitie.Lant.Pentru graful neorientat , un lant este o succesiune de varfuri cu proprietatea ca oricare
doua varfuri sunt adiacente.

Graf complet si bipartit

Se numeste graf complet cu n varfuri , notat Kn , un graf G=(X,U) cu proprietatea ca oricare doua
varfuri sunt adiacente adica :
() x,y є x → ca exista muchia [x,y] apartine de U
Teorema:
Un graf complet cu n varfuri , are n(n-1)/2 muchii.
Definitia :
Se numeste graf bipatrat ,un graf G=(X,U) cu propietate ca exista doua multimi A si B incluse in X,
astfel incat :
-A ∩ B=Ø ,A U B=X,
-toate muchiile grafului au o extremitate in A si cealalta in B .
Definitie :
Se numeste graf bipatrat complet, un graf bipatrat cu propietatea ca pentru orice varf x din A si orice
varf y din B,exista muchia (x,y) (unde A si B sunt cele doua submultimi care partitioneaza miltimea
varfurilor X).

Notiunea de lant si ciclu

Definitie :
Se numeste lant in graful G ,o succesiune de varfuri (z1, z2,z3 ,….zk),unde x1,x2,…,xk apartine de X ,
cu propietatea ca oricare doua varfuri consecutive sunt adiacente ,adica exista muchiile [z1, z2],[z2 ,z3],
….,[zk-1,zk] apartine de U.
Varfurile z1 si zk se numesc extremitatile lantului ,iar numarul de muchii care intra in componenta sa
reprezinta lungimea lantului .
Definitie :
Se numeste ciclu intr-un graf ,un lant L=(z1,z2,….zk) cu propietatea ca z1=zk si muchiile [z1,z2 ],
[z2,z3], ….,[zk-1,zk] sunt disticte doua cate doua.
Daca intr-un ciclu , toate varfurile cu exceptia primului si a ultimului sunt disticte doua cate
doua ,atunci
ciclul se numeste elementar .In contrar, el este neelementar.

Problema rezolvata
Lant intr-un graf

Sa se verifice daca o secventa de varfuri data reprezinta un lant elementar si neelementar intr-un graf
neorientat. Numarul de varfuri si matricea de adiacenta se citesc de la tastatura, iar secventa testata se
gaseste in fisierul “lant .txt”(varfurile sunt scrise in fisier pe un singur rand separate prin spatii).

program X1-5;

uses crt;
var a:array[1..20,1..20] of integer ;
n,I,j,k:integer;

78
z:array[1..20] of integer;
procedure citire matrice;
{citeste numarul de muchi si muchiile de forma (x,y),si construieste matricea de adiacenta}
var I,j,x,y:integer
begin
{citeste numarul de varfuri n}
write (‘numarul de varfuri :’) ;
readln (n) ;
{initializeaza cu 0 diagonala principala}
for I:=1 to n do a[I,i]:=0;
{citeste portiunea din matrice situata deasupra diagonalei principala}
for I:=1 to n-1 do
for j:=I+1 to n do
begin
writeln (‘exista muchie intre’ ,I,’ si ‘,j, ‘ ? [1/0] ‘);
{citeste elementul a[I,j] cu validare (el trebuie sa fie 0 sau 1)}
repeat
readln (a[I,j]);
until (a[I,j]=0 ) or (a[I,j]=1);
a[j,i] :=a[I,j];
end;
end;

procedure secventa ;
var f:text; ok:boolean;
begin
assign(f, ‘lant./txt’); reset(f);
{citeste secventa de varfuri din fisier in vectorul z=(z[1],z[2],…,z[k])
k:=0;
while not seekeoln (f) do
begin
k:=k+1; read(f,z[k]);
end;
close (f);
{afiseaza vectorul z ce contine secventa}
for I:=1 to k do write(z[I], ‘ ‘);
writeln ;
{verifica daca doua varfuri consecutive in secventa sunt adiacente (daca secventa e lant)}
ok:=TRUE;
for I:=1to k-1 do
if a[z[I],z[I+1]]=0 then ok:=FALSE;
if ok then write (‘lant’)
else writeln (‘secventa nu este in lant ‘);
if ok then
begin
{in cazul in care e lant ,testeaza daca varfurile sunt disticte intre ele(adica lant elementar ) }
for I:=1 to k-1 do
for j:=I+1 to k do
if z[I]=z[j] then ok:=FALSE;
if ok then writeln (‘elementar’)
else writeln (‘ne-elementar ‘);
end;
end;
begin
citire_matrice; secventa ;
end.

8.3 Parcurgerea grafurilor orientate

79
1.Parcurgerea in latime(BF-breadth first)
-parcurgerea in latime se face incepand de la un nod I, pe care il consideram parcurs;
-parcurgem apoi toti descendentii sai – multimea nodurilor j pentru care exista
[I,j]apartin de g;
-parcurgem apoi toti descendentii nodurilor parcurse la pasul anterior.
Parcurgerea BF se efectueaza prin utilizarea structurii numita coada, avand grija ca un
nod sa fie vizitat o singura data. Coada va fi alocata prin utilizarea unui vector.

PARCURGEREA GRAFURILOR
{Parcuregerea in latime nerecursiv si recursivla =>1 2 3 4 6 5 }
grafuri uses crt;
ex: var a:array[1..20,1..20] of integer;
n=6 co,vi:array[1..20] of integer;
8 muchii si anume (1,2),(1,3)(1,4),(2,4),(2,3),(3,4), i,n,el,j,p,u,pl,m,x,y:integer;
(3,6),(4,5)

80
procedure pp(i:integer); for i:=1 to u do
var j:integer; write(co[i],' ');
begin readln;
for j:=1 to n do end.
if (a[co[i],j]=1) and( vi[j]=0) then begin
u:=u+1; {Parcuregerea in adincime la grafuri neorientate
co[u]:=j; ex:n=5
vi[j]:=1; m=4
end; si anume (1 2),(1 5), ( 2 3),(2 4)
if i<=u then pp(i+1); nodul de pelecare este 1 =>
end; 12345
begin }
clrscr; uses crt;
writeln(' n=');readln(n); var a:array[1..20,1..20] of integer;
writeln(' nuamrul de muchii ');readln(m); vi:array[1..20] of integer;
for i:=1 to m do i,n,el,j,p,u,pl,m,x,y:integer;
begin
writeln('dati muchia ',i); procedure pp(pl:integer);
writeln( 'primul nod al muchiei ');readln(x); var j:integer;
writeln(' nodul de sfirsit al muchiei ');readln(y); begin
a[x,y]:=1;a[y,x]:=1; write(pl,' ');vi[pl]:=1;
end; for j:=1 to n do
for i:=1 to n do if (a[pl,j]=1) and (vi[j]=0) then pp(j);
vi[i]:=0; end;
writeln(' care este nodul de plecare ');readln(pl);
vi[pl]:=1;
co[1]:=pl; begin
p:=1; clrscr;
u:=1; writeln(' n=');readln(n);
while p<=u do writeln(' numarul de muchii ');readln(m);
begin for i:=1 to m do
el:=co[p]; begin
for j:=1 to n do writeln('dati muchia ',i);
if (a[el,j]=1) and (vi[j]=0) then begin writeln( 'primul nod al muchiei ');readln(x);
u:=u+1; writeln(' nodul de sfirsit al muchiei ');readln(y);
co[u]:=j; a[x,y]:=1;a[y,x]:=1;
vi[j]:=1; end;
end; for i:=1 to n do
p:=p+1; vi[i]:=0;
end; writeln(' care este nodul de plecare ');readln(pl);
for i:=1 to u do pp(pl);
write(co[i],' '); readln;
pp(1); end.
writeln(' parcurgere recursiva in latime ');

8.4 Conexitate/ tare conexe ,determinarea componentelor conexe/tare


conexe
Graf conex
CONEXITATE

Fie G=(X, U) un graf neorientat, X={x1, x2, ..., x2}.


Definiţie. Se numeşte lanţ în G succesiunea de vârfuri L={x i1, xi2,..., xik} cu proprietatea că orice două
noduri consecutive din L sunt adiacente, adică [xi1, xi2], [xi2, xi3],..., [xik-1, xik]  U.
Dacă vârfurile xi1, xi2,..., xik sunt diferite două câte două atunci lanţul se numeşte elementar. În caz
contrar, lanţul este neelementar.
1 2 5

81
8
7

3 4 6

Ex. L1=[1,2,4] – lanţ elementar


L2=[1,2,3,1,2,4] – lanţ neelementar
Definiţie. Se numeşte ciclu în G un lanţ L pentru care x i1=xik şi toate muchiile adică [x i1, xi2], [xi2, xi3],...,
[xik-1, xik] sunt diferite două câte două.
Ex. C=[1,2,3,1] este un ciclu.
Definiţie. Se numeşte ciclu elementar un ciclu care are proprietatea că oricare două vârfuri ale sale,
cu excepţia primului şi ultimului, sunt diferite două câte două.
Ex. C1=[1,2,3,1] este ciclu elementar.
C2=[3,1,2,4,8,2,3] este un ciclu neelementar.
Definiţie. Un graf G se numeşte conex dacă pentru orice două vârfuri x şi y diferite ale sale există un
lanţ care le leagă.
Definiţie. Se numeşte componentă conexă a grafului G=(X, U) un subgraf C=(X 1, U1), conex, a lui G
care are proprietatea că nu există nici un lanţ în G care să lege un vârf din X 1 cu un vârf din X-X1.

Un graf G este conex , daca oricare ar fi doua varfuri ale sale ,exista un lant care le leaga.
Definitie:
Se numeste componenta conexa a grafului G=(X,U),un subgraf G1=(X1,U1) a lui
G ,conex , cu propietatea ca nu exista nici un lant care sa lege un nod din X1 cu un nod din X-
X1(pentru orice nod , nu exista un lant intre acel nod si nodurile care nu fac parte din subgraf).
Program componenteconexe; {pentru fiecare pereche,
var m,n ,pi,ps,prim, p, actualizeaza cu 1 elementele
nc:integer; a[x,y] si a[y,x] care
a:array[1..20,1..20] of identifica muchia (x,y)}
integer; for k:=1 to mdo
d,c,viz:array[1..20] of begin
integer; writeln(‘Dati muchia cu
procedure citire_graf; numarul de ordine’,k,’:’);
{citeste numarul de muchii si repeat
muchiile de forma (x,y), si readln(x,y);
construieste matricea de until(x>=1) and (x<=n)
adiacenta} and (y>=n) and (y<=n);
var I,j,k,x,y:integer; a[x,y]:=1; a[y,x]:=1;
begin d[x]:=d[x]+1; d[y]:=d[y]
{citeste numarul de varfuri n +1;
si numarul de muchii m} end;
write (‘Numarul de varfuri :’); end;
readln(n);
write (‘Numarul de function nevizitat :integer;
muchii:’); readln(m); {parcurge tabloul viz:
{initializeaza cu 0 intreg returneaza primul nod
vectorul gradelor d} nevizitat,sau –1 daca nu mai
for i:=1 to n do d[i]:=0; sunt noduri nevizitate}
{initializeaza cu 0 toata var prim_nev,j:integer:
matricea de adiacenta} begin
for i:=1 to n do prim_nev:=-1;
for j:=1 to n do j:=1;
a[i,j]=0; while (j<=n) and
{citeste m perechi de numere (prim_nev= -1) do
intregi de forma (x,y)} begin

82
if viz[j]=0 then if (a[z,k]=1) and (viz[k]=0)
prim_nev:=j; then
j:=j+1; begin
end; pi:=pi+1; c[pi]:=k;
nevizitat:=prim_nev; viz[k]:=1;
end; end;
ps:=ps+1;
function conex:boolean; end;
{verifica daca varful este for k:=1 to pi do write(c[k]:3);
conex,returnand TRUE sau FALSE} if nevizitat=-1 then conex:=TRUE
var k,pi,ps,z:imteger; else conex:=
begin FALSE;
{face o parcurgere a grafului cu
algoritmul BF, plecanddin nodul de end;
start prim} begin
for k:=1 to 20 do c[k]:=0; writeln(‘Afisam componentele
for p;=1 to 20 do viz[p]:=0; conexe:’);
write (‘Dati varful de plecare’); citire_graf; writeln;
readln(prim); if conex:=TRUE then
pi:=1; ps:=1; writeln (‘Graful este conex’)
c[1]:=prim; viz[prim]:=1;
while ps<pi do else
begin writeln(‘Graful NU este conex’);
z:=c[ps]; end.
for k:=1 to n do
Graf tare conex .Componente tare conexe

Definitie:
Un graf orientat G=(X,U) este tare conex, daca pentru oricare doua noduri x si y apartin
de X, exista un drum de la x la y precum si un drum de la y la x.

Definitie
Fiind dat un graf orientat G=(X,U), se numeste componenta tare conexa a lui G ,un
subgraf G1=(X1,U1),tare conex, si maximal in raport cu aceasta propietate (adica pentru orice
nod x apartine de X-X1, subgraful indus de X1 U{x} nu mai este tare conex).
APLICATIE
Algoritmul de descompunere a unui graf in componente tare conexe .
Componenta tare conexa din care face parte nodul i, este multimea :
S[i] ∩ P[i] U{i}

program tare_conexe; write(‘Dati numele


type multime=set of byte; fisierului ‘);
var a:array[1..20,1..20] of integer ; readln(nume_fis);
S,P,C:array[1..20] of multime; assign(f,nume_fis);
n,nc: integer; L:multime; reset(f);
readln(f,n);
procedure citire_matrice; for i:=1 to n do
{citeste numarul de noduri n si begin
matrice de adiacenta a ,din fisierul for j:=1 to n do
text} read(f,a[i,j] );
var i,j:integer; nume_fis:string; readln(f);
f:text; end;
begin end;

83
procedure afisare_matrice; procedure
{afiseaza matricea de det_tare_conexe;
adiacenta } {descompune graful in
var i,j:integer; componente tare conexe}
begin var i,k:integer;
writeln (‘Graful are ‘ ,n, begin
‘ varfuri’); L:=[ ]; {initializeaza
writeln( ‘Matricea de multimea L a nodurilor
adiacenta este ‘); care au fost incluse in
for i:=1 to n do vreo componenta}
begin nc:=0; {initializeaza
for j:=1 to n do numarul componentelor
write(a[i,j]:2) ; tare conexe}
writeln; for i:=1 to n do
end; {parcurge nodurile de la i
end; 1 la n}
if not (i in L) then
procedure {daca nodul i nu a fost
formarea_matrice_drumur deja inclus in vreo
i; componenta}
{formeaza matricea begin
drumurilor (memorata tot {inaugureaza o
in a), cu algoritmul Roy- noua componenta ,deci
Warshall} creste numarul
var i,j,k:integer; componentelor}
begin nc:=nc+1;
for k:=1 to n do det_S(i);
for i:=1 to n do {determina S[i]}
for j:=1 to n do det_P(i);
if a[i,j]=0 then {determina P[i]}
a[i,j]:=a[i,k]*a[k,j]; C[i]:=(S[i]*P[i] ) +
end; [i]; {calculeaza
componenta tare conexa
procedure det_S C[i]}
(i:integer); {determina {adauga C[i] la
multimea S[i]} multimea nodurilor care
var k:integer; fac deja parte dintr-o
begin componenta}
S[i]:=[ ]; L:=L+C[i];
for k:=1 to n do {tipareste
if a[i,k]=1 then componenta conexa C[i]}
S[i]:=S[i]+[k] ; writeln
end; (‘Componenta conexa ]
‘,nc, ‘este ‘ );
procedure det_P for k:=1 to n do
(i:integer); {determina if k in C[i] then
multimea P[i]} write(k:3);
var k:integer; writeln;
begin end;
P[i]:=[ ]; end;
for k:=1 to n do
if a[k,i]=1 then begin
P[i]:=P[i] +[k]; citire_ matrice;
end; afisare_matrice;

84
formare_ close(f);
matrice_drumuri; end;
afisare_matrice; det_
tare_conexe; procedure
end. Roy_Warshall;
COMPONENTE TARE var i,j,k:byte;
CONEXE begin
EX: for k:=1 to n do
{Se considera o multime for i:=1 to n do
formata din n persoane in for j:=1 to n do
care fiecare persoana if a[i,j]=0 then
se cunoaste pe sine si a[i,j]:=a[i,k]*a[k,j];
eventual alte persoane. Sa end;
se formeze grupuri in
care fiecare persoana sa procedure componente;
var k,i,j:byte;
cunoasca toate celelalte viz:array[1..50] of
persoane din grup( o boolean;
persoana apartine unui begin
singur grup). for i:=1 to n do
Relalia „ x cunoaste pe y" viz[i]:=false;
nu este in mod normal nici k:=1;
simetrica, nici tranzitiva. for i:=1 to n do
if not viz[i] then
Rezolvare begin
Rezolvarea se bazeaza pe writeln('Componenta',k,':
algoritmul de determinare ');
a componentelor tare write(i,' ');
conexe intr-un viz[i]:=true;
graf orientat.} for j:=1 to n do
if(j<>i)and
program tareconexe; (a[i,j]<>0)and(a[j,i]<>0)th
type en
mat=array[1..50,1..50] of begin
byte; write(j,' ');
var f:text; viz[j]:=true;
n:byte; end;
a:mat; k:=k+1;
procedure citeste; writeln
var i,x,y:byte; end;
begin end;
assign(f,'in7.pas');
reset(f); begin
readln(f,n); citeste;
Roy_Warshall;
while not eof(f) do componente;
begin readln;
readln(f,x,y); end.
a[x,y]:=1;
end;

85
8.5 Drumuri minime si maxime in grafuri
orientate(Dijkstra,Roy-Floyd)

Consideram un graf orientat G=(X,U) cu n noduri, in care fiecarui arc ii este asociat un numar
intreg numit cost. Semnificatia
acestui cost poate fi foarte variata , in functie de domeniul pe care il descrie graful .

Matricea costurilor

Pentru evidentierea costurilor tuturor arcelor unui graf cu n noduri se poate defini o matrice a, cu
n linii * n coloane.Exista doua forme ale acestei matrici:
Forma a): Fiecare element a[i,j] poate fi:
c , daca exista un arc de cost c>0 intre nodurile i si j;
0 , daca i=j;
+∞ ,daca nu exista arc intre nodurile i si j .

Forma b): Este absolut similara,cu singura deosebire ca in loc de +∞ avem -∞.
Forma a) se foloseste pentru determinarea drumurilor de cost minim intre doua noduri , iar
forma b) este utilizata in aflarea drumurilor de cost maxim.
Daca dorim sa citim matrice costurilor ,evident ca nu putem introduce de la tastatura “+”! In
loc de + vom da un numar intreg foarte mare.
Algoritmul lui Dijkstra

Se consideră un graf neorientat, conex cu N noduri. Graful este dat prin matricea
costurilor A.

c, dacã existã un arc c între nodurile i si j



Aij  0, daca i  j
x, dac nu exista un arc intre nodurile i si j

Se consideră un nod iniţial R. Se cer lungimile drumurilor minime de la R la celelalte noduri ale
grafului, precum şi nodurile prin care trec aceste drumuri.
Problema are numeroase aplicaţii practice. Să presupunem că dispunem de o hartă cu oraşele
unei ţări. Acestea sunt unite prin şosele. Oraşele formează nodurile grafului, iar şoselele – arcele
acestuia. Algoritmul furnizează drumurile optime de la un oraş iniţial la celelalte oraşe. Este
interesant de observat faptul că, spre deosebire de alţi algoritmi, acesta furnizează şi nodurile
prin care trec drumurile optime, nu numai lungimile acestora.

Exemplu: Se consideră graful din figură:

86
Pentru acest graf matricea costurilor este:

0  13  16 8 
 
 0  6  10 
13  0 14  11 
 
 6 14 0 5 17 
16   5 0 7 

8 10 11 17 7 0 

Întrucât graful este neorientat, matricea este simetrică.


Algoritmul selectează nodurile grafului, unul câte unul, în ordinea crescătoare a costului
drumului de la nodul R la ele, într-o mulţime S, care iniţial conţine numai nodul R. În felul
acesta ne încadrăm în strategia generală GREEDY. În procesul de prelucrare se folosesc trei
vectori: D,S şi T.
Vectorul D este vectorul costurilor de la nodul R la celelalte noduri ale grafului. Prin D(I), unde
I{1..N}, se înţelege costul drumului găsit la un moment dat, între nodul R şi nodul I.
Vectorul T indică drumurile găsite între nodul R şi celelalte noduri ale grafului.
Vectorul S (vector caracteristic) indică mulţimea S a nodurilor selectate. S(I)=0 dacă nodul I este
neselectat şi S(I)=1 dacă nodul I este selectat.

Prezentarea algoritmului.
P1) Nodul R este adăugat mulţimii S iniţial vidă (S(R)=1);
- costurile drumurilor de la R la fiecare nod al grafului se preiau în vectorul D de pe linia R
a matricii A;
- pentru toate nodurile I având un cost al drumului de la R la ele finit, se pune T(I)=R.
P2) Se execută de n-1 ori secvenţa
- printre nodurile neselectate se caută cel aflat la distanţa minimă faţă de R şi se selectează
adăugându-l mulţimii S;
- pentru fiecare din nodurile neselectate se actualizează în D costul drumurilor de la R la
el, utilizând ca nod intermediar nodul selectat, procedând în felul următor: se compară distanţa
existentă în vectorul D cu suma dintre distanţa existentă în D pentru nodul selectat şi distanţa de
la nodul selectat la nodul pentru care se face actualizarea distanţei (preluată din A), iar în cazul
în care suma este mai mică, elementul din D corespunzător nodului pentru care se face
actualizarea capătă ca valoare aceasă sumă şi elementul din T corespuzător aceluiaşi nod ia
valoarea nodului selectat (drumul trece prin acest nod). Presupunând că a fost selectat nodul K,
se actualizează distanţa pentru nodul L şi se compară D(K)+A(K,L) cu D(L).

87
P3) Pentru fiecare nod al grafului, cu excepţia lui R, se trasează drumul de la R la el.

Pentu acest exemplu se consideră R=1.


Linia 1 a matricei A aste încărcată în vectorul D, vectorii S şi T au iniţial valorile care
se observă:
D 0  1  1
3 6 8

S 1 0
0 0 0 0

T 0 0
1 0 1 0

Se selectează nodul 6 (costul drumului minim).


Se actualizează conţinutul vectirilor D, S şi T.

D(6)+A(6,2)=8+10=18< D(2)=18 şi T(2)=6


D(6)+A(6,3)=8+11=19>13D(3)=13.
D(6)+A(6,4)=8+17=25< D(4)=25 şi T(4)=6.
D(6)+A(6,5)=8+7=15<16 D(5)=15 şi T(5)=6.

1 1 2 1
D 0 8 3 5 5 8

S 1 0 0 0 0 1

T 0 6 1 6 6 1

Se selectează nodul 3.
D(3)+A(3,2)=13+>18D(2)=18.
D(3)+A(3,4)=13+14=27>25D(3)=13.
D(3)+A(3,5)=13+>15D(5)=15.

0 1 1 2 1
D 8 3 5 5 8

S 1 0
1 0 0 1

T
0 6 1 6 6 1

Se selectează nodul 5.
D(5)+A(5,2)=15+>18D(2)=18.
D(5)+A(5,4)=15+5=20D(4)=20 şi T(4)=5.

1 1 2 1
D 0 8 3 0 5 8

88
S 1 0 1 0 1 1

T 0 6 1 5 6 1

Se selectează nodul 2.
D(2)+A(2,4)=18+6=24>20D(4)=20.

1 1 2 1 8
D 0 8 3 0 5

S 1 1 1 0 1 1

1
T 0 6 1 5 6

Se selectează nodul 4.
În continuare, pentru fiecare nod se trasează drumul de la nodul iniţial la el.
Vom considera, ca exemplu, nodul 4. Distanţa de la nodul 1 la el D(4) şi anume 20.
Avem T(4)=5; T(5)=6; T(6)=1; drumul trece prin nodurile 1,6,5.
Avem A(1,6)=8; A(6,5)=7; A(5,4)=5.Rezultă 8+5+7=20.
Întrucât drumul se trasează în ordine inversă faţă de cum este găsit, în program se foloseşte o
procedură recursivă.
În cele ce urmează vom nota nodurile cu Ni1,Ni2,…,Nin. Acestea sunt tot nodurile 1,2,…,R,
…,N cosiderate în altă ordine. Nodului R îi corespunde nodul Ni1.

Demonstrarea algoritmului.

Lema 1. Algoritmul selectează nodurile în ordinea costului drumului de la nodul iniţial la ele.

Demonstraţie:
Utilizăm metoda inducţiei matematice. Prima dată se selectează nodul Ni2 (are costul drumului
minim faţă de Ni1). Aceasta înseamnă că ipoteza de inducţie se verifică pentru prima selecţie.
Presupunem că nu au fost selectate nodurile Ni2,Ni3,…,Nip (p<n) în ordinea costului drumului
de la Ni1 la ele. Se selectează nodul Nip+1. Presupunem, prin absurd, că există un alt nod N1,
neselectat, care are un cost al drumului de la Ni1 la el mai scăzut decât al nodului Nip+1. Atunci,
acesta poate fi plasat în şirul nodurilor deja selectate, aşezate în ordinea distanţei faţă de Ni1, în
următoarele două moduri:
1) Ni1,…,N1,…,Nip,Nip+1.
În acest caz, se contrazice ipoteza de inducţie (nodurile Ni1,…,Nip erau aşezate în ordine
distanţei faţă de Ni1).

2) Ni2,…, Nip,N1,Nip+1.
Aici este contrazisă alegerea lui Nip+1. Acesta a fost ales ca nod cu distanţă minimă faţă de Nil
dintre toate nodurile neselectate, iar N1 este un nod neselectat.

Lema 2. Orice drum optim de la nodul iniţial la oricare din nodurile selectate trece numai prin
noduri selectate.

Demonstraţie:
Presupunem prin absurd că există un drum de cost mai mic de la Ni1 la Nik (Nik este un nod
deja selectat) care nu trece numai prin noduri selectate. Fie Nz primul nod prin care trece acest
drum şi care nu este selectat. Aceasta înseamnă că nodul Nz are costul drumului de la Ni1 la el
mai mic decât cel de la Ni1 la Nik (nod care este selectat). Aceasta contrazice LEMA 1.

TEOREMĂ.

89
Odată selectat un nod, nu există un drum de cost mai mic între Ni1 şi el, decât drumul de cost
indicat de vectorul D.

Demonstraţie:
În demonstrarea acestui fapt utilizăm metoda inducţiei matematice.
Pentru selectarea lui Ni2 afirmaţia este evidentă, întrucât acesta este cel mai apropiat de Ni1.
Presupunem selectate nodurile Ni2,…,Nip. Selectăm Nip+1. Presupunem că de la Ni1 la el există
un drum de cost mai mic decât cel indicat de vectorul D.
Avem două posibilităţi:

1) Drumul de cost mai mic trece numai prin noduri selectate.


Analizăm modul de funcţionare a algoritmului până în acest moment.
La selecţia nodurilor Ni1,…,Nip s-au actualizat distanţele reţinute în vectorul D (pentru fiecare
nod neselectat s-a comparat vechea distanţă reţinută în D cu suma dintre distanţa de la Ni1 la
nodul selectat şi distanţa de la nodul selectat la nodul pentru care se face actualizarea, iar în cazul
în care suma din urmă era mai mică, aceasta era reţinută în vectorul D). În concluzie, nu există
un drum mai scurt între Ni1 şi Nip+1 care trece numai prin noduri selectate.

2) Drumul de cost mai mic trece şi prin noduri neselectate.


În acest caz se contrazice LEMA 2.
readln(f,n);

{Fiind dat un graf neorientat G si doua varfuri x si y for i:=1 to n do


in acest graf, sa se for j:=1 to n do
determine un lant elementar de lungime minima, if i=j then a[i,j]:=0
avand ca extremitati else a[i,j]:=infinit;
varfurile date. Datele de intrare se citesc din fisierul readln(f,x,y);
Graf.dat care are while not eof(f) do
urmatoarea componenta: begin
- pe prima linie se afla numarul de varfuri ale readln(f,p,q);
grafului(n); a[P,q]:=1; a[q,P]:=1;
- pe a doua linie sunt inscrise cele doua extremitati end;
ale lantului close(f)
elementar separate prin spatii;
- pe urmatoarele n linii se gasesc valorile matricei end;
de adiacenta separate prOcedure mat_drumuri;
prin spatii. Datele de iesire se vor afrsa pe ecran si var i,j,k:byte;
vor consta in: begin
- mesajul "Nu exista lanl elementar Fntre cele doua for k:=1 to n do
varfuri" for i:=1 to n do
sau for j:=1 to n do
- mesajul "Lantul minim are lungimea .... ", iar pe if a[i,j]>a[i,k]+a[k,j] then
linia urmatoare varfurile begin
lantului a[i,j]:=a[i,k]+a[k,j];
separate printr-un spatiu. a[j,i]:=a[i,j];
end;
Rezolvare end;
Rezolvarea acestei probleme se bazeaza pe formarea procedure drum(v1,v2:byte);
matricei lanturilor. Un var k:byte;gasit:boolean;
element al acestei matrici va contine Iungimea begin
lantului minim dintre varfurile k:=1;gasit:=false;
corespunzatoare liniei si coloanei.} while(k<=n)and not gasit do
program lant_elementar; begin
const infinit=100; if(v1<>k)and(v2<>k)and(a[v1,v2]=a[v1,k]
type matrice=array[1..20,1..20] of byte; +a[k,v2])then
var n,x,y:byte;a:matrice;f:text; begin
procedure citeste; drum(v1,k);drum(k,v2);
var i,j,p,q:byte; gasit:=true;
begin end;
assign(f,'in2.pas');reset(f); k:=k+1;

90
end; write(‘r=’); readln(r);
if not gasit then write(v2,' '); for I:=1 to n do
end; begin
begin s[I]:=0; t[I]:=0;
citeste; a[I,I]:=0;
mat_drumuri; end;
if a[x,y]=infinit then writeln('Nu exista lant s[r]:=1;
elementar intre cele doua varfuri') for I:=1 to n do
else begin
begin d[I]:=a[r,I];
writeln('Drumul minim are lungimea:',a[x,y]); if I<>r then
write(x,' '); t[I]:=r;
drum(x,y); end;
end; for I:=1 to n-1 do
readln; begin
end. min:=30000;
for j:=1 to n do
ALGORITMUL DIJKSTRA if s[j]=0 then
Program dijkstra; begin
Type mat=array[1..10,1..10] of integer; min:=d[j];
vect=array[1..10] of integer; poz:=j;
var a:mat; end;
s,t,d:vect; s[poz]:=1;
n,I,j,r,min,poz:integer; for j:=1 to n do
if s[j]=0 then
procedure drum(I:integer); if d[j]>d[poz]+a[poz,j] then
begin begin
if t[i]<>0 d[j]:=d[poz]
then +a[poz,j];
begin t[j]:=poz;
drum(t[i]);write(i); end;
end end;
else write(I); for I:=1 to n do
end; if I<>r then
begin begin
write (‘n=’);readln(n); writeln(‘Distanţa de la nodul’,r,’la
writeln(‘Introduceţi matricea nodul’,’este ‘,d[I]);
costurilor’); drum[I];
for I:=1 to n do writeln;
for j:=I+1 to n do end;
begin end.
write(‘a[‘,I,’,’,j,’]=’);
readln(a[I,j]); a[j,I]:=a[I,j];
end;
writeln(‘Introduceţi nodul de pornire’);

Algoritmul Roy Floyd


Fiind dat un graf prin matricea ponderilor sa se calculeze drumul (lungimea lui adica
suma costurilor) minim de la orice doua noduri din graf.

91
matricea ponderilor este
019ω 3
ω 0 7 3 ω
ω ω 0 ω ω
1 ω 2 0 ω
ω 4 ω 2 0

Etapa 1)Caut drumurile optime intre oricare doua noduri dar drumurile trec prin nodul
intermediar 1
a[4,2]= ω >a[4,1]+a[1,2]=1+1=2 deci a[4,2]=2
a[4,5]=ω>a[4,1]+a[1,5]=1+3=4 deci a[4,5]=4
matricea ponderilor este

019ω 3
ω 0 7 3 ω
ω ω 0 ω ω
1 2 2 0 4
ω 4 ω 2 0

92
Etapa 2)Caut drumurile optime intre oricare doua noduri dar drumurile trec prin nodul
intermediar 2
a[1,3]=9>a[1,2]+a[2,3]=1+7=8 deci a[1,3]=8
a[1,4]=ω>a[1,2]+a[2,4]=1+3=4 deci a[1,4]=4
a[5,3]=ω>a[1,2]+a[2,3]=4+7=11 deci a[5,3]=11
a[5,4]=ω>a[5,2]+a[2,4]=4+3=7 deci neschimbat

matricea ponderilor este

0184 3
ω 0 7 3 ω
ω ω 0 ω ω
1 2 2 0 4
ω 4 11 2 0

Etapa 3)Caut drumurile optime intre oricare doua noduri dar drumurile trec prin nodul
intermediar 3 dar nu avem nimic nou.
Etapa 4)Caut drumurile optime intre oricare doua noduri dar drumurile trec prin nodul
intermediar 4
a[1,3]=ω>a[1,4]+a[4,3]=4+2=6 deci a[1,3]=6
a[2,1]=ω>a[2,4]+a[4,1]=3+1=4 deci a[2,1]=4
a[2,3]=ω>a[2,4]+a[4,3]=3+2=5 deci a[2,3]=5
a[2,5]=ω>a[2,4]+a[4,5]=3+4=7 deci a[2,5]=7
a[5,1]=ω>a[5,4]+a[4,1]=2+1=3 deci a[5,1]=3
a[5,3]=ω>a[5,4]+a[4,3]=2+2=4 deci a[5,3]=4

93
0164 3
4 0 5 3 7
ω ω 0 ω ω
1 2 2 0 4
3 4 4 2 0

{Fiind dat un graf orientat si readln(n);


conex cum n noduri .Sa se for i:=1 to n do
determine for j:=1 to n do
drumul cel mai scurt intre doua if i<>j then
noduri(exemplu intre primul si begin
ultimul write('a[',i,',',j,']=');
) adica drumul care are costul readln(a[i,j]);
cel mai mic Se va introduce end;
acolo unde nu avem arc orientat for k:=1 to n do
sau nu avem drum for i:=1 to n do
intre doua noduri o cifra mare for j:=1 to n do
cum ar fi 300 pe rol de infinit if a[i,j]>a[i,k]+a[k,j] then
VARIANTA 1;fiind date n orase a[i,j]:=a[i,k]+a[k,j];
si costurile tuturor drumurilor writeln;
directe writeln('matricea este ');
care exista intre orase sa se for i:=1 to n do
afle costul minim de a ajunge begin
dintr-un oras in oricare altul} for j:=1 to n do
program dm; write(a[i,j],' ');
type matrice=array[1..9,1..9] readln;
of integer; end
var a:matrice; end.
i,j,k,n:integer; {Fiind dat un graf orientat si
begin conex cum n noduri .Sa se
write('n='); determine

94
drumul cel mai scurt intre doua write(ni,' ');
noduri(exemplu intre primul si drum(ni,nf);
ultimul end
) adica drumul care are costul else write('nu este drum de la
cel mai mic Se va introduce ',ni,' la ',nf);
acolo unde nu avem arc orientat writeln;
sau nu avem drum end;
intre doua noduri o cifra mare
cum ar fi 300 pe rol de procedure lungime;
infinit} var i,j,k:integer;
const minfinit=1.e20; begin
var a:array [1..50,1..50] of for k:=1 to n do
real; for i:=1 to n do
n,i,j:integer; for j:=1 to n do
if a[i,j]>a[i,k]+a[k,j] then
procedure drum(i,j:integer); a[i,j]:=a[i,k]+a[k,j];
var k:integer;gasit:boolean; end;
begin
k:=1; begin
gasit:=false; write('n=');
while (k<=n) and not gasit do readln(n);
begin for i:=1 to n do
if (i<>k) and (j<>k) and for j:=1 to n do
(a[i,j]=a[i,k]+a[k,j]) if i=j then
then a[i,j]:=0
begin else a[i,j]:=minfinit;
drum (i,k); for i:=1 to n do
drum(k,j); for j:=1 to n do
gasit:=true; if i<>j then
end; begin
k:=k+1; write('a[',i,',',j,']=');
end; readln(a[i,j]);
if not gasit then end;
write(j,' '); lungime;
end; for i:=1 to n do
for j:=1 to n do
procedure scriu(ni,nf:byte); scriu(i,j);
begin writeln;
if a[ni,nf]<minfinit then begin readln;
writeln('drumul de la ',ni,' end.
la ',nf,' are lungimea
',a[ni,nf]:5:0);

8.6 Grafuri euleriene si hamiltoniene


Grafuri hamiltoniene
Definitie:
Se numeste ciclu hamiltonian intr-un graf, un ciclu elementar care contine toate varfurile grafului .
Se numeste graf hamiltonian ,un graf care contine un ciclu hamiltonian.
Se numeste lant hamiltonian intr-un graf, un lant elementar care contine toate varfurile grafului.
Teorema:
Daca intr-un graf G=(X,U) cu n>=3 varfuri, gradul fiecarui varf x verifica conditia d(x)>=n/2,
atuncigraful este hamiltonian,

{ Se citeste matricea de adiacenta la un ex:n=3


graf neorientat =>1 3 2 1
Sa se genereze toate ciclurile hamiltoniene 1 2 3 1}
ale acestuia type sir =array[1..100] of integer;

95
end;
var x:sir;
p,i,j,k,n,k1:integer; begin
as,ev:boolean;
a:array[1..50,1..50] of integer; write('dati numarul de noduri din graf');
readln(n);
procedure succesor(var x:sir;k:integer;var
as:boolean); for i:=1 to n-1 do
begin begin
if (x[k]<n) then begin for j:=i+1 to n do
as:=true; x[k]:=x[k]+1; begin
write('numarul ',i,',',j,' este ');
end readln(a[i,j]);
else a[j,i]:=a[i,j];
as:=false; end;
end; end;x[1]:=1;
k:=2; j:=0;
procedure valid(x:sir;k:integer;var x[k]:=1;
ev:boolean); while(k>0) do
var i:integer; begin
begin repeat
ev:=true; succesor(x,k,as);
if a[x[k-1],x[k]]=0 then ev:=false if as then valid(x,k,ev)
else until (as and ev) or (not as);
begin if as then
for i:=1 to k-1 do if (k=n) then
if x[k]=x[i] then ev:=false; afis(x,k)
if (k=n) and(a[x[n],x[1]]=0) then ev:=false; else
end; begin
end; k:=k+1;
x[k]:=1;
procedure afis(x:sir;k:integer); end
var i:integer; else
begin k:=k-1 ;
for i:=1 to k do end;
write( x[i] ,' '); readln;
write(x[1]:4); end.
writeln;
Grafuri euleriene
Definitie:
Se numeste ciclu eulerian intr-un graf, un ciclu care contine toate muchiile grafului.
Se numeste graf eulerian, un graf care contine un ciclu eulerian.

Teorema:
Un graf fara varfuri izolate este eulerian, daca si numai daca este conex, si gradele tuturor
varfurilor sunt numere pare
fara virfuri izolate si care are gradele fiecarui
{Stiind ca un graf conex(are o singura virf un numar par
componenta conexa) , Sa se determine daca este ciclu eulerian sa nu
ex:n=3
m=3 si anume (1,2),(1,3),(2,3)

96
=>1 2 3 1 e ciclu eulerian} begin
var eulerian:boolean; write(' cite noduri are graful n=');
e,grd,nd,c1:array[1..20] of integer; readln(n);
a:array[1..20,1..20] of integer; write(' cite muchii are graful m=');
n,m,i,j,k,k1,x,y,l:integer; readln(m);
viz:array[1..20] of byte; for I:=1 to n do
function izolate:boolean; for j:=1 to n do
var i,j,m,intr:byte; a[i,j]:=0;
begin writeln('dati muchiile ');
izolate:=false; for i:=1 to m do
for i:=1 to n do begin
begin writeln('primul nod al muchiei ',i,' este
intr:=0; ');readln(x);
for j:=1 to n do writeln('urmatorul nod al muchiei ',i,' este
intr:=intr+a[i,j]; ');readln(y);
grd[i]:=intr; a[x,y]:=1;
if intr=0 then begin a[y,x]:=1;
izolate:=true; end;
break; eulerian:=not izolate and gradepare and conex;
end; if not eulerian then writeln ('graful nu este
end; eulerian ')
end; else
function gradepare:boolean; begin
var i:byte; writeln('este eulerian ');
begin nd[1]:=1;
gradepare:=true; k:=1;
for i:=1 to n do repeat
if odd(grd[i]) then begin for j:=1 to n do
gradepare:=false; if a[nd[k],j]=1 then begin
break; k:=k+1;
end; nd[k]:=j;
end; a[nd[k-1],j]:=0;
function conex:boolean; a[j,nd[k-1]]:=0;
var b,viz:array[1..20] of byte; grd[j]:=grd[j]-1;
i,j,p,u,v:byte; grd[nd[k-1]]:=grd[nd[k-1]]-1;
begin break;
for j:=1 to n do end;
viz[j]:=0; until nd[k]=1;
b[1]:=1; while k-1 <m do begin
p:=1; for i:=1 to k-1 do
u:=1; if grd[nd[i]]>0 then begin
viz[1]:=1; c1[1]:=nd[i];
while p<=u do begin L:=i;
v:=b[p]; break;
for j:=1 to n do end;
if (a[v,j]=1) and (viz[j]=0) then k1:=1;
begin repeat
u:=u+1; for j:=1 to n do
b[u]:=j; if a[c1[k1],j]=1 then begin
viz[j]:=1; k1:=K1+1;
end; c1[k1]:=j;
p:=p+1; a[c1[k1-1],j]:=0;
end; a[j,c1[k1-1]]:=0;
conex:=true; grd[j]:=grd[j]-1;
for i:=1 to n do grd[c1[k1-1]]:=grd[c1[k1-1]]-1;
if viz[i]=0 then begin break;
conex:=false; end;
break; until c1[k1]=c1[1];
end; for j:=k downto L do
end; nd[j+k1-1]:=nd[j];

97
for j:=1 to k1-1 do for i:=1 to m+1 do
nd[j+1]:=c1[j+1]; write(' ',nd[i]);
k:=K+k1-1; end;
end; readln;
writeln('un ciclu care trece prin toate muchiile end.
este ');

8.7 Arbori,arbori partiali de cost minim


Arbori
Noţiunea de arbore

Definiţie. Se numeşte arbore un graf orientat care este conex si nu conţine cicluri.

Problema. Se citeşte un graf sa se scrie un program care sa verifice daca este arbore.

1. Mai întâi trebuie văzut daca graful este conex. In cazul grafurilor orientate aceasta problema se rezolva printr-o
simpla parcurgere in adâncime (DF). Dar in cazul grafurilor neorientate? Aici apare o problema. De la nodul i la
nodul j exista doua arce, de la i la j si de la j la i. Aceasta conduce la semnalarea unui ciclu fals. Pentru rezolvarea,
după alegerea unei muchii ,de exemplu de la i la j se elimina muchia de la j la i. In final daca au fost atinse toate
nodurile(adică daca orice componenta a vectorului s retine numai 1) înseamnă ca graful este conex.

2. Trebuie analizat daca graful nu are cicluri. Aceasta problema se rezolva tot cu ajutorul parcurgerii in adâncime.
Parcurgerea asigura selecţia unei muchi o singura data. Daca graful are cel puţin un ciclu, atunci un nod este atins
de doua ori. Cum ne putem da seama ca aceasta are loc? simplu, daca a fost atins un nod i , după care s[i]=1.

In aceste condiţii, nu se face decât o simpla parcurgere in adâncime. Iată programul:

program arbore ;
uses grafuri;
var s:array[1.. 50] of byte;
A:mat_ad;
gasit:boolean;
n,i,suma:integer;

procedure df_r(nod:byte);
var k:byte;
begin
s[nod]:=1;
for k:=1 to n do
if (a[nod,k]=1)
then
begin
a[k,nod]:=0;
if s[k]=0; then df_r(k)
else gasit:=true;
end;
end ;

begin
clrscr;
citiren( ` graf.txt `,a,n);
df_r(1);
suma:=0;
for i:=1 to n do suma:=suma +s[i];

98
if suma<>n then
writeln( `graful nu este conex `);
else if gasit then writeln( ` graful are ce putin un ciclu `);
else writeln( ` este arbore `);
end. .

 Complexitatea algoritmului este cea a parcurgerii in adancime:O(m),unde m reprezintă numărul de muchii.

Mai jos este reprezentat grafic acelasi arbore in mai multe feluri. Ultimele 3 reprezentări sunt
făcute considerând pe rând ca vârf al arborelui nodurile 1,3,2. de asemenea ultimele trei
reprezentări justifica si denumirea data grafurilor conexe si fara cicluri, cea de arbori.

Teorema. Fie G un graf neorientat cu n noduri. G este arbore daca si numai daca g are n-1 muchii si nu
contine cicluri.

Demonstraţie :

 Vom demonstra prin inducţie. Daca n=1,numarul muchiilor este 0(se verifica). Vom presupune
proprietatea adevărata pentru arbori cu n noduri(vom avea n-1 muchii). Fie un arbore cu n+1 noduri.
Exista cel putin un nod terminal(nod care are o singura muchie incident). Daca nu ar exista un astfel de
nod, arborele va contine cicluri(se contrazice definiţia). Eliminam nodul terminal si muchia care ii este
incident. Obţinem un arbore cu n noduri. Conform ipotezei făcute aceasta va avea n-1 muchii.
Înseamnă ca arborele cu n+1 noduri va avea n muchii(n- 1 +1).

 Fie un graf cu n-1 muchii care nu contine cicluri. Rămâne de dovedit ca G este conex. Vom
demonstra prin reducere la absurd. Presupunem ca G nu este conex. Fie G 1, G2, .. ,Gp componentele
conexe. Fiecare dintre ele indeplineste conditiile:

2) Este conexa(asa a fost aleasa);


3) Nu contine cicluri(pentru ca G nu contine cicluri).

Rezulta ca fiecare dintre ele este arbore. Fie mi numarul muchiilor si ni numarul nodurilor fiecarui arbore
Gi. Avem mi=ni-1. Dar m1+m2+….+mp=n-1. Rezulta: n1-1+n2-1+…..np-1=n-1, deci n1+n2+…..+np=n+p-1.

99
Dar G are n noduri. Rezulta :n+p-1=n,deci p=1. In concluzie exista o singura componenta conexa care
nu contine cicluri. Deci G este arbore.

 Din demonsratie s-a vazut ca un graf neorientat fara cicluri dar neconex este alcătuit,
din mai mulţi arbori. Din acest motiv, un astfel de graf se numeşte pădure !

 Tot in aceasta demonstatie, a fost introdus termenul de nod terminal al unui arbore cu
o singura muchie incident.

 Ati reţinut, ca arborele poate fi privit ca avand un anumit varf ! Varf al arborelui poate
fi oricare nod al sau, deci si unul termial !
Algoritmul lui Prim
Fie G=(X,) un graf neorientat şi conex. Graful este dat prin matricea costurilor. Se cere să se
determine arborele de cost parţial minim (între oricare două noduri să existe un drum), iar în plus suma
muchiilor să fie minimă.
O problemă concretă, în care intervine problema enunţată, este cea a conectării oraşelor cu
cost minim.
Avem N oraşe precum şi costul conectării anumitor perechi de oraşe. Se cere să se genereze
muchii care asigură existenţa unui drum între oricare două oraşe astfel încât costul cuplării să fie
minim.
Pentru rezolvare se folosesc trei vectori:
-vectorul S, vector caracteristic. Avem S(I)=0 dacă nodul I nu aparţine arborelui construit şi
S(I)=1 în caz contrar;
-vectorul T reţine pentru fiecare nod care se adaugă arborelui nodul părinte al acestuia (cu
ajutorul acestui vector se poate reconstitui arborele);
-vectorul P reţine pentru fiecare nod C costul arcului de la părinte la el.
Prezentarea algoritmului.
P1) Se citeşte N (numărul nodurilor), matricea costurilor A şi nodul de pornire V (S(V)=1);

P2) Se alege muchia de cost minim (L,C) care are o extremitate într-unul din nodurile
arborelui deja construit (S(L)=1), iar cealălaltă într-un nod care nu aparţine arborelui (S(C)=0). Se pune
T(C)=L şi P(C)=A(L,C);

P3) Dacă nu au fost alese N-1 muchii, se reia pasul 2.


Exemplu. Fie graful din figura următoare: (s=(0 1 1 1 1) )

3 2

5 2

5
2 1 5

4 3

4
Se porneşte cu nodul 1(v=1).

100
Alegem muchia de cost minim (1,2).
S=(0 0 2 2 1)

Pentru nodurile 1 şi 2, ca puncte de plecare, se alege muchia de cost minim (2,4) si s=(0 0 4 0 1)

2
1

21
4

Pentru nodurile 1,2 şi 4 se alege muchia de cost minim (1,5).


S=(0 0 4 0 0)

2 3
5

Pentru nodurile 1,2,4 şi 5 se alege muchia de cost minim (4,3) .

11
3
2 5

1
4

101

3
4

s=(0 0 0 0 0)
Am ales patru muchii şi s-a obţinut muchia de cost minim.
Configuraţiile finale ale vectorilor T şi P sunt:

1 2 3 4 5
T 0 1 4 2 1
P 0 2 4 1 3

Dacă pornim dintr-un alt nod, este posibil să obţinem un alt arbore dar şi el va avea costul
minim.

Demonstrarea algoritmului.

În urma aplicării algoritmului se obţine un arbore (vom avea N noduri şi N-1 muchii).
Rămâne de demonstrat că acest arbore este de cost minim. Notăm cu Gk=(Xk,k) arborele
obţinut după alegerea a k muchii, cu k{1,2,…,N-1}. Fie G1 un arbore de cost minim. Fie M1,M2,
…,Mk primele k muchii găsite în urma aplicării algoritmului pentru arborele Gk+1. Considerăm că
muchia Mk este prima muchie care nu aparţine lui G1. Fie P şi Q cele două noduri unite de muchia Mk.
Este evident că în G1, cele două nu sunt unite direct (în caz contrar muchia Mk ar face parte din arborele
G1). Aceasta înseamnă că în G1, nodurile P şi Q sunt unite printr-un lanţ. Acest lanţ nu aparţine lui G k+1,
pentru că el împreună cu Mk ar forma un ciclu. Înseamnă că acest lanţ uneşte în G1 două noduri, P1 şi
Q1 cu P1Xk şi Q1Xk. În caz contrar dacă ar uni numai noduri din Xk înseamnă că Gkm ar conţine un
lanţ (conţine muchia Mk, care uneşte pe P şi Q, conţine şi restul lanţului din G1 pentru că primele k
noduri în G1 şi Gk sunt legate identic). Presupunem nodurile P1 şi Q1 unite prin muchia M1. Înlocuim
în G1 pe M1 cu Mk. În urma acestei înlocuiri,G1 se transformă într-un alt arbore G2. Dar
A(P,Q)A(P1,Q1) pentru că în caz contrar, prin logica algoritmului, s-ar fi ales muchia M1. Aceasta
înseamnă că arborele parţial G2 rămâne tot de cost minim. În plus G1 şi Gk+1 au k+1 muchii care
coincid. Repetăm procedeul până obţinem coincidenţa a n-1 muchii. Rezultă de aici că l-am
transformat pe G1 în arborele generat de algoritm fără a-i modifica costul. În concluzie arborele generat
de algoritm este de cost minim.
Program prim;
Type matrice=array[1..9,1..9] of integer;
vector=array[1..9]of integer;
var a:matrice;
s,t,p:vector;
n,I,j,k,v,min,l,c:integer;
begin
write(‘n=’); readln(n);
for l:=1 to n-1 do
for j:=I+1 to n do begin
write(‘a[‘,I,’,’,j,’]=’);
readln(a[I,j]);
a[j,I]:=a[I,j];
end;
write (‘nodul de pornire=’); readln(v);
for I:=1 to n do begin
s[I]:=0;
t[I]:=0;
p[I]:=0
end;
s[v]:=1;
for k:=1 to n-1 do begin

102
min:=30000;
for I:=1 to n do
for j:=1 to n do
if (s[I]=1)and (s[j]=0)and (min>a[I,j])then
begin
min:=a[I,j];
I:=I;
c:=j
end;

s[c]:=1; t[c]:=1; p[c]:=a[1,c]


end;
for I:=1 to n do
write (t[I],’ ‘);
writeln;
for I:=1 to n do
write(p[I],’ ‘);
end.

8.8 Arbori cu radacina:metode specifice de


reprezentare in memorie.Arbori binari

ARBORI SI ARBORESCENTE
Arbori
Noţiunea de arbore

Definiţie. Se numeşte arbore un graf orientat care este conex si nu conţine cicluri.

103
Problema. Se citeşte un graf sa se scrie un program care sa verifice daca este arbore.

1. Mai întâi trebuie văzut daca graful este conex. In cazul grafurilor orientate aceasta problema se rezolva printr-o
simpla parcurgere in adâncime (DF). Dar in cazul grafurilor neorientate? Aici apare o problema. De la nodul i la
nodul j exista doua arce, de la i la j si de la j la i. Aceasta conduce la semnalarea unui ciclu fals. Pentru rezolvarea,
după alegerea unei muchii ,de exemplu de la i la j se elimina muchia de la j la i. In final daca au fost atinse toate
nodurile(adică daca orice componenta a vectorului s retine numai 1) înseamnă ca graful este conex.

2. Trebuie analizat daca graful nu are cicluri. Aceasta problema se rezolva tot cu ajutorul parcurgerii in adâncime.
Parcurgerea asigura selecţia unei muchi o singura data. Daca graful are cel puţin un ciclu, atunci un nod este atins
de doua ori. Cum ne putem da seama ca aceasta are loc? simplu, daca a fost atins un nod i , după care s[i]=1.

In aceste condiţii, nu se face decât o simpla parcurgere in adâncime. Iată programul:

program arbore ;
uses grafuri;
var s:array[1.. 50] of byte;
A:mat_ad;
gasit:boolean;
n,i,suma:integer;

procedure df_r(nod:byte);
var k:byte;
begin
s[nod]:=1;
for k:=1 to n do
if (a[nod,k]=1)
then
begin
a[k,nod]:=0;
if s[k]=0; then df_r(k)
else gasit:=true;
end;
end ;

begin
clrscr;
citiren( ` graf.txt `,a,n);

104
df_r(1);
suma:=0;
for i:=1 to n do suma:=suma +s[i];
if suma<>n then
writeln( `graful nu este conex `);
else if gasit then writeln( ` graful are ce putin un ciclu `);
else writeln( ` este arbore `);
end. .

 Complexitatea algoritmului este cea a parcurgerii in adancime:O(m),unde m reprezintă numărul de muchii.

Mai jos este reprezentat grafic acelasi arbore in mai multe feluri. Ultimele 3 reprezentări sunt
făcute considerând pe rând ca vârf al arborelui nodurile 1,3,2. de asemenea ultimele trei
reprezentări justifica si denumirea data grafurilor conexe si fara cicluri, cea de arbori.

Teorema. Fie G un graf neorientat cu n noduri. G este arbore daca si numai daca g are n-1 muchii si nu
contine cicluri.

Demonstraţie :

 Vom demonstra prin inducţie. Daca n=1,numarul muchiilor este 0(se verifica). Vom presupune
proprietatea adevărata pentru arbori cu n noduri(vom avea n-1 muchii). Fie un arbore cu n+1 noduri.
Exista cel putin un nod terminal(nod care are o singura muchie incident). Daca nu ar exista un astfel de
nod, arborele va contine cicluri(se contrazice definiţia). Eliminam nodul terminal si muchia care ii este
incident. Obţinem un arbore cu n noduri. Conform ipotezei făcute aceasta va avea n-1 muchii.
Înseamnă ca arborele cu n+1 noduri va avea n muchii(n- 1 +1).

 Fie un graf cu n-1 muchii care nu contine cicluri. Rămâne de dovedit ca G este conex. Vom
demonstra prin reducere la absurd. Presupunem ca G nu este conex. Fie G 1, G2, .. ,Gp componentele
conexe. Fiecare dintre ele indeplineste conditiile:

4) Este conexa(asa a fost aleasa);


5) Nu contine cicluri(pentru ca G nu contine cicluri).

105
Rezulta ca fiecare dintre ele este arbore. Fie mi numarul muchiilor si ni numarul nodurilor fiecarui arbore
Gi. Avem mi=ni-1. Dar m1+m2+….+mp=n-1. Rezulta: n1-1+n2-1+…..np-1=n-1, deci n1+n2+…..+np=n+p-1.
Dar G are n noduri. Rezulta :n+p-1=n,deci p=1. In concluzie exista o singura componenta conexa care
nu contine cicluri. Deci G este arbore.

Din demonsratie s-a vazut ca un graf neorientat fara cicluri dar neconex este alcătuit, din mai mulţi
arbori. Din acest motiv, un astfel de graf se numeşte pădure !

 Tot in aceasta demonsratie, a fost introdus termenul de nod terminal al unui arbore cu
o singura muchie incident.

 Ati reţinut, ca arborele poate fi privit ca avand un anumit varf ! Varf al arborelui poate
fi oricare nod al sau, deci si unul termial !

Metode de memorare a arborilor

1. asa cum am aratat, un arbore este un graf neorientat, cu anumite


proprietati. Aceasta inseamna ca el poate fi reprezentat ca un graf. De aici
rezulta ca pentru reprezentarea unui arbore se pot utilza:

- matricea de adiacenta;
- liste de adiacente.
2. O a doua forma de reprezentare a arborilor este legatura de tip TATA . arborele se
reprezinta sub forma unui vector t cu n componente: daca t[i]=k, atunci nodul i
este descendent al nodului k. Daca nodul i este varf, t[i]=0.

5 3 5 5 0 3 4 1 7--------- k
1 2 3 4 5 6 7 8 9 --------- t[i]

 Legatura de tip TATA se mai numeste si legatura cu referinte ascendente.

 In mod evident, legatura de tip TATA este determinata si de nodul ales ca varf ! Daca, de exemplu
pentru acelasi arbor varful este 9, reprezentarea este alta. Este ca si cum „apucam” arborele de un nod
si celelalte cad !

 De fapt prin legatura de tip TATA se reprezinta o padure !

106
035003 417
123456789

 Aceasta reprezentare a mai fost intalnita. De exemplu, la altgoritmul lui Dijkstra !

3.Codul lui Puffer(facultativ). Pentru a reprezenta un arbore oarecare se pot utiliza doi vectori, pe care-i
vom numi t-de la nodul terminal – si pt – de la parinte nod terminal. Modul in care acestia retin datele
este explicat mai jos:

 Se cauta cel mai mic nod terminal, acesta este retinut in vectorul t iar parintele sau este
memorat in vectorul pt.
 Se obtine un nou arbore renuntand la nodul terminal si la muchia care-l uneste de parinte.
 Procedeul se rea pana cand ramane un arbore cu un singur nod.

Exemplu .

Pentru arborele alaturat cel mai mic nod terminal este doi,iar parintele trei.

In noul arbore ,cel mai mic nod terminal este 6, iar parintele lui 6 este 3.

Cel mai mic nod terminal este 3, iar parintele 5.

107
Cel mai mic nod terminal este 8, iar parintele sau este 1.

Cel mai mic nod terminal este 1, iar parintele sau este 5.

108
 Pana in acest moment am
memorat arborele prin utilizarea a 2 vectori t si pt. Fiecare dintre ei, are n-1 componente!

 Prin logica altgoritmului nodul care ramane este cel mai mare adica nodul n. Acesta este ultimul
memorat in vectorul pt.Prin urmare, daca se cunoaste n sunt suficiente n-2 componente pentru vectorul
pt.

 Foarte important! Vectorul t se poate reconstitui doar daca cunoastem vectorul pt. aceasta inseamna
ca un arbore cu n noduri a fost memorat doar printr-un vector cu n-2 componente!

Pentru reconstituirea vectorului t pornim de la pt,vom incepe prin a memora in pt, numarul n, pentru
componenta n-1. vectorul t se reconstituie prin formula:

i{1,2…n-1}
t[i]=min{kk{t[1]=t[2],…t[i-1],pt[i],pt[i+1]…pt[n-1]}}

Cum s-a dedus formula de mai sus?

- daca numarul se gaseste in pt[i],pt[i+1],…pt[n-1] inseamna ca nodul respectiv nu a fost eliminat pana
la pasul i, pentru ca este parinte.
- daca numarul se gaseste in t[1],t[2],…t[i-1] inseamna ca a fost extras la unul din pasii anteriori.
 dintre nodurile care nu se gasesc ca mai sus , la pasul i a fost extras nodul minim.

Exemplu. Plecam de la n=9,si pt={3 3 5 1 5 4 7 }


Pasul 1
T={}
Pt={3 3 5 1 5 4 7,9}
Cel mai mic numar care nu se gaseste in pt si este intre 1 si 9 este 2.

Pasul 2
T={2}
Pt={3 3 5 1 5 4 7,9}
Se alege 6.

Pasul 3.
T={2 6 }
Pt={3 3 5 1 5 4 7,9}
Se alege 3.

109
Programul care urmeaza citeste de la tastatura n si pt, dupa care tipareste vectorul t.

Program puffer;
Var t,pt:array[1..50] of byte;
Var i,j,k,n:byte;
Gasit:boolean;
Begin
Write(`n=`);readln(n);
For i:=1 to n-2 do begin
Write(`pt[`,i,`]=`);readln(pt[i]);
End;
Pt[n-1]:=n;
K:=n;
For i:=1 to n-1 do
Begin
K:=1;
Repeat
Gasit:=false;
For j:=1 to i-1 do
If t[j]=k then
Gasit:=true;
If not gasit
Then
For j:=1 to n-1 do
If pt[j]=k then
gasit: = true;
if gasit then k:=k+1;
until not gasit;
st[i]:=k;
end;
for i:=1 to n-1 do
write(t[i],` `);
end.

 Foarte important. Cati arbori cu n noduri exista? Vectorul pt are n-2 componente si
fiecare componenta poate retine valori intre 1 si n. Deci exista n n-2 arbori cu n noduri.
 Pornind de la u un arbore ,i se asociaza prin codul lui Puffer un vector cu n-2
componente. Se arata usor ca daca arborii sunt diferiti codificarea lor este diferita. Tot
asa, pornind de la un vector cu n-2 componente, unde fiecare ia valori intr 1 si n se
ajunge la un arbore. Cu alte cuvinte am definit o functie f pe multim,ea arborilor care
ia valori in produsul cartezian:

(1,2,…n)*(1,2,…n)*…(1,2,…n)

 Din cele aratate rezulta ca f este bijectiva. Prin urmare tinand cont de faptul ca functia
este definita pe o multime finita,numarul de elemente al codomeniului este egal cu
numarul de elemente al domeniului de definitie. Aceasta explica modul in care a fost
determinat numarul de arbori
 Codul lui pruffer asociaza acelasi cod arborelui indiferent de reprezntarea grafica
folosita.

110
Arbori

Definitie : Un graf conex si fara cicluri se numeste arbore .


Teorema
Fie un graf G=(X,U) . Urmatoarele afirmatii sunt echivalente :
4. G este arbore .
5. G este un graf conex ,minimal in raport cu aceasta propietate (eliminand o muchie oarecare
se obtine un graf ne-conex).
6. G este un graf fara cicluri,maximal in raport cu aceasta propietate (adaugand o muchie
oarecare, se obtine un graf care are cel putin un ciclu).
In cazul arborilor ,in loc de “varfuri” si “muchii”,se folosesc cu precadere termenii sinonimi “noduri”
respectiv “arce”.
Teorema : Un arbore cu n varfuri are n-1 muchii.

Detaliem si sistematizam in continuare cateva propietati care caracterizeaza un arbore :


● exista un nod in care nu intra nici un arc, numit radacina arborelui.
● cu exceptia radacinii, fiecare nod are propietatea ca in el intra un singur arc. Aceasta leaga nodul
respectiv de un alt nod numit predecesor sau parinte.
● dintr-un nod pot iesi unul sau mai multe arce. Fiecare astfel de arc , leaga nodul rsepectiv de un
alt nod numit succesor sau fiu al nodului.
● nodurile sunt organizate pe nivele , primul nivel fiind ocupat de nodul-radacina. Nodurile de pe
ultimul nivel se caracterizeaza prin faptul ca din ele nu mai iese nici un arc , si se numesc noduri
terminale sau frunze.
● nodurile pot contine o asa-numita informatie utila care poate fi de orice tip . De obicei aceste
informatii se mai numesc si chei ale arborelui.

Arbori binari

Definitie
Un arbore cu propietatea ca fiecare nod cu exceptia frunzelor , are cel mult doi descendenti
(succesori )
se numeste arbore binar.
Intr-un arbore binar ,cei doi succesori ai unui nod (daca exista), se numeste succesor stang
respectiv arbore drept.
Definitie
Un arbore cu propietatea ca fiecare nod ,cu exceptia frunzelor , are exact doi descendenti
(succesori) se numeste arbore binar complet .
Notiunea de arborescenta

Notiunea de arbore poate fii extinsa si pentru grafuri orientate.

Definitie. Fiind date doua noduri i si j ale unui graf orientat, se spune ca exista un lant de la i la j daca
exista o succesiune de arce, indiferent de sensul lor prin care cele doua noduri sunt unite.
 Daca exista un lant de de la i la j, exista si unul de la j la i.

111
Definitie. Un graf orientat G=(x,) exte conex daca  ijx
exista un lant de la i la j.

 Daca un graf orientat este tare conex, atunci el este conex, dar reciproca nu este
adevarata. Graful de mai sus este conex.
Definitie. Un graf orientat admite un ciclu daca exista un mod i, pentru care exista un lant de la i
la i.

Exemplu. In graful anterior nodurile 4 2 3 sunt unite printr-un ciclu.

Definitie. Un graf orientat este arbore daca nu este conex si nu admite cicluri.

Exemple:

1. Graful anterior nu este arbore pentru ca admite un ciclu.


2.

Definitie. Un graf orentat g=(x,) admite o radacina vx daca pentru orice xx-(v) exista un drum
(atnete, nu lant) de la v la x.

Exemple:

1. graful de mai sus nu admite o radacina. De exemplu nu exista drum de la 1 la 3


(1 nu este radacina), nu exista drum de la 3 la 4 (nici 3 nu este radacina) etc.

2. Graful alaturat are radacinile 1, 2, 3,4.

112
Definitie. Se numeste arborescenta un graf orientat care indeplineste simultant doua conditii :
1.Este arbore;
2.Admite radacina.

 Intr-o arborestenta radacina este unica. Daca de exemplu exista doua radacini v 1 si v2 atunci exista
drum de la v1 la v2 si de la v2 la v1. aceasta presupune existenta unui ciclu, deci nu este arbore.
 De regula, atunci cand se da o arborescenta se preciaza radacina sa.

Alaturat este prezentata o arborescenta de radacina 2.

 Se observa ca din radacina pleaca arce, nu intra. Daca ar si intra s-ar obtine un ciclu.

 de asemenea, orice nod are un singur predecesor. Daca, prin absurd, ar avea doi sau mai multi, s-ar
obtine un ciclu care include radacina.

Problema. Se citeste un graf orientat. Acesta este dat prin matricea de adiacenta.se cere ca programul
dv. sa decida daca graful este sau nu oarborescenta. In caz afirmativ, se va tipari radacina acesteia.

113
Rezolvare.

1. Tebuie decis mai intai daca graful orientat este arbore. Acesta se face printr-o singura
parcurgere in adancime,asemanator cu altgoriymul aplicat in cazul grafurilor orienta.
2. In cazul cand graful este arbore , trebuie vazut daca acesta are o radacina. Se testeaza, pe
rand, fiecare nod daca indeplineste conditia de radacina. Fiecare test se face printr-o
parcurgere in adancime pornind de la nodul respectiv.

Program arborescent; For i:= 1 to n do suma:=suma=s[i];


Uses grafuri; If suma<>n then writeln(‚graful nu este conex’)
Var s:array[1..50] of byte; Else writeln(‚graful este conex’);
A,b:mat_ad; If gasit then writeln(‚graful are cel putin un ciclu’)
Gasit,ok,radacina:boolean; Else writeln(‚graful nu are cicluri’);
N,i,suma,r:integer; If (suma=n) and not gasit
Then
Procedure df_r(nod:byte); Begin
Var k:byte; Writeln(‚este arbore’);ok:=true;
Begin End;
S[nod]:=1; A:=b;
For k:=1 to n do If(ok)
If (a[nod,k]=1) or (a[k,nod]=1) Then
Then Begin
Begin R:=1;
A[k,nod]:=0;a[nod,k]:=0; Repeat
If s[k]+0 then df_r(k) Suma:=0;
Else gasit:=true; For i:=1 to n do s[i]:=0;
End Df_r1( r ) ;
End; For i:=1 to n do suma:=suma +s[i];
If suma=n
Procedure df_r1(nod:byte); Then
Var k:byte; Begin
Begin Writeln(‚radacina este’,r);writeln(‚este
S[nod]:=1; arborescenta’);
For k:=1 to n do Radacina:=true;
If(a[nod,k]=1)and(s[k]=0) End
Then df_r1(k) Else r:=r+1;
End; Until (radacina) or (r>n);
Begin If not radacina then writeln(‚nu are radacina’)
Citire(‚graf.txt’,a,n); End
B:=a; df_r(1); suma:=0; End.

 Testul de abordare se face in o(m) , unde m reprezinta nr. muchiilor.


In concluzie altgoritmul are complexitatea o(nXm).

114
Programatorii folosesc de multe ori prin abuz de limbaj, termenul de arbore, in loc de arborescenta.
In astfel de cazuri se specifica radacina care se mai numeste si varf si se considera ca sensul arcelor
este implicit,motiv pentru care nu se mai reprezinta grafic.

In cazul in care arborescenta are cel mult doi descendenti, unul stang si unul drept, spunem ca avem
un arbore binar.

Exemplu. Mai jos vedeti o arborescenta cu radacina 1 care este un arbore binar. Alaturat obs. Modul in
care se reprezinta grafic renuntand la sensurile arcelor, care sunt implicite.

115
 Se presupune ca nodurile sunt asezate pe mai multe niveluri. Radacina este pe
nivelul 0, descenndentii direci directi ai radacini sunt pe nivelul 1, descendentii directi
ai nodurilor de pe nivelul 1 sunt pe nivelul 2 etc.
 Numarul de niveluri mai putin cel al radacinii, ocupate de nodurile grafului,se numeste
adancimea arborelui binar.
 Vom face dinstinctie intre descendentul stang si cel drept. De exemplu, arborii de mai
jos sunt considerati dinstincti.

Modalitati de reprezentare a arborilor binari

2. Desigur, arborii binari pot fi reprezentati ca orice grf orientat, dar aceasta forma este deosebit
de greoaie in aplicatii. Din acest motiv sunt cu mult mai convenabile reprezentarile pe care le
urmarim in continuare.

3. reprezentarea cu ajutorul vectorilor ( clasica ).

116
Un arbore binar poate fi reprezentat cu ajutorul a doi vectori, pe care ii vom numi st (de la stanga ) si dr
(de la dreapta). Pentru fiecare nod i dintre cele n, st[i] retine nr. de ordine al nodului stang subordonat
de i, iar dr[i] retine nr de ordine al nodului drept subordonat de i. Daca nu exista nod subordonat retine
0.

Exemplu. Arborele binar cu 7 noduri si v=1 de pe pagina anterioara se reprezinta astfel:

st 2 4 5 0 0 0 0

1 2 3 4 5 6 7

dr 3 0 6 0 7 0 0

4. Reprezentarea in HEAP (actuala).

Fiecare nod al arborelui este reprezentat in HEAP de o inregistrare cu urmatoarea structura:

Type ref= inr;


Inr-record
Info:integer;
St,dr:ref
End;

Programul va retine doar adresa radacinii (varfului). In aplicatii veti intalni numeroase exemple in acest
sens, motiv pentru care ne oprim aici cu aceasta reprezentare.

5. Reprezentarea cu ajutorul legaturii TATA.

Aceasta a mai fost prezentata in cazul arborilor neorientati. Mentionam doar faptul ca aceasta
reprezentare este neconvenabila in majoritatea aplicatiilor.

Modalitati de parcurgere a arborilor binari

117
In scopul prelucrarii,este necesar ca nodurile arborelui binar sa fie vizitate. Axista mai multe modalitati
de parcurgere a arborilor binari carer difera prin ordinea de vizitare a nodurilor.

Putem considera ca fiecare nod al arborelui binar subordoneaza un subarbore binar stang si unul drept.
Pe baza acestei observatii putem scrie usor subprograme recursive pentru diverse le modalitati de
pacurgere.

Principalele modalitati de parcurgere ale unui arbore binar sunt:

Parcurgerea in inordine – SVD – se se patrcurge mai intai subarborele stang, apoi varful apoi
subarborele drept.
Parcurgerea in preordine – VSD – se parcurge mai intai subarborele stang, apoi subarborele drept.
Parcurgerea in postordine – SD – se parcurge mai intai subarborele stang, apoi subarborele drept, apoi
varful.
Parcurgerea in adancime – a fost studiata pentru grafuri, aici se aplica in particular. Se parcurge
radacina, apoi nodurile de pe nivelul 1,apoi cele de pe nivelul 2 etc.

De exemplu parcurgerea SDV se face pe urmatoarea idee: varful subordoneaza doi subarbori: cel stang
si cel drept. Se trece la subarborele stang, apoi la varf, apoi la subarborele drept. Pentru fiecare
subarbore se repeta rationamentul.

Ordinea de parcurgere pentru arborele alaturat este: inordine –SDV-:4 2 1 5 7 3 6


preordine –VSD-:1 2 4 3 5 7 6
postordine –SDV-:4 2 7 5 6 3 1
latime:1 2 3 4 5 6 7

Programul urmator citeste si parcurge in inordine,postordine si preordine un arbore binar. Arborele este
retinut in HEAP. Pentru a marca faptul ca descendentul unui anumit nod lipseste se introduce 0.

Program arbori; End


Type ref= ^inr; End;
Inr=record
St,dr:ref; Function arb :ref;
Nr:integer Var n:integer;
End; C:ref;
Var c:ref; Begin
Write(‚n=’);readln(n);
If n<> o
Procedure vsd (c:ref); Then
Begin Begin
Writeln(c .nr); New( c );
Vsd(c ^.st); Arb:=c;
Vsd(c^ .dr) arb.nr:=n;

118
arb ^.st:=arb; end
arb ^. dr:=arb; end;
end
else arb:=nil begin
end; c:=arb;
writeln(`parcurg svd’);
procedure svd (c:ref); svd( c);
begin
if c<nil writeln(`parcurg vsd’);
then vsd( c);
begin writeln(`parcurg sdv’);
svd(c ^.st); sdv( c);
writeln(c^ .nr); end.
svd(c^ .dr)

 Nodurile arborelui se introduc in ordinea:

124000350700600

 Atat pentru introducerea arborelui, cat si pentru parcurgeri s-au utilizat tehnici

recursive care decurg din tehnica DIVIDE et IMPERA !

Programul urmator efectueaza aceleasi parcurgeri ca si precedentul, numai ca graful este


reprezentat cu ajutorul vectorilor.

Program arbori;
Var n,i,v:integer;
St,dr:array[1..50] of integer;

Procedure sdv(nod:byte);
Begin
If (nod<>0)
Then
Begin
Sdv(st[nod]);
Sdv(dr[nod]);
Writeln(nod);
End;
End;

Pocedure vsd(nod:byte);
Begin
If (nod<>0)
Then
Begin
Writeln(nod);
Vsd(st[nod]);
Vsd(dr[nod]);
End;
End;

Begin
Citire;
Writeln(`svd’0;svd(v);
Writeln( `vsd’);vsd(v);
Writeln(`sdv’);sdv(v);
End.

119
9.1 Definirea bazei de date
SISTEME DE GESTIUNE A BAZELOR DE DATE
9.1.1Aspecte privind organizarea datelor
Organizarea datelor presupune umatoarelor activitati:
-definirea ,structurarea,ordonarea si gruparea in colectii de date;
-stabilirea relatiilor intre date,intre elementele unei colectii de date;
-reprezentarea lor pe un sport informational
Definirea uniu model de date impune precizarea urmatoarelor elemente:
-structurile de date si stabilirea relatiilor intre date;
-operatori;
-restrictii de integritate
Intre date se pot stabili urmatoarele tipuri relatii intre baze de date:
 unu la unu ;
 unu la mai multi;
 multi la multi;
Operatori:citire,inserare,modificare,join etc.
Restrictii de integritate:corectitudinea datelor...
Modele de date:ierarhice,retea,relationale,orientate pe obiect,logice de date.
9.1.2 Baze de date
9.1.2.1 Definirea unei baze de date
Scopul principal al unei baze de date consta in stocarea datelor in vederea satisfacerii facile a cerintelor
utilizatorului,utilizand tehnica de calcul.deci,baza de date apare ca un sistem de
inmagazinare,regasire,actualizare si intretinere a datelor necesare procesului de fundamentare a
deciziei.
Definitia 1.1.2 O baza de date este o colectie structurata de date atasate unui fenomen al
lumii reale pe care incercam sa-l modelam.
Baza de date implica patru componenete:
 date
 hardware
 software
 utilizatori
9.1.2.2 Arhitecturi standardizate pentru bazele de date
Pe plan international exista mai multe grupuri specializate in standardizarea conceptelor ce
apar in dezvoltarea bazelor de date,cele mai importante fiind DBTG,CODASYL,ANSI/X3/SPARC,grupul
IMB.
In general ,o arhitectura cuprinde urmatoarele componente :
 baza de date propriu-zisa in care se memoreaza colectia de date;
 sistemul de gestiune al bazei de date
 un dictionar al bazei de date
 mijloace hard utilizate
 personal implicat:utilizatori finali sau de specialitate,programatori si operatori.
Datele pot fi definite pe trei nivele:
-nivel intern;
-nivel conceptual;
-nivel extern.
9.1.2.3 Limbaje pentru baze de date
1. Limbaje pentru definirea datelor(LDD)
Realizeaza definirea entitatilor si a atributelor acestora prin nume,forma de memorare,lungime.
2.Limbaje pentru manipularea datelor(LMD)
In general,o comanda are urmatoarea structura:
-operatia care poate fi calcul aritmetic sau logic,editare,extragere,manipulare
-criterii de selectie
-mod de acces
-forma de editare.
2. Limbaje pentru controlul datelor(LCD)

120
Se refera la asigurarea confidentialitatii si integritatii datelor,la salvarea informatiei in carzul unor
incidente,la obtinerea unor performante,la rezolvarea unor probleme de concurenta.
9.1.2.4 Avantajele utilizarii bazelor de date
Acestea sunt urmatoarele:
 Poate fi redusa redundanta datelor
 Se poate evita inconsistenta datelor
 Datele pot fi partajate
 Se poate obtine standardizarea
 Se pot aplica restrictii de securitate a datelor
 Poate fi mentinuta integritatea datelor prin existenta unor proceduri de validare ,unor protocoale de
control concurent a unor proceduri de refacere a bazei de date dupa incidente
 Pot fi echilibrate cerintele conflictuale
Intr-o baza de date nu se doreste ca aplicatiile sa fie deperndente de date din motivele :
-diferite aplicatii au nevoie de viziuni diferite ale acelorasi date
-administratorul bazei de date trebuie sa aiba sa schimbe structura de memorare sau strategia de acces
fara sa modifice aplicatii existente.
9.1.3 SISTEMUL DE GESTIUNE A BAZEI DE DATE(SGBD)
9.1.3.1 Definirea sistemului de gestiune a bazei de date
Definitia 1.1.3 Sistemul de gestiune a bazei de date reprezinta softwar-ul care asigura realizarea
urmatoarelor activitati:
-definirea structurii bazei de date
-incaracrea datelor in baze de date
-accesul la date
-intretinea bazei de date
-reorganizarea bazei de date
-securitatea datelor
9.1.3.2 Obiectivele unui sistem de gestiune a bazelor de date
1. Asigurarea independentei datelor
Aceasta trebuie privita din doua puncte de vedere:
-independenta fizica
-independenta logica
2. Asigurarea unei redundante minime si controlate a datelor din baza de date
3. Asigurarea unor facilitati sporite de utilizare a datelor
Aceasta presupune:
-folosira datelor de catre mai multi utilizatori in diferite scopuri;
-accesul cat mai simplu al utilizatorilor la date
-existenta unor limbaje performante de regasire a datelor
-acces multicriterial al sistemului de gestiune
-utilizarea unui limbaj natural
3. Sporire gradului de securitate a datelor
4. Asigurarea integritatii datelor
5. Asigurarea partajabilitatii datelor

9.1.3.3 Functiile unui sistem de gestiune a bazelor de date


1.Functia de descriere a datelor
2.Functia de manipulare a datelor
Aceasta realizeaza activitatile :
-crearea bazei de date;
-adaugarea de noi inregistrari;
-suprimarea unor inregistrari;
-modificarea valorilor corespunzatoare unor campuri;
-cautatea ,sortarea si editarea partiala sau totala a unei inregistrari virtuale.

121
9.2 Clasificarea bazelor de date (modelul relaţional,
modelul reţea, modelul ierarhic)
Aplicaţiile de tip “bază de date” se referă la acele produse livrate utilizatorului “la cheie” pentru
a-şi rezolva o problemă concretă. Aplicaţiile de tip “bază de date” existente pe piaţa românească se pot
împărţi în trei mari grupe, după finalitatea datelor manevrate:
a. a.       baze de date personale;
b. b.      baze de date informaţionale;
c. c.       baze de date pentru gestiunea economică.
 
a. Bazele de date “personale” sunt mici colecţii de date care prezintă interes şi sunt manipulate
de un singur utilizator. Câteva exemple tipice sunt următoarele: agendă telefonică, planificarea de
întruniri, evidenţa cărţilor din biblioteca personală. Pentru astfel de utilizări restrânse ale unei baze de
date, se poate folosi aplicaţia Card File disponibilă în pachetul Windows 3.x.
b. Bazele de date de tip informaţional sunt în general caracterizate de un volum foarte mare de
date (informaţii) ce sunt destinate publicului larg. Ele pot fi considerate adevărate “birouri de informaţii”
computerizate. Domeniul de aplicabilitate a acestor baze de date este extrem de diversificat şi face
imposibilă o clasificare.
c. Bazele de date pentru gestiunea economică reprezintă colecţii de date necesare şi utilizate
pentru gestionarea unei întreprinderi. Aplicaţiile cele mai reprezentative care operează cu astfel de baze
de date sunt produsele CIEL.
 
Pentru a înţelege mai bine cum este alcătuită şi cum funcţionează o bază de date, trebuiesc
specificate câteva noţiuni privind teoria generală a bazelor de date, cu aplicabilitate în arheologie:
Datele dintr-o colecţie de entităţi pot fi unite şi rezumate în moduri
diferite pentru a produce informaţie. Informaţia este o colecţie de date plasată în
context, care poate fi furnizată de către o situaţie sau de alte date.
Pentru a creşte (mării) bazele umane de cunoştinţe mentale memorate,
omul colectează şi memorează date în formă automată. O astfel de colecţie se
numeşte bază de date. Ea reprezintă nu numai date despre entităţi dar şi date
despre relaţiile dintre entităţi. Pe baza aceleaşi structuri funcţionează o bază de
date şi într-un calculator.
 
Există două forme de baze de date:
a. a.       baze de date fizice, care sunt reprezentări pe medii de memorare a
entităţilor, atributelor şi a relaţiilor dintre ele;
b. b.      baze de date logice, care reprezintă entităţi, atribute şi relaţiile
independente de modul în care datele şi relaţiile sunt reprezentate şi
memorate într-o bază de date fizică.
 
           Modele de baze de date
 
Există trei categorii de modele de baze de date:
1. 1.      modelul relaţional;
2. 2.      modelul reţea;
3. 3.      modelul arborescent (ierarhic).
 
9.2 1.      Modelul relaţional
 
Un model relaţional de baze de date cuprinde trei componente principale:
                     structura datelor prin definirea unor domenii (valori atomice)
şi a relaţiilor “n” (atribute, tupluri, chei primare);

122
                     integrarea datelor prin impunerea unor restricţii;
                     prelucrarea datelor prin operaţii din algebra relaţională sau
calcul relaţional.
 
Modelul relaţional se bazează pe noţiunea matematică de relaţie (din
teoria mulţimilor) definită ca o submulţime a produsului cartezian a unei liste
finite de mulţimi numite domenii. Elementele unei relaţii se numesc tupluri (sau
n-cupluri), iar numărul de domenii din produsul cartezian se numeşte arietatea
relaţiei (FOTACHE 1997, 102).
 
De obicei relaţiile sunt reprezentate sub forma unor tabele în care fiecare
rând reprezintă un tuplu şi fiecare coloană reprezintă valorile tuplurilor dintr-
un domeniu dat al produsului cartezian.
În reprezentarea sub formă de tabel a unei relaţii, coloanelor şi
domeniilor corespunzătoare lor, li se asociază nume intitulate atribute. Mulţimea
numelor atributelor unei relaţii se numeşte schemă relaţională.
 
Deci prin relaţie se înţelege o mulţime de funcţii definite pe o mulţime de
atribute cu valori în reuniunea unor domenii, cu restricţia ca valoarea
corespunzătoare fiecărui atribut să se afle în domeniul asociat acelui atribut.
 
Se numeşte cheie candidat al unei relaţii R coloana sau mulţimea de
coloane din R pentru care valorile corespunzătoare din oricare două tupluri nu
coincid, deci identifică tuplurile prin relaţia respectivă şi nu conţin strict o
submulţime de coloane cu această proprietate. Pentru fiecare relaţie se alege un
candidat de cheie care se numeşte cheie primară a relaţiei. Tuplurile unei relaţii
nu pot să conţină valoarea nulă în coloane ce aparţin cheii primare. Eventualii
candidaţi de chei diferiţi de cheia primară se numesc chei alternante. Se numeşte
cheie străină o coloană sau o mulţime de coloane a unei relaţii R 1 ale cărei valori,
dacă nu sunt nule, coincid cu valori ale unei chei primare dintr-o relaţie R, nu
neapărat distinctă de R1.
 
Mulţimea tuturor schemelor relaţionale corespunzătoare unei aplicaţii se
numeşte schema bazei de date relaţionale, iar conţinutul curent al relaţiilor, la un
moment dat, se numeşte bază de date relaţională.
 
În modelul relaţional, entităţile sunt reprezentate sub formă de relaţii în
care schema relaţională conţine toate atributele entităţii şi fiecare tuplu al
relaţiei corespunde unui element al entităţii.
Cele mai multe cereri ale unui utilizator privesc determinarea unor
informaţii cu anumite proprietăţi, iar răspunsul posibil este o relaţie care descrie
toate elementele cu aceste proprietăţi. Modul de prezentare al răspunsului
depinde de interfaţa dintre DBMS şi utilizator.
 
Exemplu:
 
9.2 2.      Modelul reţea
 
Modelul reţea este cel mai apropiat de forma de reprezentare a bazelor de
date sub forma diagramelor entitate-relaţie. Deosebirea constă în faptul că toate

123
relaţiile ce apar pot fi numai binare şi de tipul 1:1 sau 1:N. Această restricţie
permite reprezentarea grafică a unei baze de date de tip reţea sub forma unui
graf direcţionat numit reţea.
Într-o reţea, nodurile corespund entităţilor şi relaţiile sunt reprezentate
prin săgeţi între noduri (de la tată la fiu) şi anume săgeţi simple dacă relaţia este
de tipul 1:1 şi săgeţi duble dacă relaţia este de tipul 1:N.
 
În modelul reţea, entităţilor le corespund fişiere logice care au drept
câmpuri atributele entităţii şi eventuale câmpuri de legătură pentru relaţii.
Fiecărui element al entităţii îi corespunde o înregistrare logică. Dacă
înregistrările sunt identificate numai prin relaţia cu alte entităţi, atunci se mai
adaugă la înregistrarea logică încă un câmp ce cuprinde un număr de ordine
care permite identificarea acestor înregistrări.
 
Operaţiile cele mai frecvente pentru modelul reţea se împart în două
categorii:
         căutarea unor elemente ale unor entităţi cu anumite proprietăţi
sau căutarea unor informaţii prin utilizarea legăturilor între entităţi;
         navigarea în reţeaua de date.
 
9.2 3.      Modelul ierarhic
 
Modelul ierarhic (arborescent) este considerat un caz particular al
modelului reţea, în care diagrama asociată este o pădure (mulţime de arbori) şi în
care toate legăturile sunt pe direcţia drumului, de la rădăcină la nodul fiu din
relaţie, toate relaţiile fiind de tipul 1:N.
La fel ca în cazul celorlalte două modele, există posibilitatea interpretării
diagramelor entitate-relaţie sub forma modelului ierarhic. Pentru evitarea
redundanţelor în modelul ierarhic, se foloseşte noţiunea de element virtual, care
înlocuieşte dublura unui element prin adresa elementului respectiv, fiecare
element apărând în baza de date reală o singură dată.
Operaţiile din bazele de date de tip ierarhic se traduc în procese de
parcurgere a arborilor. Elementele virtuale permit legarea informaţiilor din
aceeaşi entitate sau din entităţi diferite.
Implementarea la nivel logic pentru modelul ierarhic poate fi cea utilizată
pentru modelul reţea sau prin înregistrări de lungime variabilă.
Datele sunt stocate pe mediul extern în ordinea dată de parcurgerea în
preordine a arborilor, ceea ce uşurează determinarea informaţiilor pentru
cererile care se referă la descendenţii unor noduri printr-un număr mic de
accese la mediul extern.

9.3 Prezentarea conceptelor de bază ale unui sistem de


gestiune a bazelor de date
Ce este o bază de date ?
 
O bază de date conţine toate informaţiile necesare despre obiectele ce intervin într-o mulţime
de aplicaţii, relaţiile logice dintre aceste informaţii şi tehnicile de prelucrare corespunzătoare. În bazele
de date are loc o integrare a datelor, în sensul că mai multe fişiere sunt privite în ansamblu, eliminându-

124
se informaţiile redundante. Este permis accesul simultan la aceleaşi date, situate în acelaşi loc sau
distribuite spaţial, a mai multor persoane prin mai multe tipuri de interogări (BÂSCĂ 1997, 11; DESPI &
1999, 2).
O bază de date poate fi:
         integrată;
         partajată.
 
Prin “integrată” înţelegem că baza de date poate fi gândită ca o unificare de mai multe fişiere
de date, distincte şi neredundante.
Prin “partajarea” unei baze de date se înţelege că bucăţile individuale de date
din baza de date pot fi partajate între mai mulţi utilizatori individuali, fiecare dintre ei
putând avea acces la aceeaşi bucată de date simultan (sisteme multiutilizator).
 
Hardul unui sistem de baze de date constă din volumele de memorare secundare (discuri,
dischete sau benzi magnetice) pe care rezidă baza de date, împreună cu aparatele, unităţile de control
şi canalele respective.
 
Între baza de date fizică (adică datele aşa cum sunt ele memorate pe suport) şi utilizatorii
sistemului există un nivel de software, numit sistem de gestionare a bazelor de date (DBMS – Data
Base Management System), care permite construirea unor baze de date, introducerea informaţiilor în
baza de date şi dezvoltarea de aplicaţii privind bazele de date.
Un DBMS dă posibilitatea utilizatorului să aibă acces la date folosind un limbaj de nivel înalt,
apropiat de modul obişnuit de exprimare, pentru a obţine informaţii, utilizatorul făcând abstracţie de
algoritmii aplicaţi pentru selectarea datelor implicate şi a modului de memorare a lor. DBMS-ul este deci
o interfaţă între utilizator şi sistemul de operare.
 
Orice DBMS conţine un limbaj de descriere a datelor (LDD) care permite descrierea structurii
unei baze de date, a fiecărei componente a ei, a relaţiilor dintre componente, a drepturilor de acces ale
utilizatorului la baza de date, a restricţiilor în reprezentarea informaţiilor, etc. LDD-ul este utilizat atât
pentru proiectarea bazelor de date, cât şi pentru redefinirea lor.
 
O altă componentă a DBMS este limbajul de cereri (LC) sau limbajul de prelucrare a datelor
(LPD), ce permite operaţii asupra datelor aflate în baza de date, cum ar fi:
              încărcarea bazei de date;
              inserarea unui nou element;
              ştergerea unui element;
              modificarea unui element;
              căutarea unor elemente;
              realizarea de diferite statistici asupra datelor.
 
Limbajele LDD şi LC sunt extinderi ale unor limbaje de programare numite limbaje gazdă.
Compilarea succesiunilor de comenzi pentru descrierea datelor sau pentru operarea cu date se reduce
la transformarea acestor comenzi într-o succesiune de instrucţiuni ale limbajelor gazdă care, prin
executare, să dea efectul dorit. O altă modalitate de operare este aceea a transformării comenzilor în
lansări de programe executabile.

Utilizatorii sistemelor de gestionare a bazelor de date (DBMS) se grupează în trei categorii:


a. a.       programatorii de aplicaţie (care scriu programele aplicaţie în limbaje de
programare: Cobol, C, etc.) sau în limbaje de programare specifice: dBase,
FoxPro, etc.);
b. b.      end-userii sau utilizatorii (care accesează baza de date de la un terminal,
folosind un limbaj de interogare numit “query language”);
c. c.       administratorii bazelor de date DBA (care stabilesc structura iniţială a bazei
de date şi modul de memorare a datelor la nivel fizic, acordă utilizatorilor drepturi
de acces la baza de date sau părţi ale ei, asigură securitatea datelor, modifică
structura şi întreţine baza de date).
      Datele operaţionale
 

125
Datele operaţionale sunt date din bazele de date, distincte de datele de intrare, ieşire
sau alte tipuri de date. O bază de date este o colecţie de date operaţionale folosite de către
aplicaţiile sistem ale unei instituţii (Muzeu, Bibliotecă, Intreprindere, etc.)
Datele de intrare sunt informaţii introduse în sistem din lumea exterioară, de obicei
prin terminale.
Datele de ieşire se referă la mesajele şi rapoartele extrase din sistem (tipărite sau
afişate pe ecran).
Entităţile de bază sunt elementele constitutive ale unei baze de date (expl. materialul
arheologic, materialul bibliografic, materialul grafic, etc.). Între aceste entităţi există
întotdeauna asociaţii sau relaţii ce le leagă într-o bază de date comună.
Relaţiile dintre entităţi sunt la rândul lor părţi ale datelor operaţionale, chiar mai
importante decât entităţile asociate. O relaţie poate fi asociată la una, două sau trei entităţi, iar
o entitate poate fi asociată la oricâte relaţii.
      Independenţa datelor
 
Modul în care datele sunt organizate pe suportul secundar de stocare şi modul în care
ele sunt accesate depind de cerinţele aplicaţiei şi de ştiinţa organizării datelor şi tehnicile de
acces.
Imunitatea aplicaţiilor la modificările de structură a memorării şi a strategiei de acces
se numeşte independenţă a datelor.
Tipuri de modificări pe care administratorul bazei de date (DBA) poate să le facă:
         reprezentarea datelor numerice (câmpul numeric poate fi memorat în formă
internă aritmetică sau ca un şir de caractere);
         reprezentarea datelor caracter (un câmp şir de caractere poate fi memorat în
mai multe coduri de caractere : ASCII, EBCDIC, etc.).
 
Terminologie:
       Un câmp este cea mai mică unitate de date stocată în baza de date.
       Baza de date conţine mai multe ocurenţe sau instanţe pentru fiecare din
tipurile de câmpuri.
       O înregistrare este o colecţie de nume de câmpuri asociate.
       O ocurenţă sau instanţă de înregistrare constă dintr-un grup de ocurenţe de
câmp înrudite (asociate) şi reprezintă o asociere între ele.
       Un fişier este o colecţie a tuturor înregistrărilor de unul sau mai multe tipuri.
       Într-o bază de date, un câmp numeric poate avea două unităţi metrice (inches
şi centimetrii) la alegerea utilizatorului.
 
Structura înregistrărilor memorate
 
Într-o bază de date, două tipuri de înregistrări pot fi combinate într-unul singur.
Exemplu:
înregistrarea 1.: neolitic, Vinča, ceramică pictată, străchini (…)
înregistrarea 2.: neolitic, Petreşti, ceramică pictată, străchini (…)
structură integrată: neolitic, Vinča, Petreşti, ceramică pictată, străchini
(…)
 
Astfel se explică faptul că înregistrarea logică a unei aplicaţii poate consta dintr-o
submulţime a unei înregistrări memorate, adică anumite câmpuri memorate pot fi invizibile
pentru o aplicaţie particulară (de exemplu elementele care se repetă). La fel, un singur tip de
înregistrare memorată poate fi despicat în două, pentru a particulariza anumite aplicaţii.
 
  Structura fişierelor memorate
 
Un fişier poate fi implementat fizic în memorie în mai multe moduri:

126
         poate fi în întregime conţinut într-un volum de memorare (expl.: disc
magnetic);
         poate fi împărţit pe mai multe volume de tipuri diferite;
         poate fi sau nu fizic secvenţial, în concordanţă cu valorile unui anumit câmp;
         poate avea unul sau mai mulţi indecşi asociaţi;
         poate fi construit cu pointeri;
         înregistrările pot fi blocate sau nu, etc.
 
Baza de date trebuie să fie în stare să crească fără a afecta aplicaţiile existente,
aceasta fiind raţiunea majoră a independenţei datelor.
 
    Arhitectura unui sistem de baze de date
 
a. a.      nivelul exterior scheme exterioare
(vederile utilizatorilor
individuali)
 

b. b.      nivelul conceptual


(vederile comune utilizatorilor)
 
c. c.       nivelul intern
(vederile memorate)
 
O bază de date poate fi privită din mai multe puncte de vedere:
a. a.       opţiunea utilizatorului, care lucrează cu anumită părţi ale unei baze de date
numite vederi;
b. b.      opţiunea administratorului bazei de date care integrează toate vederile
referitoare la baza de date într-un singur model numit schemă conceptuală, ea
reprezentând nivelul logic al bazei de date;
c. c.       opţiunile implementatorului bazei de date (coincide uneori cu cele ale
administratorului) care priveşte baza de date ca pe o colecţie de fişiere memorate
pe diferite medii externe (benzi şi discuri magnetice), ele constituind nivelul fizic
al bazelor de date.
 
Primele două nivele sunt descrise prin planuri ce constau în enumerarea tipurilor de entităţi ce
apar în baza de date, relaţiile dintre aceste tipuri de entităţi şi modul de trecere de la noţiunile acestui
nivel la nivelul imediat următor. În mod curent, aceste planuri se numesc scheme externe, subscheme
conceptuale sau vederi, pentru primul nivel şi scheme conceptuale pentru al doilea nivel. Descrierile la
nivel fizic sunt făcute prin scheme interne sau scheme fizice.
 
Scheme externe
 
O schemă externă reprezintă conţinutul bazei de date aşa cum este ea văzută de un utilizator
particular.
Exemplu:
Pentru un utilizator poate să apară într-o vedere atributul număr străchini (= numărul
fragmentelor ceramice de tipul “N”), dar la nivel logic şi fizic acest atribut nu este indicat, din cauza
permanentei modificări a conţinutului său. În acest caz se foloseşte la nivel logic atributul ceramică (=
numărul total general de fragmente ceramice) din care se scad atributele nr. oale, nr. farfurii, nr.
chiupuri, etc. (= numărul fragmentelor ceramice “M”≠”N”) din baza de date. Astfel se permite aflarea
numărului exact al fragmentelor ceramice de tip strachină din baza de date.
 
Pentru utilizatorul obişnuit, modul de definire a vederilor este transparent, el putând să obţină
sau să modifice informaţiile dorite prin intermediul unor comenzi cu structură dată, folosind formule
predefinite pe care le completează sau poate utiliza un sistem de meniuri.
În reprezentarea intuitivă a vederilor intervin noţiunile de entitate, relaţie, atribut, cheie,
funcţionalitate, diagramă, şi altele pe care le vom definii ulterior.

127
Schema externă este scrisă într-un sublimbaj de definire a datelor (SLDD) dintr-un DLL numit
adesea DLL extern.
  Scheme conceptuale
 
O schemă conceptuală este o reprezentare a întregii informaţii conţinute în
baza de date ce combină subschemele vederilor ce privesc o anumită aplicaţie într-un
model unitar. Acest tip de schemă trebuie să se bazeze pe un model teoretic şi să fie
simplă, adică uşor de înţeles şi de prelucrat.
 
Sistemele de gestiune a bazelor de date au fost clasificate în trei grupe mari,
în funcţie de tipul elementelor cu care lucrează şi a structurilor obţinute:
a. a.       modelul reţea – permite lucrul cu entităţi şi relaţii binare de tipul 1:1 şi 1:N,
diagrama rezultată fiind un graf oarecare;
b. b.      modelul arborescent (ierarhic) – permite lucrul cu entităţi şi relaţii binare de
tipul 1:1 şi 1:N, iar diagrama este alcătuită dintr-o mulţime de arbori;
c. c.       modelul relaţional – în care intervin numai relaţii şi operaţii cu aceste relaţii.
 
Scheme interne
 
Schemele interne descriu diferitele fişiere utilizate pentru memorarea
informaţiilor bazei de date şi modul de operare cu ele. Există mai multe moduri de
organizare a fişierelor, cele mai cunoscute fiind:
         organizarea secvenţială;
         organizarea cu index rar;
         organizarea cu index dens;
         organizarea cu dispersie;
         organizarea folosind B-arbori.
 
Traducerea schemelor conceptuale în scheme interne se face, de obicei,
automat de către DBMS. Pe lângă stabilirea diferitelor tipuri de înregistrări utilizate
în reprezentarea fizică a datelor, se specifică şi existenţa indecşilor asociaţi unor
fişiere, semnificaţia câmpurilor înregistrărilor, ordinea de apariţie a înregistrărilor şi
modul de acces.
Corespondenţa dintre scheme poartă numele de mapare şi este de două tipuri:
         mapare conceptuală / internă (vederea conceptuală / baza de date memorată);
         mapare externă / conceptuală (vedere externă particulară / vedere
conceptuală).
 
Sistemul de gestiune a bazelor de date (DBMS) este softul (programul) care
coordonează toate accesele la baza de date, în modul următor:
a. a.       un utilizator emite o cerere de acces, folosind un limbaj particular de
manipulare a datelor;
b. b.      DBMS-ul interceptează cererea şi o interpretează;
c. c.       DBMS-ul inspectează, pe rând, schema externă, maparea
externă/conceptuală, schema conceptuală, maparea conceptuală/internă şi
definiţia de structură de memorare;
d. d.      DBMS-ul realizează operaţiile necesare asupra bazei de date memorate.
 
Administratorul bazei de date (DBA) urmează apoi să gestioneze operaţiile
specifice, responsabilităţile lui incluzând:
         decizia asupra conţinutului informaţiei inclusă în baza de date;
         decizia asupra structurii de memorare şi a structurii de acces;
         legătura cu utilizatorii;
         definirea procedurilor de verificări autorizate şi de validări;

128
         definirea unei strategii pentru salvări şi restaurări;
         monitorizarea performanţei şi răspunsuri la schimbări de cerinţe.
 
Pentru aceasta DBA are la îndemână un număr de programe utilitare pentru a
se ajuta în rezolvarea acestor sarcini:
         rutina de încărcare (pentru a crea versiunea iniţială a bazei de date);
         rutina de reorganizare (pentru a reorganiza baza de date prin eliminarea
datelor perimate şi introducerea altora noi);
         rutine jurnaliere (pentru a nota orice operaţie asupra bazei de date împreună
cu identificarea utilizatorului care a efectuat-o);
         rutine de restaurare (pentru a restaura baza de date la o stare anterioară unui
eşec hard sau de programare);
         rutina de analiză statistică (pentru a sista în realizarea performanţei).
 
Instrumentul utilizat de DBA în lucrul cu programele utilitare este dicţionarul
de date. El este o bază de date ce conţine date despre date, adică descrieri ale
obiectelor sistemului.
De asemenea atât DBA cât şi utilizatorul beneficiază de o interfaţă utilizator
pentru a uşura accesul la date. Această interfaţă poate fi definită ca un ecran în sistem,
sub care totul devine invizibil pentru utilizator. Interfaţa se află întotdeauna la nivelul
extern.
 
Într-un sistem de baze de date (DBMS) datele sunt memorate la locaţia la care sunt folosite
mai des, dar ele sunt disponibile (prin reţeaua de comunicaţii) şi utilizatorilor din alte locaţii. Acest tip de
bază de date, împrăştiată într-o reţea de calculatoare se numeşte bază de date distribuite.
STRUCTURA RELATIONALA A DATELOR

Prezentarea sructurii relationale a datelor impune definirea notiunilor de domeniu , atribut ,


relatie si schema a unei relatii [6].
In figura 2.2.1 se prezinta un model relational ce corespunde unei multimi concrete de
caracteristici despre lumea reala .Orarul de zbor al avioanelor poseda o sructura de date
relationala .Pentru fiecare linie aeriana din orarul de zbor sunt date caracteristicile :numarul cursei,
aeroportul de decolare, aeroportul de aterizare, ora decolarii, ora aterizarii.
Fiecare avion este determinat de multimea valorilor de fiecare linie.Trebuie sa ne limitam
numai la actele date care pot sa apara in definirea coloanei.Coloana cu numele ,Punct de decolare(PD)
contine numele aeroporturilor liniilor aeriene considerate.Coloana Ora decolarii (OD) (respectiv, Ora
aterizarii (OA))exprima ora la care are loc decolarea (respectiv , aterizarea).Coloana cu numele Punct
de aterizare (PA) contine numele aeroportului unde se aterizeaza.
Nr Punct de Punct de Ora de Ora de
zbor(nr) decolare(Pd) aterizare(pa) decolare(Od) aterizare(oa)
70 Bucurest Craiova 16:59 17:50
i
75 Craiova Bucuresti 07:25 08:25
80 Bucurest Timisoara 17:30 19:30
i
85 Timisoar Bucuresti 07:15 09:25
a
90 Timisoar Craiova 10:15 13:20
a
Definitia 2.2.1 Domeniul reprezinta o multime de valori ,caracterizat printr-un nume si este
definit fie explicit prin enumerarea tuturor componentelor sale,fie printr-o proprietate distinctiva a
valorilor din domeniul respectiv.
Penrtu tabelul din figura 2.2.1 se pot da urmatoarele exemple:
D1={Bucuresti,Craiova,Timisoara}
D2={x / xєN , xє[1,100]}
Atributul reprezinta coloana unei tabele de date , caracterizata printr-un nume. Numele
coloanei (atributului ) exprima de obicei semnificatia valorilor din cadrul coloanei respective .Fiecarui

129
nume de atribut ii corespunde un domeniu Di numit domeniu numit domeniul atributului Ai ,1 in si se
va nota cu dom(Ai) .Pt a diferentia coloanele care contin valori ale aceluiasi domeniu si a elimina astfel
dependenta de pozitie in cadrul tabelei , se asociaza fiecarei coloane un nume distinct.
Pentru tabelul din figura 2.2.1 avem atributele NR,PD,PA,OD,OA si domeniile asociate
dom(NR), dom(PD), dom (PA), dom (OD),dom (OA).
De exemplu , dom (PD) ={Bucuresti ,Craiova,Timisoara}.
Fie D1 , D2 , …,Dn domenii finite , nu neaparat disjuncte.Produsul cartezian D1xD2x…xDn
al acestora este definit de multimea tuplurilor <v1,v2,…, vn> unde v1єD1,v2єD2,…,vn єDn. Numarul n
defineste aritatea tuplului.
Definitia 2.2.2 O relatie r pe multimile D1,D2,…,Dn este o submultime a produsului
cartezian D1x D2 x … Dn , deci o multime de tupluri.
Exista si un alt mod de a defini o relatie, si anume , ca o multime finita de functii. Asociem
fiecarui domeniu Di un atribut Ai si definim relatia r ca fiind o multime de tupluri {t1,t2,… ,tn} , unde ti :
{A1, A2, … ,An} - D1 D2 … Dn si ti (A j) єDj pentru orice valori ale lui i si j .Intr-o relatie ,
tuplurile trebuie sa fie distincte (nu se admit duplicari ale tuplurilor). De obicei ,vom nota relatia cu r sau
r{A1,A2, … , An} .
Orarul din figura 2.2.1 reprezinta un exemplu de relatie pe care o vom numi orar.Continutul
informational al liniei nu depinde de ordinea coloanelor , de exemplu coloanele PS si PA pot fi
interschimbate.
Definirea unei relatii ca o multime de tupluri sau ca o multime de functii se refera la
multimi care variaza in timp (se adauga , se sterg, sau se modifica elemente).Pentru a caracteriza o
relatie este nevoie de un element invariant in timp , iar acest invariant este dat de structura relatiei
(schema relatiei).
Definitia 2.2.3 Multimea tuturor atributelor R={A 1, A2 , … , An}corespunzatoare unei
relatii o numim schema relatiei si o notam r(A1 , A2 , … , An) .
Schema relatiei orar se defineste astfel: orar (NR,PD,PA,OD,OA).
Schema unei relatii mai este cunoscuta si sub numele de intensia unei relatii , ca expresie a
proprietetilor comune si invariante ale tuplurilor care compun relatia .Spre deosebire de intensie ,
extensia unei relatii reprezinta multimea tuplurilor care compun la un moment relatia , multime care este
variabila in timp . De obicei , extensia unei relatii este stocata fizic in spatiul asociat bazei de date , caz
in care relatia se numeste relatie de baza .Exista situatii in care extensia nu este memorata in baza de
date . Este cazul asa numitelor relatii virtuale , cunoscute si sub numele de relatii derivate sau viziuni.
Acestea sunt definite implicit , pe baza altor relatii , prin intrmediul unei expresii relationale iar stabilirea
tuplurilor care o compun se face prin evaluarea expresiei.
Asadar , putem reprezenta o relatie printr-un tabel bidimensional in care fiecare linie
corespunde unui tuplu si fiecare coloana corespunde unui domenui din produsul cartezian. Numarul
atributelor defineste gradul relatiei , iar numarul de tupluri cardinalitatea relatiei .
Fiecare linie a relatiei este o multime de valori , cate una pentru fiecare nume de
atribut .Linia relatiei se numeste tuplu. In figura 2.2.1 relatia orar este formata din 5 tupluri . Unul dintre
acestea , notat cu t , este definit astfel:
t(NR)=75 , t(PD) = Craiova , t(PA)=Bucuresti,t(OD)=7.25, t(OA)=8.25
Valoarea concreta a tuplului t pentru atributul A o numim Avaloarea tuplului t , iar daca t
este considerata ca functie , atunci Avaloarea tuplului o vom nota cu t(a). Pentru X R, restrictia
tuplului t la X o notam cu t/X sau t(X) si o vom numi Xvaloarea tuplului t .
Pentru relatia orar , consideram un tuplu t oarecare , de exemplu primul tuplu din relatie .
{PD , PA} – valoarea tuplului t este tuplul t’ pentru care t’(PD)=Bucuresti, t’(PA)= Craiova.

FORME NORMALE IN BAZE DE DATE


In lucrul cu baze se manifesta o serie de anomalii datorita dependentelor “nedorite” ce se
manifesta intre datele din cadrul relatiilor bazei.Aceste dependente determina cresterea redundantei
datelor si reducerea flexibilitatii structurii bazei de date .Formele normale ale relatiilor sunt definite in
raport de anomaliile care pot apare in lucrul cu aceste relatii , deci in functie de anumite dependente
“nedorite”.
O relatie este intr-o anumita forma normala particulara daca satisface o multime
specificata de restrictii . Pana in prezent se cunosc cinci forme normale ale relatiilor dintr-o baza de
date.
Fie r[A1,…,An]o relatie si X={Ai1 ,…,Aip}{A1,…,Am} o multime de atribute . Reamintim
ca ,prin proiectia relatiei r pe X se intelege r’[Ai1,…,Aip]=Ai1,…,Ain(r)unde pt p=(a1,a2,…,an) r ,
avem x p=p[X]=(ai1 ,ai2 ,…,aip) r’ (si toate elementele din r’ sunt distincte).

130
Fie relatiile r(X,Y), s(X,Z) si X,Y,Z multimi de atribute , XZφ.Prin join-ul natural al
relatiilor r si s se intelege :
r⊲⊳s={(x(t),y(t),z(v)) t  r, v  s,y(t)=y(v)}
O relatie r se poate descompune in mai multe relatii noi : r1 ,r2 ,…,rm.Aceasta
descompunere este corecta , daca : r= r 1⊲⊳r2 ⊲⊳… ⊲⊳rm.
Vom da un exemplu de descompunere care nu este corecta .Fie relatiile :
r[NUME,VARSTA,SALARIU,LOCALITATE]
r1[NUME,SALARIU]
r2[VARSTA,SALARIU,LOCALITATE].
si presupunem ca pt r avem urmatoarea extensie:
NUME VARSTA SALARIU LOCALITATE

Ionescu 30 800000 Arad


Popescu 40 1200000 Oradea
Georgescu 60 1500000 Iasi
Calinescu 25 1200000 Arad

In acest caz se obtine:


r1

NUME SALARIU

Ionescu 800000
Popescu 1200000
Georgescu 1500000120000
Calinescu 0

r2
VARSTA SALARIU LOCALITATE

30 800000 Arad
40 1200000 Oradea
60 1500000 Iasi
25 1200000 Arad

r1 ⊲⊳r2
NUME VARST SALARIU LOCALITATEA
A
Ionescu 30 800000 Arad
Popescu 40 1200000 Oradea
Popescu 40 1200000 Arad
Avram 60 1500000 Iasi
Calinescu 25 1200000 Arad
Calinescu 25 1200000 Oradea

Este posibil , ca in diverse aplicatii sa apara atribute (simple sau compuse), ce au mai
multe valori pt un element din relatie.Aceste atribute formeaza un atribut repetitiv .Prin atribut simplu
vom intelege un singur atribut din relate, iar prin atribut compus o multime de atribute (cel putin doua).
Consideram , de exemplu relatia :

131
persoana[NUME,AN-NASTERE,PROFESIA,NUME-COPIL,AN-NASTERE-COPIL] cu
atributul NUME cheie primara.Perechea {NUME-COPLI,AN-NASTERE-COPIL}este un grup repetitiv ,
deoarece relatia poate avea urmatoarea extensie:
Popa 1970 inginer Daniel 1992
Anca 1994
Viorel 1998
Ionescu 1966 economist Andrei 1989
Magda 1993
De asemenea, relatia:
carte [COTA,AUTOR,TITLU,EDITURA,AN-APARITIE,CUVINTE-CHIE]cu atributul cheie
COTA cheie primara , are atributele respective AUTOR si CUVINTE-CHEIE.Ocarte poate avea mai
multi autori si mai multe cuvinte cheie.
Grupele de atribute repetitive creeaza greutati in memorarea diverselor relatii si de aceea
se incearca emiterea lor,fara apierde insa din informatii.Daca r[A1, …,An]este o relatie , unde Am+1 ,
…,An formeaza un grup repetitiv , atunci relatia r se poate descompune in doua relatii fara atribute
repetitive .Daca A1`,…,Ap, p<m , este o cheie pt relatia r atunci cele doua relatii in care se descompune
r sunt:
r′[A1,A2,…,Am]=A1,…,Ap,Am+1,..,An(r)
r″[A1,A2,…,Ap,Am+1,…,An]=A1,…,Ap,Am+1,…,An (r)

Astfel , relatiile persoana si carte se descompun in doua , respectiv trei relatii:


parinte[NUME,AN-NASTERE,PROFESIA]
copil[NUME,NUMECOPIL,AN-NASTERE-COPIL]
autori[COTA,AUTOR]
carti[COTA,TITLU,EDITURA,AN-APARITIE]
cuvinte[COTA,CUVANT-CHEIE]
Definitia2.2.8 [3] O relatie este in prima forma normala (FN1)daca nu contine grupuri (de
atribute ) repetitive .
Urmatoarele forma normale utilizeaza notiunea de dependenta functionala intre submultimi
de artibute .Stabilirea dependentelor functionale este sarcina administratorului bazei si depinde de
semnificatia datelor care se memeoreaza in relatie . Operatiile de actualizare a datelor
(adaugare,modificare,stergere) nu trebuie sa modifice dependentele functionale existente.
Definitia 2.2.9 Fie r[A1,…,An] o relatie si X, Y {A1,…,An}.Atributul Y este complet
dependent functional de X , daca Y este dependent functional de X(XY)si nu este dependent
functional de nici o submultime de atribute din X (pt aceasta dependenta functionala trebiue ca X sa fie
atribut compus).
Fie r [A1,…,An] orelatie si CA={A1,…,An} o cheie .Presupunem ca exista YA,
YC=(Y nu este chie ), Y dependent functional de XC (Y este complet dependent functional de o
submultime stricta de atribute cheie).Dependenta XY se poate elimina daca relatia r se descompune
in urmatoarele doua relatii:
r=[XY]=xy(r)
r=[AY ]=AY(r)
Definitia2.2.10 [3] O relatie este in a doua forma normala (FN2) daca este de prima forma
normala si orice atribut (simplu sau compus) este complet dependent de cheie sau este inclus in cheie.
Exemplul 2.2.6 Se considera urmatoarea relatie (cu rezultatele la examene):
examen [NUME-STUDENT,DISCIPLINA,NOTA,PROFESOR]
in care cheia este {NUME-STUDENT,DISCIPLINA}si unei discipline ii corespunde un singur
cadru didactic , iar uni cadru didactic pot sa-i corespunda mai multe discipline , deci avem dependenta
functionala DISCIPLINAPROFESOR.
De aici deducem ca atributul PROFESOR nu este complet dependent functional de
cheie.Atunci , relatia examen se poate descompune in urmatoarele doua relatii:
apreciere [NUME-STUDENT,DISCIPLINA,NOTA] si
stat-functii[DISCIPLINA,PROFESOR]

132
Daca depndenta functionala DISCIPLINAPROFESOR nu este respectata , atunci poate
apare o inconsistenta .Fie doua elemente din relatie:

T …DISCIPLINA … PROFESOR
……………………………………
t1 …ANALIZA … POPA
t2 …ANALIZA … POPA
……………………………………..

Daca in t1 vsloarea atributului PROFESOR se schimba, dar in t2 nu se face schimbarea,


atunci dependenta functionala nu este respectata si apare o inconsistenta (la aceeasi disciplina apar
cadre didactice diferite).
Definitia 2.2.11 Un atribut Z este tranzitiv dependent de atributul X daca exista Y astfel
incat XY,YZ, iar YX nu are loc si Z nu e inclus in XY.
Daca C este o cheie si Y un atribut tranzitiv dependent de cheie , atunci exista un X care
verifica CX si XY .Deoarece relatia este in forma normala FN2 , obtinem ca Y este complet
dependent de C, deci XC = si exista o dependenta XY , iar X nu este cheie.
Daca r[A1,…,An]are cheia C si exista atributul Y{A1,…,An} ,tranzitiv dependent de C si
care nu este cheie (adica YC=), atunci relatia r se poate descompune in urmatoarele relatii (se
elimina dependenta functionala XY):
r[XY]=XY(r)
r=[AY ]=AY(r)
Definitia 2.2.12 [3] Orelatie este in a treia forma normala (FN3) daca si numai daca relatia r
este in a doua forma normala si fiecare atribut care nu este cheie (nu participa la o cheie) nu este
tranzitiv dependent de nici o cheie a lui r.
Exemplul 2.2.7 Se considera urmatoarea relatie (cu rezultatele obtinute de absolventi la
lucrarea de diploma):
diploma[NUME-ABSOLVENT,NOTA,CADRU-DID –INDR,CATEDRA]
cu cheia NUME-ABSOLVENT.
Se obseva ca avem urmatoarele dependente functionale:
CADRU-DID-INDRCATEDRA
NUME-ABSOLVENTCADRU-DID-INDR
Relatia initiala se poate , atunci descompunerea in urmatoarele doua relatii :
rezultate[NUME-ABSOLVENT,NOTA,CADRU-DID-INDR]
indrumatori[CADRU-DID-INDR,CATEDRA].
Dupa definitia ormei normale FN3 data de E.F/Codd[16] , ulterior , au mai aparut o serie de noi
definitii:
O relatie r este in a treia forma normala Boyce-Codd(FNBC) daca orice determinant este
cheie (principala sau seundara).
O relatie este in a treia forma normala C.J.Date (FN3 Date) [4] daca orice atribut care nu este
cheie, nu este tranzitiv dependent de cheia principala.
Exemplul 2.2.8 Transportul local pe timp de o saptamana dintr-un oras este specificat de
relatia:
transport [ZI,NR-TRASEU,NR-MASINA,COND-AUTO]
unde COND-AUTO este numele conducatorului auto (el conduce o singura masina , dar pe
acea masina o poate conduce si un alt conducator).Avem cheia : {ZI,NR-TRASEU, NR-MASINA} si
dependenta COND-AUTONR-MASINA.
Relatia definita este in FN3 Date (NR-MASINA)apare in cheie , dar nu este in FNBC si se
poate descompune in urmatoarele doua relatii :
traseu [ZI,NR-TRASEU,NR-MASINA]
soferi[NR-MASINA,COND-AUTO]
Definitia 2.2.13 Fie relatia r [A1, A2,…,An]si doua multimi de atribute X,Y{A1,
…,An} .Spunem ca Y este multiplu dependent funcional de X(XY) daca si numai daca pt orice t1, t2
 r pt care x(t1)=x (t2) exista t1 si t2  r astfel incat :
x(t1)=x(t2)=x(t3)=x(t4)
y(t1)=y(t2)=y(t3)=y(t4)
A-X-Y(t1)=y(t2)=A-X-Y(t3)=A-x-Y(t4)
Dependenta XY se numeste dependenta functionala multipla sau dependenta
multivaloare si se poate reprezenta astfel:

133
X Y A-X-Y
t1 v u1 w1
t2 v u2 w2
t3 v u1 w2
t4 v u2 w1

Daca A=XY sau YX, atunci dependenta XY se numeste tricviala.


Definitia 2.2.14 [3] O relatie r este in a patra forma normala (FN4) daca pt dependentele
funcionale multiple , avem XY este dependenta triviala sau X este cheie pt r.
Aceasta definitie difera de definitia formei FNBC doar prin folosirea dependentelor
functionale multiple in locul celor simple.
Exemplul 2.2.9 Consideram relatia carte in care se observa ca avem urmatoarele
dependente functionale:
COTAAUTOR ;COTA CUVANT-CHEIE.
COTA{TITLU,EDITURA,AN-APARITIE}
carte
AUTOR COTA TITLU EDITU AN-APARITIE CUVINTE-
RA CHEIE
Popescu I. 1 Mara ALL 1990 Rom
Slavici I. 1 Mara ALL 1990 Rom
Popescu I. 1 Mara ALL 1990 Roma
Slavici I. 1 Mara ALL 1990 n
Roma
n
Tudor P. 2 Baze de date Teora 1993 Bdate
Ioan S. 2 Baze de date Teora 1993 Bdate
Vigu T. 2 Baze de date Teora 1993 Bdate
Tudor P. 2 Baze de date Teora 1993 Rom
Ioan S. 2 Baze de date Teora 1993 Rom
Vigu T. 2 Baze de date Teora 1993 Rom

Pt a forma FN4 , vom descompune relatia in urmatoarele relatii:


COTA TITLU EDITURA AN-APARITIE
1 Mara ALL 1990
2 Baze de date Teora 1993

COTA AUTOR
1 Popescu I.
1 Slavici I.
2 Tudor P.
2 Ioan S.
2 Vigu T.

COTA CUVANT-
CHEIE
1 Rom
1 Roman
2 Bdate
2 Rom

Definitia 2.2.15 Fie relatia r [A1, A2, …, An]si r1[x1],…,rm[xm] o descompunere a relatiei r
. Relatia r satisface dependenta join notata *(r1,…,rm) , daca r = r1 ⊲ ⊳ r2 ⊲ ⊳ … ⊲⊳rm .Daca
una din relatiile ri este egala cu r , atunci aceasta dependenta este triviala.
Sa consideram o relatie r si o dependenta join*(r1,r2) , unde r1[X],r2[Y] sunt relatii . Cu
aceste presupuneri , avem : r = r1⊲⊳r2 .

134
Fie t1, t2  r si valotile lor date prin urmatorul tabel:
X-Y XY Y-X
x(t1) u1 V ….
x(t2) u2 V ….
………………………………………….
y(t1) …… V w1
y(t2) …… V w2

Daca se calculeaza r1⊲⊳r2 , care este egala cu r , rezulta faptul ca mai avem doua
elemente t3 si t4 din r cu valorile urmatoare:
X-Y XY Y-X
t1 u1 v
t2 w1
u2 v
t3 w2
t4 …………………………………
………………
u1 v
w1
u2 v
w2

De aici , se deduce ca XYX sau XY Y , deci dependenta join*(r1,..,rm) este
echivalenta cu dependenta functionala multipla.
Definitia 2.2.16 [5] O relatie este in forma normala cinci (FN 5) cu respectarea unei multimi
D de dependente functionale multiple sau join , daca fiecare dependenta *(r1 ,…,rm) este fie triviala , fie
Xi este cheie (avem ri[Xi])pt r , pt toate valorile lui i.
Cu alte cuvinte , o relatie r este in FN5 daca orice dependenta join definita pe r este
implicata de cheile candidat ale lui r.
Exemplul 2.2.10 Fie relatia cursa [CP#,CA#,PD,PA], unde CP-codul pilotului , CA-codul
avionului, PD si PA punctul de decolare , respectiv aterizare.
In aceasta relatie , care este in FN4 , nu exista dependente functionale multiple, dar exista
o redundanta logica , care va ridica probleme la actualizare.
cursa

C C PA PD
P# A#
1 1 Sibiu Iasi
1 00 Iasi Sibiu
1 1 Sibiu Iasi
0 00 Sibiu Iasi
1 1
0 00
1 1
0 01

Descompunem relatia cursa prin proiectie in :


r1 (CP#,CA#)
r2 (CP#,PD,PA)
r3 (CP#,PD,PA)
Se observa ca, cursa r1⊲⊳r2; cursa r2⊲⊳r3; cursa r1⊲⊳r3, dar cursa
=r1⊲⊳r2⊲⊳r3 .
In relatia r1⊲⊳r2 a aparut un tuplu (10,101,Iasi,Sibiu)care nu exista in cursa .Daca ar fi
existat , ar fi avut loc multidependenta CPCA si astfel descompunerea reversibila a relatie cursa r1
si r2.

135
r1
CP CA#
#
11 100
10 100
10 101

r2
C PD PA
P#
1 Sibiu Iasi
1 Iasi Sibiu
1 Sibiu Iasi
0
1
0

r3
C PD PA
A#
1 Sibiu Iasi
00 Iasi Sibiu
1 Sibiu Iasi
00
1
01

r1⊲⊳r2
C C PD PA
P# A#
1 1 Sibiu Iasi
1 00 Iasi Sibiu
1 1 Sibiu Iasi
0 00 Iasi Sibiu
1 1 Sibiu Iasi
0 00
1 1
0 01
1 1
0 01

1.2.2. TEHNICA NORMALIZARII RELATIILOR


Proiectarea schemei conceptuale a unei baze de date presupune parcurgerea
urmatoarelor etepe:
Determinarea formei normale in care trbuie sa se afle relatiile din baza de date .In majoritatea
cazurilor bazele de date reltionale sunt constituite din relatii aflate in FN1 sau FN2 .Acest lucru se
explica prin faprull ca formele normale superioare , desi reduc dificultatea de realizare a operatiilor de
actualizare , reduc in acelasi timp si performantele operatiilor de regasire a datelor.Relatiile aflate in
forme normale superioare contin un nr mic de atribute si acest lucru favorizeaza opertiile de actualizare
a datelor , dar ingreuneaza procesul de regasire a lor , deoarece satisfacerea cererilor de date impune
interogarea simultana a mai multor relatii, deci efectuarea unor operatii de join , care sunt costisitoare in
termenii resurselor de calcul solocitate.
Stabilirea relatiilor care sa faca din BD,in forma normala precizata la etapa anteriora .
Presupune definirea schemei relatiilor si a restrictiilor de integrare .Modul prin care se stabileste
multimea de relatii din baza de date , se numeste tehnica relatiilor.
Descrierea schemei conceptuale in limbajul de descriere a datelor utilizat de SGBD-ul
relational ce se utilizeaza.

136
In obtinerea unei baze de date performanta , un rol important il are tehnica normalizarii
relatiilor .Aceasta tehnica permite obtinerea schemei conceptuale printr-un proces de ameliorare
progresiva a unei scheme concepute initial,prin utilizarea formelor normale.Dupa fiecare etapa de
ameliorare , relatiile din baza ating un anumit grad de perfectiune , prin eliminarea unui anumit tip de
dependente nedorite (dependente functionale partiale,tranzitive,multivaloare), deci se afla intr-o anumita
forma normala.
Procesul de ameliorare , trebuie sa satisfaca urmatoarele cerinte:
sa garanteze conservarea datelor , adica in schema conceptuala finala trebuie sa figureze
toate datele din schema initiala;
sa garanteze conservarea dependentelor dintre date, adica in schema finala fiecare
dependenta trebuie sa aiba determinantul si determinatul in schema aceleiasi relatii;
sa reprezinte o descompunere minimala a relatiilor initiale.Nici una din relatiile care compun
schema finala nu trebuie sa fie continuta intr-o alta relatie din aceasta schema .
Necesitatea normalizarii este ilustrata in exemplul urmator.
Fie schema relationala avion(NR,TIP,CAPACITATE,LOCALITATE), cu cheia primara
numarul avionului (NR).
avion
N TIP CAPACITATE LOCALITATE
R
1 IAR500 90 Brasov
00 IAR500 90 Arad
1 ROMBAC 100 Bucuresti
01 TU154 200 Timisoara
1
02
1
03
Presupunem ca in cadrul companiei , exista restrictia : “toate avioanele de acelasi tip au
aceeasi capacitate” care este de fapt o dependenta functionala de forma TIPCAPACITATE .
Datorita acestei dependente , pot exista redundante in date sau pot sa apara anomalii la
reactualizare.Astfel , in relatia de mai sus , avem o redundanta logica (perechea <IAR 500 ,90>apare de
mai multe ori)precum si anomalii l areactualizare : daca dorim sa stergem avionul cu nr 102 , vom
pierde informatia care ne arata ca un avion ROMBAC are capacitatea 100.
De asemenea , daca dorim sa modificam capacitatea avionului IAR 500 , de la 90 la 190
de locuri putem intalni urmatoarele anomalii: modificand un singur tuplu,relatia devine incoerenta
(restrictia nu mai este verificata), iar daca modificam toate tuplurile cu IAR 500 , costul modificarii creste
semnificativ.
Prezentam in continuare procedeul de ameliorare a schemei conceptuale initiale , care
consta in aducerea acesteia la diferite forme normale([4]).
Aducerea relatiilor la FN1
Presupune eliminarea atributelor compuse si a celor repetitive.Aducerea unei relatii in FN1 se
realizeaza atfel:
1.Se trec in relatie , in locul atributelor compuse componentele acestora , ca atribute simple.

Aducerea relatiilor in FN2

Presupune eliminarea dependentelor functionale partiale din relatiile aflate in


FN1.Procesul de aducere a unei relatii din FN1 in FN2 se desfasoara astfel
1.Pentru fiecare dependenta functionala partiala se creaza o noua relatie,cu
schema constituita din determinantul si determinantul acestei dependente.
2.Daca in relatia initiala exista mai multe dependente functionale partiale cu
acelasi determinant,pentru toate acestea se creaza o singura relatie cu sche
ma constituita din determinantul,luat o singura data si din determinantii
depoendentelor considerate.
3.Se determina cheia primara a fiecarei noi relatii creata in pasul1.Aceasta va

137
fi formata din atributul/atributele din determinantul dependentei functiona-
le partiale,care a stat la baza constituirii relatiei.
4.Se analizeaza relatiile rezultate la pasul 1.Daca aceste relatii contin depen-
dente functionale partiale se reia procesul de aducere in FN2,astfel procesu
s-a terminat.
Aducerea relatiilor in FN3
Presupune aducera unei relatii in FN2 in FN3 prin aliminarea dependente-
lor tranzitive.
1.Pentru fiecare dependenta functionala tranzitiva se transfera atributele implicate in
dependenta tranzitiva intr-o noua relatie.
2.Se determina cheia primara a fiecarei noi relatii creata la pasul 1.
3.Se introduc in relatia initiala in locul atributelor transferate,cheile primare determinate
la pasul2.
4.Se reanalizeaza relatia initiala .Daca in cadrul ei exista noi dependente
tranzitive,atunci se face transfer la pasul1,altfel procesul de aducere la FN3
s-a terminat.
A treia forma normala poate fi obtinuta si cu ajutorul unei scheme sinteza
([8],[9]).Algoritmul de sinteza construieste o acoperire minimala F+ a depen-
dentelor functionale totale.Se elimina atributele si dependentele functionale
redundante.Multimea F este partitionata in grupuri Fi,astfel incat in fiecare
grupa Fisunt dependente functionale care au acelasi membru stang si nu esxis
ta doua grupuri cu acelasi membru stang.Fiecare grup Fi produce o schema
FN3.Algoritmul realizeaza o descompunere ce conserva dependentele.
Vom ilustra algoritmul pe un exemplu.Fie A1.A2,…,Am o multime de atribute
Si fie E o multime de dependente functionale f1,f2,fn de forma fi:xi->yj,unde
Xi=Ai1,Ai2,Aik si Yj=Aj1,Aj2,…,Aj

9.4 Operaţii specifice prelucrării bazelor de date (creare,


adăugare, modificare, ştergere,
sortare, căutare, vizualizare, interogare)
1.1 MODELUL RELATIONAL AL DATELOR

Modelul relational al datelor a fost acceptat aproape fara rezerve de atat specialistii din domeniu bazelor
de date cat si de utilizatori ,inca de la aparitia primului articol al lui Codd E. F. [1] , prin care erau puse
bazele acestui model asamblist al datelor a fost lansata de catre Childs D.F. in 1968 ,care a subliniat
faptul ca orice structura de date poate fi reprezentata printr-una sau mai multe tabele de date , in cadrul
carora este necesar sa existe informatii de legatura , in vederea stabilirii unor legaturi intre acestea.
S-a constatat ca, prin utilizarea sistemelor relationale este posibila atingerea unor obiective importante
ale organizarii datelor in comparatie cu modelele ierarhice si retea [2]:
1. Asigurare unui grad sporit de independenta a programelor de aplicatie fata de modul de
reprezentare interna a datelor si metodele de acces la date.In precizarea prelucrarilor asupra
datelor ,programele nu fac apel la pointeri sau alte elemente ale schemei interne a bazei de date .
2. Furnizarea unor metode si tehnici eficiente de control a coerentei si redundantei
datelor .Modelul relational ,prin tehnica normalizarii relatiilor permite definirea unei structuri conceptuale
optime a datelor , prin care se minimizeaza riscurile de eroare la actualizare, reducandu-se redundanta
datelor.
3. Oferirea unor facilitati multiple de definire si manipulare a datelor.In primul rand modelul
relational ofera posibilitatea utilizarii unor limbaje procedurale ,bazate pe algebra relationala ,precum si
a unor limbaje neprocedurale ce au la baza calculul relational.

138
4. Ameliorarea integritatii si confidentialitatii datelor.Modelul relational realizeaza acest lucru prin
mecanisme flexibile si eficace de specificare si utilizare a restrictiilor de integritate si a relatiilor virtuale.
Componentele modelului relational sunt: structura relationala a datelor, prin care datele sunt organizate
sub forma unor tablouri bidimensionale (tabele ) de date , numite relatii, operatorii modelului relational ,
ce definesc operatiile care se pot efectua asupra relatiilor ,in scopul realizarii functiilor de prelucrare
asupra bazei de date ,respectiv consultarea ,inserarea,modificarea si stergerea datelor ,precum si
restrictiilede integritate care permit definirea starilor coerente ale bazei de date.
1.1.1 SRUCTURA RELATIONALA A DATELOR

Prezentarea sructurii relationale a datelor impune definirea notiunilor de domeniu , atribut , relatie si
schema a unei relatii [6].
In figura 2.2.1 se prezinta un model relational ce corespunde unei multimi concrete de caracteristici
despre lumea reala .Orarul de zbor al avioanelor poseda o sructura de date relationala .Pentru fiecare
linie aeriana din orarul de zbor sunt date caracteristicile :numarul cursei, aeroportul de decolare,
aeroportul de aterizare, ora decolarii, ora aterizarii.
Fiecare avion este determinat de multimea valorilor de fiecare linie.Trebuie sa ne limitam numai la
actele date care pot sa apara in definirea coloanei.Coloana cu numele ,Punct de decolare(PD) contine
numele aeroporturilor liniilor aeriene considerate.Coloana Ora decolarii (OD) (respectiv, Ora aterizarii
(OA))exprima ora la care are loc decolarea (respectiv , aterizarea).Coloana cu numele Punct de
aterizare (PA) contine numele aeroportului unde se aterizeaza.
Nr zbor(nr) Punct de Punct de aterizare(pa) Ora de decolare(Od) Ora de aterizare(oa)
decolare(Pd)
70 Bucuresti Craiova 16:59 17:50
75 Craiova Bucuresti 07:25 08:25
80 Bucuresti Timisoara 17:30 19:30
85 Timisoara Bucuresti 07:15 09:25
90 Timisoara Craiova 10:15 13:20
Definitia 2.2.1 Domeniul reprezinta o multime de valori ,caracterizat printr-un nume si este definit fie
explicit prin enumerarea tuturor componentelor sale,fie printr-o proprietate distinctiva a valorilor din
domeniul respectiv.
Penrtu tabelul din figura 2.2.1 se pot da urmatoarele exemple:
D1={Bucuresti,Craiova,Timisoara}
D2={x / xєN , xє[1,100]}
Atributul reprezinta coloana unei tabele de date , caracterizata printr-un nume. Numele coloanei
(atributului ) exprima de obicei semnificatia valorilor din cadrul coloanei respective .Fiecarui nume de
atribut ii corespunde un domeniu Di numit domeniu numit domeniul atributului Ai ,1in si se va nota cu
dom(Ai) .Pt a diferentia coloanele care contin valori ale aceluiasi domeniu si a elimina astfel dependenta
de pozitie in cadrul tabelei , se asociaza fiecarei coloane un nume distinct.
Pentru tabelul din figura 2.2.1 avem atributele NR,PD,PA,OD,OA si domeniile asociate dom(NR),
dom(PD), dom (PA), dom (OD),dom (OA).
De exemplu , dom (PD) ={Bucuresti ,Craiova,Timisoara}.
Fie D1 , D2 , …,Dn domenii finite , nu neaparat disjuncte.Produsul cartezian D1xD2x…xDn al
acestora este definit de multimea tuplurilor <v1,v2,…, vn> unde v1єD1,v2єD2,…,vn єDn. Numarul n
defineste aritatea tuplului.
Definitia 2.2.2 O relatie r pe multimile D1,D2,…,Dn este o submultime a produsului cartezian D1x
D2 x … Dn , deci o multime de tupluri.
Exista si un alt mod de a defini o relatie, si anume , ca o multime finita de functii. Asociem fiecarui
domeniu Di un atribut Ai si definim relatia r ca fiind o multime de tupluri {t1,t2,… ,tn} , unde ti : {A1, A2,
… ,An} - D1 D2 … Dn si ti (A j) єDj pentru orice valori ale lui i si j .Intr-o relatie , tuplurile trebuie
sa fie distincte (nu se admit duplicari ale tuplurilor). De obicei ,vom nota relatia cu r sau r{A1,A2, … , An}
.
Orarul din figura 2.2.1 reprezinta un exemplu de relatie pe care o vom numi orar.Continutul
informational al liniei nu depinde de ordinea coloanelor , de exemplu coloanele PS si PA pot fi
interschimbate.
Definirea unei relatii ca o multime de tupluri sau ca o multime de functii se refera la multimi care
variaza in timp (se adauga , se sterg, sau se modifica elemente).Pentru a caracteriza o relatie este
nevoie de un element invariant in timp , iar acest invariant este dat de structura relatiei (schema relatiei).

139
Definitia 2.2.3 Multimea tuturor atributelor R={A 1, A2 , … , An}corespunzatoare unei relatii o
numim schema relatiei si o notam r(A1 , A2 , … , An) .
Schema relatiei orar se defineste astfel: orar (NR,PD,PA,OD,OA).
Schema unei relatii mai este cunoscuta si sub numele de intensia unei relatii , ca expresie a
proprietetilor comune si invariante ale tuplurilor care compun relatia .Spre deosebire de intensie ,
extensia unei relatii reprezinta multimea tuplurilor care compun la un moment relatia , multime care este
variabila in timp . De obicei , extensia unei relatii este stocata fizic in spatiul asociat bazei de date , caz
in care relatia se numeste relatie de baza .Exista situatii in care extensia nu este memorata in baza de
date . Este cazul asa numitelor relatii virtuale , cunoscute si sub numele de relatii derivate sau viziuni.
Acestea sunt definite implicit , pe baza altor relatii , prin intrmediul unei expresii relationale iar stabilirea
tuplurilor care o compun se face prin evaluarea expresiei.
Asadar , putem reprezenta o relatie printr-un tabel bidimensional in care fiecare linie corespunde
unui tuplu si fiecare coloana corespunde unui domenui din produsul cartezian. Numarul atributelor
defineste gradul relatiei , iar numarul de tupluri cardinalitatea relatiei .
Fiecare linie a relatiei este o multime de valori , cate una pentru fiecare nume de atribut .Linia
relatiei se numeste tuplu. In figura 2.2.1 relatia orar este formata din 5 tupluri . Unul dintre acestea ,
notat cu t , este definit astfel:
t(NR)=75 , t(PD) = Craiova , t(PA)=Bucuresti,t(OD)=7.25, t(OA)=8.25
Valoarea concreta a tuplului t pentru atributul A o numim Avaloarea tuplului t , iar daca t este
considerata ca functie , atunci Avaloarea tuplului o vom nota cu t(a). Pentru X R, restrictia tuplului t
la X o notam cu t/X sau t(X) si o vom numi Xvaloarea tuplului t .
Pentru relatia orar , consideram un tuplu t oarecare , de exemplu primul tuplu din relatie . {PD ,
PA} – valoarea tuplului t este tuplul t’ pentru care t’(PD)=Bucuresti, t’(PA)= Craiova.
Asupra tuplurilor unei relarii se pot efectua urmatoarele operatii:
Adaugarea. Permite adaugarea de noi tupluri la o relatie .
Astfel , pentru relatia r{A1 , A2 , … , An} operatia are forma :
ADD(r: A1= d1 , A2 = d2 , … ,An = dn)
De exemplu , adaugarea unui tuplu la relatia orar se face astfel:
ADD(orar : NR =99, PD =Oradea , PA = Bucuresti , OD = 20 , OA = 22)
Cand ordinea atributelor este fixata aceasta poate fi scrisa sub forma :
ADD(orar : 99, Oradea , Bucuresti, 20 , 22)
Scopul operatiei de adaugare este de a adauga un tuplu la o anumita relatie r ,dar rezultatul
adaugarii nu este conform cu scopul acesteia in urmatoarele cazuri:
tuplul de adaugat nu corespunde schemei relatiei;
anumite valori ale tuplului nu apartin domenuilui respectiv ;
tuplul de adaugat coincide dupa cheie (vezi 2.2.1.3) cu tuplul din relatie .
De exemplu , adaugarea in relatia orar , a tuplului :
ADD (orar: NR :90 , PD :Iasi , PA : Sibiu , PD :16 , PA :12)
nu e permisa , deoarece nu respecta prima conditie .
2. Stergerea. Aceasta operatie se introduce pentru a elimina tupluri din relatie . Pentru o relatie r ,
operatia are forma :
DEL(r :A1 =d1 , A2 =d2 , … , An =dn)
Atunci cand numele atributelor sunt ordonate , se pot scrie mai simplu :
DEL( r : d1 , d2 , … , dn)
De exemplu , pentru relatia orar , stergerea primului tuplu , se realizeaza astfel:
DEL(orar : 70 , Bucuresti , Craiova , 16:59 , 17:50)
Deoarece , intr-o relatie , tuplurile sunt identifcate unic prin valoarea unei chei (vezi 2.2.1.3) , este
suficient pentru a realiza stergerea , sa definim numai valoarea cheii .
Daca K= {B1 , B2 , … , Bn} este o cheie , atunci se poate utiliza urmatoarea forma directa:
DEL ( r : B1 = c1 , B2 =c2 , … , Bn = cn )
De exemplu , varianta scurta a operatiei de strgere din relatia orar este :
DEL (orar : 70)
Daca tuplul ce doreste a fi sters , nu exista in relatia r atunci se genereaza o eroare .
3.Modificarea . Se refera la faptul ca anumite valori dintr-un tuplu se pot modifica .
Pentru o relatie oarecare r si pentru submultimea {c1 , c2 , … , cp} {A1 , A2 , … , An} , operatia de
modificare are forma:
CH (r : A1 =d1 , A2 =d2 , … , An =dn ; C1 = c1 , … , Cp = cp)
Daca K ={B1 , … , Bn } este o cheie , atunci operatia de modificare se poate scrie :
CH( r : B1 = d1 ,…, Bm = dm ; C1 = c1 ,…, Cp = cp)
Pentru relatia orar , operatia de modificare a primului tuplu are forma :

140
CH(orar : NR = 70 , PD = Bucuresti , PA = Craiova , OD = 16:59 , OA = 17:50 , OD =
18 , OA = 19) sau utilizand numai cheia operatiei :
CH (orar : NR = 70 , OD = 18 , OA = 19)

1.1.2. OPERATORII MODELULUI RELATIONAL


Modelul relational ofera doua colectii de operatori pe relatii , si anume : algebra relationala (AR) si
calcul relational (CR). E.F. Codd a introdus algebra relationala (AR) ca o colectie de operatii pe relatii ,
fiecare operatie avand drept operanzi una sau mai multe relatii si avand ca rezultat o relatie .
Unele operatii ale AR pot fi definite prin intermediul altor operatii . In acest sens , putem vorbi de
operatii de baza , precum : reuniunea , diferenta , produsul cartezian , etc. dar si de operatii derivate :
intersectia , diviziunea , etc.
Ulterior , la operatiile standard au fost adaugate si alte operatii , numite extensii ale AR standard,
precum : complementarea , splitarea (spargerea), inchiderea tranzitiva , etc.
In general , operatiile AR pot fi grupate in:
- operatii traditionale pe multimi (reuniunea , intersectia , diferenta , produsul cartezian );
- operatii relationale speciale (selectia , protectia , join-ul , etc.)
In continuare vom prezenta principalele operatii ale AR , precum si modul lor de utilizare.
1.Reunuinea. Este o operatie definita pe doua relatii r si s cu aceeasi schema R si consta in
construirea unei noi relatii q , cu aceeasi schema R si avand drept extensie tuplurile din r si s luate
impreuna o singura data .
Noutaiile uzuale pentru aceasta operatie sunt : r  s, OR (r,s), UNION(r,s).
Considerand tuplurile ca transformari , avem urmatoarea definitie formala a reuniunii:
r s ={t / t є r}{t / t є s}
Exemplul 2.2.1 Fie orar 1 si orar 2 doua relatii cu aceeasi schema R(NR, PD, PA, OD,OA).
orar 1
NR PD PA OD OA

75 Craiova Bucuresti 07:15 08:25


80 Bucuresti Timisoara 17:30 19:30
85 Timisoara Bucuresti 07:15 09:25
90 Timisoara Craiova 10:15 13:20

orar 2
NR PD PA OD OA

75 Craiova Bucuresti 07:15 08:25

80 Bucuresti Timisoara 17:30 19 :30

95 Timisoara Arad 11:15 11:25


96 Timisoara Oradea 12:15 13:20

Prin operatia de reuniune a celor doua se obtine un nou orar :


(orar1 orar 2)
NR PD PA OD OA

75 Craiova Bucuresti 07:15 08:25

80 Bucuresti Timisoara 17:30 19:30


85 Timisoara Bucuresti 07:15 09:25
90 Timisoara Craiova 10:15 13:20

95 Timisoara Arad 11:15 11:25


96 Timisoara Oradea 12:15 13:20

141
2.Diferenta . Reprezinta o operatie definita pe doua relatii r si s cu aceeasi schema R, si consta in
construirea unei noi relatii q , cu aceeasi schema R si avand drept extensie tuplurile din r care nu se
regasesc in s .
Notatiile uzuale pentru aceasta operatie sunt : r-s , REMOVE (r,s), MINUS(r,s)
Considerand tuplurile ca transformari , avem urmatoarea definitie formala a diferentei :
r-s ={t / t є r }-{t / t є s}
Diferenta relatiilor orar1 si orar 2 din exemplul 2.2.1 ne conduce la urmatoarea relatie:
NR PD PA OD OA
85 Timisoara Bucuresti 07:15 09:25
90 Timisoara Craiova 10:15 13:20

3. Intersectia . Reprezinta o operatie definita pe doua relatii r si s cu aceeasi schema R , si consta


in construirea unei noi relatii q , cu aceeasi schema R si avand drept extensie tuplurile comune din r si s
.

Notatiile uzuale pentru aceasta operatie sunt :


, INTERSECT(r,s), AND(r,s).
Intersectia realtiilor orar 1 si orar 2 din exemlul 2.2.1 , ne conduce la relatia:
NR PD PA OD OA
75 Craiova Bucuresti 07:15 08:25
80 Bucuresti Timisoara 17:30 19:30

Intersectia reprezinta o operatie derivata , care poate fi exprimata prin intermadiul diferentei astfel: r 
s= r – (r -s) sau rs= s – (s- r).
4.Produs cartezian . Reprezinta o operatie definita pe doua relatii r si s de schema R ,respectiv S ,
si consta in construirea unei noi relatii q , a carei schema Q , se obtine din concatenarea schemelor
relatiilor r si s iar extensia lui q se obtine din toate combinatiile tuplurilor din r cu cele din s.
Notatiile uzuale pentru aceasta operatie sunt : r x s, PRODUCT(r,s) , TIMES(r,s).
Considerand tuplurile ca transformari , avem urmatoarea definitie formala a produsului cartezian :
r x s = {t / (t1 є r)(t2 є s ) (t[R]=t1) (t[S]=t2)}
Fie pilot o relatie cu urmatoarela extensie :
pilot
NUME VARSTA
Popa 35

Vigu 40

Produsul cartezian al relatiei orar 1 din exemplul 2.2.1. si pilot , ne conduce la urmatoarea relatie:
NR PD PA OD OA NUME VARSTA

75 Craiova Bucuresti 07:15 08:25 Popa 35


80 Bucuresti Timisoara 17:30 19:30 Popa 35
85 Timisoara Bucuresti 07:15 09:25 Popa 35
90 Timisoara Craiova 10:15 13:20 Popa 35
75 Craiova Bucuresti 07:25 08:25 Vigu 40

80 Bucuresti Timisoara 17:30 19:30 Vigu 40


85 Timisoara Bucuresti 07:15 09:25 Vigu 40
90 Timisoara Craiova 10:15 13:20 Vigu 40

142
5. Selectia. Reprezinta o operatie definita asupra unei relatii r , si consta in construirea unei relatii
s , cu schema identica cu cea a relatiei r si a carei extensie este constituita din acele tupluri din r care
satisfac o conditie mentionata explicit in cadrul operatiei . Conditia este in general de forma :< atribut
operator de comparatie valoare>.

Notatiile uzuale in aceasta operatie sunt : σconditie (r) , r[conditie ] sau RESTRICT(r ,conditie ).
Considerand tuplurile ca transformari , operatorul de selectie se poate defini astefel :
σA=a (r)={t ε r / t (A)=a}
Selectia σ PD=Timisoara (orar 1 ) se aplica relatiei orar 2 din exemplul 2.2.1, ne conduce la urmatoarea
relatie:
NR PD PA OD OA

85 Timisoara Bucuresti 07:15 09:25

90 Timisoara Craiova 10:15 13:20

6.Proiectia. Reprezinta o operatie definita aupra unei relatii r si consta in construirea unei relatii s in
care se regasesc numai acele atribute din r specificate explicit in cadrul operatiei.Suprimarea unor
atribute din r poate avea ca efect aparitia unor tupluri duplicate ce vor trebui eliminate.Prin operatia de
proiectie se trece la o de la relatie de grad n la o relatie de grad m, mai mic decat cel initial.
Notatiile uzuale pt aceasta operatie sunt: Π A1 ,A2,…,Am (r), PROJECT(r, A1, A2,…,Am).
Considerand tuplurile ca transformari , operatorul de proiectie se poate defini astfel :
Πx = {t(X) / t ε r}
Aplicarea operatorului ΠPD,PA(orar 1) relatiei orar 1 din exemplul 2.2.1 ne conduce la urmatoarea
relatie:

PD PA
Craiova Bucuresti

Bucuresti Timisoara
TImisoara Bucuresti
Timisoara Craiova

7.Join(Jonctiunea sau unirea) [7] Reprezinta o operatie definita pe doua relatii r si s , operatie care
consta din construirea unei noi relatii q , prin concatenarea unor tupluri din r cu tupluri din s.Se
concateneaza acele tupluri din r si s care satisfac o anumita conditie.Extensia relatei q va contine acele
tupluri care satisfac conditia de concatenare.
Notatiile uzuale pentru aceasta operatie sunt : r ⋈ codities sau JOIN(s,r,conditie).
In general conditia de concatenare are urmatoarea forma :
<atribut din r operator de comparatie atribut s>.
In functie de operatorul de comparatie , join-ul poate fi de mai multe tipuri.Cel mai important tip ,
in sensul celei mai frecvente utilizari este echijoin-ul , care reprezinta o operatie de join, dirijata de o
conditie de forma urmatoare :<atribut din r =atribut din s>.
Definitia 2.2.4. fie relatiile r si s de schema R respectiv S, cu Ai є R si Bi є S, dom(Ai)=dom (Bi ),
i=1 ,…, m . Relatia:
q(RS)={t : tr ε s , astfel incat t(R) =tr , t(S)=ts , t(Ai)=t(Bi), i=1,…,m}
se numeste echijoin-ul relatiilor in raport cu A1=B1=…=Am=Bm si se noteaza cu r[A1=B1=…=Am=Bm]s
.
Considerand relatia oras , de forma urmatoare:
oras
PD JUDET

Timisoara Timis
Craiova Dolj
Oradea Bihor

143
Operatia orar 1⋈PD=PDoras aplicata relatiilor orar 1 din exzemplul 2.2.1 si oras definita sus, ne
conduce la urmatoarea relatie:

NR PD PA OD OA PD JUDET

75 Craiova Bucuresti 07:15 08:25 Craiova Dolj

85 Timisoara Bucuresti 07:15 09:25 Timisoara Timis

90 Timisoara Craiova 10:15 13:20 Timisoara Timis

Operatia de mai jos se poate exprima cu ajutorul operatiilor de produs cartezian si selectie ,
rezultatul unui join fiind acelas cu rezultatul unei selectii operate asupra unui produs cartezian , adica :
JOIN (r,s,conditie )=RESTRICT(PRODUCT(r,s,conditie ), conditie)
Produsul cartezian reprezinta o operatie laborioasa si foarte costisitoare , ceea ce face ca in locul
produsului sa fie utilizat join-ul ori de cate ori acest lucru este posibil.
In cazul echijoin-ului , schema relatiei rezultat , contine toate atributele celor doi operanzi si de
aceea vor exista cel putin doua valori egale in fiecare tuplu . Join-ul natural elimina aceasta redundanta
, fiind definita in mod similar cu echijoin-ul cu observatia ca atributele cu acelas nume se trec o singura
data i relatia rezultat iar extensia se compune din concatenarea tuplurilor lui r cu tuplurile lui s care
prezinta aceleas valori pentru atributele cu acelas nume . Notatia uzuala pt aceasta operatie este : r ⋈s.
Join-ul natural al relatiilor orar 1 din exemplul 2.2.1. si oras definita mai sus , ne conduce la
urmatoarea relatie:
NR PD PA OD OA JUDET
75 Craiova Bucuresti 07:15 08:25 Dolj
85 Timisoara Bucuresti 07:15 09:25 Timis
90 Timisoara Craiova 10:15 13:20 Timis

Join extern . Atunci cand relatiile care participa la join nu au proiectii identice pe atriburul de
jonctiune (atributul nu are acelaesi valori in relatiile care se jonctioneaza ), operatia de join conduce la
pierderea de tupluri , cel putin dintr-o relatie . pt a evita pierderile de informatie a fost definit join-ul
extern , ca o operatie prin care din doua relatii r si s se obtine o noua relatie q prin join-ul relatiilor s si
r , relatie la care se adauga si tuplurile din r si s care nu au participat la join .Aceste tupluri sunt
completate in relatia q cu valori “null” pt artibutele relatiei corespondente (r, respectiv s).
Notatiile uzuale pt desemnarea unei join extrem sunt :r ⋈.s sau EXT-JOIN(r,s).
Join-ul extern al relatiilor orar 1si oras conduce la urmatoarea relatie :
NR PD PA OD OA JUDET

75 Craiova Bucuresti 07:15 08:25 Dolj

80 Bucuresti Timisoara 17:30 19:30 Null


85 Timisoara Bucuresti 07:15 09:25 Timis

90 Timisoara Craiova 10:15 13:20 Timis


Null Oradea Null Null Null Bihor

Semi-join . Aceasta operatie a fost introdusa de Bernstein P.A. , fiind necesara la definirea
procesului de optimizare a interogarilor .Semi-jonctiunea conserva atributele unei singure relatii
participante la join si reprezinta o operatie pe doua relatii r si s in urma careia rezulta o noua relatie ce
contine numai tuplurile din relatia r care participa la join .Notatiile uzuale pt aceasta operatie sunt : r ⋈s
sau SEMIJOIN(r,s).
Astfel , orar1><oras conduce la urmatoarea relatie :
NR PD PA OD OA
75 Craiova Bucuresti 07:15 08:25

144
85 Timisoara Bucuresti 07:15 09:25
90 Timisoara Craiova 10:15 13:20

8.Diviziunea . Reprezinta o operatie din AR definita asupra unei relatii r de schema : R(A1:D1 ,
…,Ap: Dk, Ap+1: D1, …,An: Dm), operatie care consta din construirea , cu ajutorul unei relatii
s(Ap+1 : D1 , … , An : Dm) a relatiei q (A1 : D1 , …, Ap : Dk) . Tuplurile relatiei q , concatenate cu
tuplurile relatiei s permit obtinerea tuplurilor relatiei r .
Definitia 2.2.5 Fie r si s doua relatii de schema R respectiv S , cu S R si R’=R-S .Relatia :
r’(R’)={t :ts  s ,  tr  r astefel incat tr (S)=ts , tr (R’ )=t } se numeste diviziunea relatiei r la s .
Operatia de diviziune este o operatie derivata , care poate exprima prin intermediul diferentei ,
prudusului cartezian si proiectiei astfel :
r / s =A1,A2,…,Ap(r) - A1,A2,…,Ap((A1,A2,…,Ap(r)x s )-r)
Consideram relatiile drept si tip de forma urmatoare :
drept
Pilot Tip avion

Dan AIRBUS

Dan TU154

Ion TU154

Ion AIRBUS

Mihai TU154

tip
Tip avion

AIRBUS

TU154

Daca dorim sa obtinem pilotii care au drept de zbor pe toate tipurile de avionane, calculam drept+tip ,
si rezulta relatia :

Pilot
Dan
Ion

9. Complementarea . Complementul unei relatii reprezinta multimea tuplurilor din produsul


cartezian al domeniilor asociate atributelor relatiei , care nu figureaza in extensia relatiei
considerate .Este obligatoriu ca domeniile sa fie finite.Cardinalitatea rezultatului poate fi extrem de
mare, ceea ce face ca operatia sa fie destul de rar utilizata.
Sa consideram , de exemplu , pt relatia drept definita la operatia de diviziune , urmatoarele valori
ale domeniilor :
Pilot={Dan,Ion,Mihai,Andrei}
Tip avion={AIRBUS,TU154,IAR500}
Complementul relatiei drept este :

145
Pilot Tip avion

Dan IAR500
Ion IAR500
Mihai AIRBUS
Mihai IAR500
Andrei IAR500
Andrei AIRBUS
Andrei TU154

10.Splitarea (spargerea). Este o operatie aditionala din AR , definita asupra unei relatii r si
care, pe baza uneiconditii definite asupra atributelor lui r permite construirea a doua relatii r1 si
r2 , cu aceeasi schema cu r .Extensia lui r1 contine tuplurile din r care indeplinesc conditia
specificata , iar r2 pe cele care nu verifica aceasta conditie.
Pt relatia drept definita mai sus si conditia Pilot=”Dan”, operatia de splitare produce ca
rezultat relatiile drept 1 si drept 2:
drept 1
Pilot Tip avion

Dan AIRBUS

Dan TU154

drept2
Pilot Tip avion

Ion TU154
Ion AIRBUS

Mihai TU154

11.Inchiderea tranzitiva . Este o operatie aditionala din AR prin care se pot adauga noi
tupluri la o relatie .Operatia de inchidere tranzitiva presupune efectuarea in mod repetat a
secventei de operatii : join-protectie-reuniune. Numarul de executii depinde de continutul relatiei
. Inchiderea tranzitiva se defineste asupra unei relatii r , a carei schema contine doua atribute A1
si A2 cu acelasi domeniu , si consta in adaugarea la relatia r a tuplurilor care se obtin succesiv
prin tranzitivitate , in sensul ca , daca exista in r tuplurile <a,b> si <b,c> se va adauga la r si
tuplul <a,c>.Notatiile uzuale pt aceasta operatie sunt : (r), r, CLOSE()r.
Prezentam mai jos , o relatie legatura ce ne arata legaturile aeriene intre anumite localitati
precum si inchiderea tranzitiva a relatiei (legatura).
Legatura
PD PA
Bucuresti Iasi

Bucuresti Timisoara
Timisoara Arad
Timisoara Craiova

(legatura)
PD PA
Bucuresti Iasi

146
Bucuresti Timisoara
Timisoara Arad
Timisoara Craiova

Bucuresti Arad
Bucuresti Craiova

Crearea unei baze de date se face la fel ca in formele anterioare de fox cu CREATE
NUME_TABELA si apare ceva de forma:

Modificarea inregistrarilor se face cu BROWSE

147
Calculul unei formule economice cu conditii seface cu BROWSE

,TABLE/REPLACE FIELD
Pozitionarea pe anumite inregistrari:
Stergerea unor inregistrari care
indeplinesc anumite conditii se face cu
TABLE/DELETE RECORDS

LUCRAREA DE LABORATOR
CREAREA SI MODIFICAREA STRUCTURII FISIERELOR
Scop
Insusirea modului de lucru privind crearea si modificarea structurii fisierelor.

Studiu necesar
Lungu i.,N. Musat,M. Velicanu FoxPro 2.6. Prezentare si aplicatii Ed.All,1966

Mod de realizare a lucrarii


Comentarii detaliate privind fiecare notiune,sintaxa comenzilor si exemple.

2.1 Consideratii generale


Domeniul bazelor de date este un domeniu distinct al informaticii,operand cu
marimi si notiuni specifice.Foarte multe probleme informatice se reduc, la nivel

148
principal,la memorarea unor informatii, urmata de extragerea acestora sub diferite
forme.
Baza de date reprezinta structura logica in care este memorata o cantitate de
informatii,pe un suport fizic de memorare .La nivel inferior,baza de date reprezinta
unul sau mai multe fisiere,care respecta conditiile impuse de sistemul de operare.
Pentru a determina in mod univoc structura unui fisier trebuie specificate
campurile care compun fisierul,impreuna cu caracteristicile acestora.Fiecarui camp ii
sunt caracteristice:
-nume -identifica campul printre celelalte elemente
-tipul - stabileste prelucrarile care se pot aplica datelor memorate in campul respectiv
-lungimea -numarul de octeti ocupati de camp(adica latimea coloanei in tabel)
necesar pentru rezervarea spatiului de memorie pe disc
-zecimale -pentru campurile numerice ,stabileste pozitia punctului zecimal in cadrul
campului respectiv
Pentru manipularea unui fisier Foxpro foloseste o zona de memorie in care
memoreaza unele informatii referitoare la starea acestuia..,numita zona de
lucru.Acest SGBD poate lucra simultan cu mai multe fisiere,deci va avea mai multe
zome de lucru(25 la numar).Modul de lucru cu o baza de date este urmatorul:-se
deschide fisierul(acestuia I se atribuie o zona de lucru)
-se executa operatiile dorite asupra fisierului(adaugare inregistrari,stergere
inregistrari,etc)
-la terminarea lucrului aceasta se inchide;
La deschiderea unui fisier(intr-o zona de lucru ) acestuia I se atribuie un nume numit
alias,prin care este identificat.Aliasul poate fi furnizat de utilizator sau poate fi atribuit
automat de FOXPRO . Identificarea unei date memorate intr-un fisier se face prin
specificare inregistrarii si campului de care aceasta apartine.
Zone de lucru
Pentru identificarea zonelor de lucru se folosesc doua metode:
-primele 10 zone de lucru se identifica prin litele de la A la J ,adica primele 10 litere
din alfabet.
-pentru toate cele 25 de zone de lucru putem folosi pentru identificare numere de la 1
la 25.
La deschiderea unui fisier intr-o zona de lucru, acestei I se atribuie un nume pe care
il vom numi’alias’. Deci fisierul deschis in zona de lucru va putea fi identificat si
prin alias-ul respectiv.La un moment dat, o singura zona este curenta..Aceasta
inseamna ca o anumita comanda ,in interiorul careia nu s-a specificat explicit fisierul
la care se refera ,va actiona asupra fisierului din zona de lucru curenta .
La pornirea FOXPRO zona de lucru curenta va fi zona A sau 1.
Aceasta se poate schimba folosind comanda SELECT<expN>|<expC> unde <
expN> reprezinta numarul zonei de lucru ce va deveni curenta(activa).Daca <expN>
este 0 se va selecta prima zona de lucru neocupata (in care nu s-a deschis nici un
fisier) iar <expC> reprezinta alis-ul fisierului deschis in acea zona de lucru.
Exemplul 1
SELECT 1 && zona curenta va fi zona 1
SELECT A && echivalenta cu prima comanda
Sa presupunem ca in zona de lucru 2 avem deschis fisierul STUDENT,,pentru
selectarea acestei zone putem folosi comenzile:
SELECT 2
SELECT B
SELECT STUDENT
SELECT ‘STUDENT’

149
Pentru a afla care este zona de lucru curenta se foloseste functia SELECT( ) ,aceasta
returnand numarul zonei de lucru curenta sau numarul ultimei zone de lucru
nefolosite.Sintaxa este:SELECT([0|1])
0-functia returneaza numarul zonei de lucru curente
1-functia returneaza numarul ultimei zone de lucru nefolosite
SELECT() si SELECT(0) sunt echivalente
Exemplul 2
?SELECT ( )
1
?SELECT(1)
25
?SELECT SELECT() +1 && se selecteaza prima zona de lucru dupa cea curenta
2

Crearea unui fisier .Structura unui fisier.


In acest scop folosim CREATE cu sintaxa CREATE[<fisier>|?],unde <fisier>
reprezinta numele fisierului de baza de date ce va fi creat.Daca pentru acest fisiernu
se specifica nici o extensie,Foxpro asociaza automat extensia DBF.
Aceasta comanda permite pentru fiecare camp specificarea
numelui ,tipului ,lungimii si numarul de zecimale(numai pentru campurile de tip
numeric).Introducerea acestor informatii se face in fereastra de dialog Structure.

Structure:C:\fox\student.dbf
Name Type With Dec Field
Matricol Numeric 4 <Insert>
Nume Character 10 <Delete>
Grupa Numeric 3 <ok>
Adresa Character 10 <cancel>
Datan Date 8
Notabd Numeric 5 2
Codl Numeric 4

Fields:7 Leght :45 Available:3955

Figura 1. Fereastra de dialog Structure

Prima coloana nu poarta nici un nume.Cand cursorul se afla in aceasta coloana se pot
apasa doua taste : INSERT pentru a insera un camp nou in aceasta pozitie,DELETE
pentru a sterge campul existent in pozitia curenta.Lungimea maxima a unei
inregistrari =4000 caractere.
Deschiderea si inchiderea unui fisier

150
Deschiderea unei baze de date se realizeaza folosind comanda USE cu sintaxa:
USE [<fisier>|?]
[IN<zona de lucru>]
[AGAIN] [INDEX<lista fisiere index>|?
[ORDER [<expN>|<fisier index .idx>| [TAG] <nume eticheta>
[OF<fisier .cdx>] [ASCENDING|DESCENDING]]]]
[ALIAS<alias>] [EXCLUSIVE] [NOUPDATE]
<fisier> reprezinta fisierului bazei de date ce va fi deschis ,caruia ,daca nu I se
specifica nici o extensie ,I se va atribui implicit extensia DBF.Implicit,baza de date
specificata va fi deschisa in zona de lucru curenta.De asemenea inchiderea unei
baze de date se refera tot la aceasta zona de lucru.Pentru a ne referi la o alta zona se
foloseste clauza IN specificand prin<zona de lucru > aceasta zona.
Exemplul 3
? SELECT ( ) && afiseaza zona de lucru curenta
1
USE student && s-a deschis in zona 1
USE && s-a inchis
USE student IN 2 && s-a deschis in zona 2 chiar daca zona de lucru curenta a
&& a fost si va ramane 1
USE IN 2 && se va inchide baza din 2
In Foxpro exista posibilitatea deschiderii unei baze de date in mai multe zone de
lucru..In acest scopse foloseste clauza AGAIN.
Exemplul 4
SELECT A && se selecteaza zona de lucru 1
USE student
USE student IN 2 AGAIN && se deschide si-n zona 2
USE IN 2 && se inchid bazele
USE
Observatie : Daca la deschiderea unei baze de date , in zona de lucru exista anterior
o alta baza de date ,cea veche este inchisa automat inainte de deschiderea celei noi.
Clauza NOUPDATE se introduce pentru a proteja fisierul la scriere .
Exemplul 5
SELECT A
USE student NOUPDATE
USE
INDEX-se refera la indexarea bazei de date
EXCLUSIVE- se refera la folosirea intr-o retea a bazei de date
ALIAS-se refera la alias-ul atribuit de utilizator bazei de date
Inchiderea bazelor de date se poate utiliza so cu comenzile CLOSE ALL si CLOSE
DETABASE.
CLOSE ALL inchide toate fisierele din toate zonele de lucru si selecteaza zona de
lucru 1.Printre aceste fisiere se afla si bazele de date care vor fi inchise cu aceasta
comanda.CLOSE DETABASE inchide toate
bazele de date si selecteaza zona de lucru 1.Pentru a obtine informatii despre zonele
de lucru ale FOXPRO si bazele de date deschise inele se vor folosi doua functii
USED( )si DBF( ).
USED( ) ne informeaza daca o zona de lucru este libera sau este ocupata de un
fisier .Sintaxa:
USED([<expN>|<expC>]) in care <expN> sau <expC> specifica zona de lucru despre
care dorim informatii(prin numarul sau prin alias-ul corespunzator).Functia returneaza
.T. daca in zona de lucru respectiva este deschis un fisier si .F. daca zona de lucru este

151
libera.Daca nu se specifica o zona de lucru , functia se refera la zona de lucru
curenta .Daca se secifica un alias, functia returneaza un alias ,functia returneaza
adevarat , daca un fisier cu acest alias este deschis intr-una din zonele de lucru
FoxPro.
Exemplul 6
SELECT A
USE student IN 4
USE student AGAIN
? USED()
.T.
?USED(2)
.F.
?USED(‘student’)
.T.
-USE
USE IN 4
Pentru a afla ce fisier este deschis intr-o anumita zona de lucru se foloseste functia
DBF().Aceasta returneaza un sir de caractere ce contine numele fisierului deschis
intr-o zona de lucru sau care are un anumit alias.
Exemplul 7
SELECT a
USE student
?DBF(‘stuent’)
C:\FPD 26\STUDENT.DBF
?DBF(‘a’)
C:\FPD 26\STUDENT .DBF
?DBF(1)
C:\FOXPRO 20\STUDENT .DBF
?DBF(2)==‘ ‘
.T.
USE

Alias-ul unei baze date


Identificarea unui fişier se face fie prin intermediul zonei de lucru în care
acesta a fost deschis, fie prin alias-ul fişierului. La deshiderea fişierului, acestuia i se
atribuie un nume, prin care se identifică, care poartă numele de alias.

Exemplul 8
SELECT student IN b ALIAS info
SELECT info
?SELECT0
2
USE IN b

Alias-ul implicit ce se atribiue unui fişier, la deschidere, de către FoxPro este numele
fişierului, fără extensie.

Exemplul 9
SELECT a
USE student IN b

152
SELECT student
?SELECT0
2
USE IN b

Manipularea structurii unei baze de date

Comanda MODIFY STRUCTURE realizează comanda structurii unui fişier


prin deschiderea unei ferestre de dialog, aceaşi ca la crearea structurii ( vezi Figura
1 ),unde se vor realiza modificările.
Vizualizarea structurii unui fişier se face cu comenzile DISPLAY
STRUCTURE sau LIST STRUCTURE. Acestea au sintaxa :
DISPLAY STRUCTURE [INexpN expC] [TO PRINTERITO FILE fisier]
[NOCONSOLE]
LIST STRUCTURE [IN expN expC ] [TO PRINTERITO FILE fisier]
[NOCONSOLE]
Deosebirea dintre ele este că prima face pauza după umplerea unui ecran cu
informaţii.
expN sau  expC specifică zona de lucru, respectiv fişierul, la care se referea
comanda. Dacă se specifică opţiunea NOCONSOLE, afişarea pe ecran este inhibată.
In paralel cu afişarea pe ecran, dacă aceasta nu este inhibată, se pot trimite aceleaşi
informaţii şi la imprimantă în cazul clauzei TO PRINTER sau şi la fişierul fisier în
cazul clauzei TO FILE. Cele două clauze TO PRINTER şi TO FILE, se exclud
reciproc. Un alt mod de a crea un fişier îl reprezintă comanda COPY STRUCTURE,
care crează un nou fişier, cu aceaşi structură (sau asemănătoare) cu a celui deschis în
zona de lucru curentă. Sintaxa este:
COPY STRUCTURE TO fisier[ FIELDS lista cîmpuri][[WITH]CDX  [WITH]
PRODUCTION] unde fisier reprezintă noul fişier. Clauza FIELDS are ca efect
copierea în noul fişier doar a câmpurilor specificate în lista de câmpuri care urmează
clauzei.

Exemplul 10

SELECT a
USE student
COPY STRUCTURE TO studenti.dfb FIELDS matricol, nume, grupă
USE studenti
LIST STRUCTURE
O modalitate de transmitere a unei structuri a bazei de date, şi anume printr-o
bază de date intermediară, în care se încarcă srtuctura de copiat. Comanda folosită
este COPY STRUCTURE EXTENDED cu următoarea sintaxă:
COPY TO fisier STRUCTURE EXTENDED
Stuctura bazei de date se copiază în înregistrările unei noi baze de date, fisier, care
are o srtuctură fixă, formată din patru câmpuri.

NR. FIELD_NAME FIELD_TYPE FIELD_LEN FIELD_C


( nume câmp ) ( tip câmp ) ( lăţime câmp ) (zecimale câmp )
1 Matricol N 4 0
2 Nume C 10 -

153
3 Grupa N 3 0
4 Adresa C 10
5 Datan D - -
6 Notbad N 5 2
7 Codl N - -

Câmpurile sturcturii devin înregistrări în zona de bază de date. Conţinutul


acestor înregistrări se poate modifica, se pot şterge, se pot adăuga înregistrări,
modificându-se astfel structura codificată în această bază de date. Trecerea inversă,
din înregistrările bazei de date în structura unei noi baze de date, se face cu comanda
CREATE FROM ce are următoarea sintaxă:
CREATE [fisier1] FROM [fisier2]
fisier2 este o bază de date ce memorează în înregistrările sale o structură, în modul
descris la comanda anterioară. Acest fişier s-a creat anterior, fie cu o comandă COPY
STRUCTURE EXTENDED, fie manual.
fisier1 este o bază de date ce se va crea şi va avea structura codificată în fişier
fisier2 . Noua bază de date va deveni activă.

Manipularea câmpurilor unei baze de date

Accesul la câmpurile unei baze de date este controlat de comanda SET FIELDS, care
are sintaxa:
SET FIELDS ON  OFF
SET FIELDS TO [[ câmp1 [câmp2…]]  ALL ]
câmp1 ,câmp2… reprezintă lista câmpurilor ce pot fi accesate în cazul SET
FIELDS ON.

Exemplul 11
SET FIELDS ON
SET FIELDS TO nume, grupa
Iar pentru a reveni la normal se introduce fie SET FIELDS TO ALL fie SET FIELDS
OFF.

Numărul câmpurilor dintr-o bază de date este returnat de funcţia FCOUNT () ce are
următoarea suntaxă:
FCOUNT ([ expN   expC]), expN - zona de lucru în care este deschis fişierul
la care se referă funcţia;
 expC - alias-ul fişierului respectiv.

Exemplul 12
CLOSE ALL
USE student
?’Fişierul are’,FCOUNT(),’câmpuri’
?FCOUNT()=FCOUNT(1)
.T.
?FCOUNT(1)=FCOUNT(‘student’)
.T.
?FCOUNT(2)
0
USE

154
Funcţia FIELD () returnează numele unui câmp dintr-un fişier identificat prin
numărul câmpului în cadrul structurii bazei. Funcţia are următoarea sintaxă:
FIELD ( expN1 [, expN2 expC]) în care expN1 specifică numărul de
ordine al câmpului ( primul câmp are numărul de ordine 1 al doilea 2 s.a.m.d.), iar
expN2 sau expC identifică baza de date la care se referă funcţia, prin zona de
lucru în cazul specificăriiexpN sau prin alias-ul bazei de date ( când se specifică
 expC ).
Exemplul 13
CLOSE ALL
USE student
?FIELD(1)
matricol
USE student IN 2 AGAIN
?FIELD(1,2)
matricol, nume
?FIELD(7)= ‘’
.T.
?FIELD(FCOUNT())
adresa
CLOSE ALL

Funcţia FSIZE ()returnează mărimea unui câmp al unui fişier. Sintaxa este:
FSIZE ( expC1 [, expN   expC2 ]) rezultatul fiind numeric.  expC1 este un
şie de caractere ce reprezintă numele câmpului, iar prin  expN sau  expC2  se
specifică zona de lucru, respectiv fişierul la care se referă funcţia.
Exemplul 14

CLOSE ALL
USE student
?’structura fişierului :’,DBF()
?’câmp’,’nume’,’lăţime’
TOTAL=0
FOR I=1 to FCOUNT()
?I,FIELD(1),TYPE(),FSIZE(FIELD(I))
TOTAL=TOTAL+FSIZE(FIELD(I))
ENDFOR
?’**Total**’,TOTAL+1
USE

Domeniul înregistrărilor
Există comenzi în FoxPro care acţionează asupra mai multor înregistrări ale
unui fişier. Selectarea acestora se face specificând în comandă condiţia de selectare,
cu ajutorul căreia, din mulţimea totală a înregistrărilor se aleg doar acelea care
respectă condiţia respectivă. Mulţimea înregistrărilor selectate formează “domeniul
înregistrărilor” la care se referă comanda. Domeniul înregistrărilor se specifică prin
clauzele  domeniu  ,FOR, WHILE incluse opţional în comanda respectivă. Clauza
 domeniu  se va înlocui cu una din următoarele construcţii, în funcţie de necesităţi:
ALL selectează toate înregistrările din baza de date
NEXT exp N  se referă la următorele  exp N  înregistrări, începând de la
înregistrarea curentă inclusiv.

155
RECORD  exp N  acţionează numai asupra înregistrării cu numărul  exp N 
REST selectează înregistrările începând de la cea curentă, inclusiv, şi până la sfârşitul
fişierului.
Clauza FOR se foloseşte pentru selectarea înregistrărilor în funcţie de o condiţie
logică  exp L . Se selectează acele înregistrări pentru care  exp L  este
adevărată. Clauza WHILE ( cât timp) cu sintaxa WHILE  exp L  - este
asmănătoare clauzei FOR. Spre deosebire de clauza FOR, după găsirea unei
înregistrări ce nu respectă condiţia  exp L  , continuă testarea celorlalte, clauza
WHILE întrerupe testarea înregistrărilor când găseşte o înregistratre ce nu respectă
condiţia dată.Dacă se specifică ambele clauze FOR şi WHILE, prima care contează
este clauza WHILE. Folosind clauza FOR viteza de preluare creşte foarte mult, de
aceea se recomandă folosirea acesteia, oricând este posibil.

LUCRAREA DE LABORATOR

ÎNTREŢINEREA INFORMAŢIILOR DIN FIŞIERE

Scop
Însuşirea modalităţilor de adăugare, modificare, ştergere şi vizualizare a
informaţiiolor dintr-un fişier. Utilizarea indicatorului de înregistrări, filtrarea şi
căutarea informaţiilor.

Studiu necesar
Lungu I., N. Muşat, M. Velicanu FoxPro2.6. Prezentare şi aplicaţii. Ed. All,
Bucureşti, 1996.

Mod de realizare a lucrării


Comentarii detaliate privind fiecare noţiune, sintaxa comenzilor şi exemple.

Adăugarea de înregistrări

Adăugarea de înregistrări se poate face în două moduri, în funcţie de poziţia pe


care o va ocupa noua înregistrare în fişier :
- adăugarea de înregistrări noi la sfîrşitul bazei de date ;
- intoducerea de înregistrări noi în interiorul bazei de date ;
Prima metodă se realizează cu comenzile APPEND, APPEND FROM.
- la comanda APPEND informaţiile sunt furnizate de utilizator, în mod interactiv
(excepţie făcând clauza BLANK). Sintaxa : APPEND [BLANK]
- comanda APPEND FROM se foloseşte când informaţiile sunt luate dint-un fişier.
Pentru a edita un câmp de tip memo, când cursorul se află în câmpul respectiv, se
apasă combinaţia de taste CTRL + Home. Ieşirea cu salvare din această fereastră se
face cu CTRL+W. (ESC nu salvează modificările). Terminarea introducerii tuturor
înregistrărilor se realizează apăsând simultan tastele CTRLşi END., fereastra de
editare închizându-se după aceasta.
Intoducerea datelor în fereastra de editare corespuzătoare comenzii APPEND este
influenţată de comanda SET CARRY. Acastă comandă permite sau inhibă copierea
conţinutului înregistrării curente în noua înregistare creată cu APPEND sau
INSERT.SINTAXA :
SET CARRY ON OFF
SET CARRY TO [ listă câmpuri [ADDITIVE]]

156
Clauza ON determină copierea îregistrării curente în cea nouă pe când clauza OFF
opreşte aceasstă copiere. Opţiunea implicită este OFF. Cea de-a doua formă a
comenzii se foloseşte când se doreşte copiera numai a anumitor câmpuri ale
înreigstrării curente în noua înregistrare, aceste câmpuri fiind specificate în lista de
câmpuri listă câmpuri. Dacă se include în comandă şi opţiunea ADDITIVE, la
vechea listă de câmpuri, are ca efect întoarcerea la lista implicită, în care sunt
specificate toate câmpurile. Prima formă a comenzii SET CARRY ON  OFF se
referă doar la zona de lucru pe când cea de-a doua formă, SET CARRY TO, se referă
la zona de lucru curentă.
Eemplul 1
Să presupunem că introducem informaţii într-un fişier în care unul din câmpuri este
data curentă. În cadrul unei zile, această dată nu se schimbă, iar introducerea în
fiecare înregistrare a datei curente este ineficientă, De aceea se recomandă copierea
automată a datei curente pentru fiecare nouă înregistare ce se adaugă. Aceasta se
realizează cu secvenţa de comenzi :
SET CARRY ON
SET CARRY TO data_intr
Iar la sfîrşitul zilei se introduce secvenţa de comenzi :
SET CARRY TO
SET CARRY OFF
pentru anularea acestei stări (inhibarea copierii datei de la o inregistrare la alta).
Comanda APPEND BLANK are ca efect adăugarea unei noi înregistrări “ blank”
(goală) la sfîrşitul bazei, urmând ca informaţia utilă să se încarce mai târziu, prin alte
comenzi FoxPro.
Adăugarea de înregistrări la sfîrşitul bazei active se poate realiza cu comanda
APPEND FROM. Înregistrările ce se vor adăugabazei de date active vor fi preluate
din fişierul fişier.
APPEND FROM fişier ?
[FIELDS listă câmpuri]
[FOR expL]
[TYPE] [DELIMITED [WITH TAB  WITH delimitator  WITH
BLANK]
[DIP  FWZ  MOD  PDOX  RPD  SDP  SYLK  WK1  WK3  WKS 
WR1  WRK  XLS]
fişier reprezintă numele fişierului din care se preiau înregistrările ce se vor adăuga
la fişier.
Dacă nu se specifică numele fişierului, trebuie specificată clauza ?, utilizatorului
oferindu-i-se astfel posibilitatea selectării fişierului printr-o fereastră de dialog. Dacă
se doreşte ca din fişier fişier să se preia doar anumite câmpuri, se va include clauza
FIELD. Dacă nu se specifcă asfel, întreg fişierul va fi adăugat la sfârşitul bazei de
date. Pentru a prelua din fişier doar anumie înregistrări, se va specifica domeiul
acestora, prin clauza FOR. Se foloseşte clauza TYPE pentru a specifica tipul acestui
fişier.
Exemplul 2
CLOSE ALL
USE student
APPEND FROM studenti FIELDS nume, grupa FOR codl = 1100
LIST
USE

157
Transferul invers de la o bază de date la un alt fişier de pe disc se realizează cu
comanda COPY TO cu următoarea sintaxă :
COPY TO fişier[FIELDS listă câmpuri]
[domeniu][FOR expL1][WHILEexpL2]
[[WITH]CDX]  [[WITH] PRODUCTION]
[NOOPTIMIZE]
[TYPE][FOXPLUS  DIF  MOD  SDF  SYLK  WK1  WKS  WR1  WRK 
XLS  DELIMITED [WITH delimitator  WITH BLANK  WITH TAB]]
Comanda copiază înregistrări din baza de date activă într-un fişier nou, cu numele
fişier. Acestuia dacă nu se specifică o extensie, i se va atribui automat
extensia .DBF. În cazul în care nu se specifică alt tip, fişierul nou creat va fi o bază de
date FoxPro în care se copiază înregistrări din baza de date activă.
Ce de-a doua metodă de adăugare a unei înregistrări noi la un fişier o
reprezintă inserarea înregistrării în interiorul bazei de date folosind comanda
INSERT.
Fie Ik înregistrarea curentă.
Înregistrarea I se introduce între Ik şi Ik+1. Comanda INSERT are următoarea sintaxă :
INSERT [BEFORE][BLANK]
Şi are ca efect înscrierea unei înregistrări noi, după înregistrarea curentă. Dacă se
specifcă clauza APPEND, completarea câmpurilor este influenţată de SET CARRY.
Clauza BEFORE determină adăugarea unei înregistrări noi înaintea înregistrării
curente.
Exemplul 3
USE student
GOTO 2
INSERT BEFORE
USE

Modificarea conţinutului înregistrărilor

Modificarea informaţiilor stocate într-un fişier se realizează cu comenzile BROWSE,


EDIT, CHANGE, REPLACE.
Sintaxa comenzii BROWSE :
BROWSE
[FIELDS listă cîmpuri ] [FOR expL ] [FORMAT]
[FREEZEcâmp] [KEYexpr1[,expr2]] [LAST]
[LEDIT]][REDIT] [LOCKexpN1] [LPARTITION]
[NOAPPEND][NOCLEAR][NODELETE]
[NOEDIT NOMOIFY] [NOLGRID][NORGRID]
[NOLINK][NOMENU][NOOPTIMIZE]
[NOREFRESH][NORMAL][NOWAIT]
[PARTITIONexpN1] [PREFERENCEexpC1]
[REST][SAVE] [TIMEOUTexpN3] [TITLEexpC2]
[VALID][:F] expL2[ERRORexpC3]][WHENexpL3]
[WIDTHexpN4] [WINDOWnume fereastră 1 ]
[IN[WINDOWnume fereastră 2  IN SCREEN]]
[COLOR[listă perechi culori]  COLOR SCHEME expN5]

158
Lista de câmpuri de la clauza FIELDS reprezintă o înşiruire de câmpuri, ale unei baze
de date sau calculate,separate prin virgulă, ce se vor edita, având următoarea sintaxă :
câmp [:R] [:V=expr1[:F][:E=expC1]] [:P=expC2]
[:B=expr2,expr3[:F]] [:H=expC3]
[:W=expL1] [,câmp2[:R]…]
Câmpurile calculate reprezintă câmpuri din fereastra de editare, create prin evaluarea
unei expresii şi afişate în fereastra respectivă ca un câmp de sine stătător. Aceste
câmpuri se pot vizualiza, dar nu se pot modifica. Sintxa de definiţie a unui câmp
calculat este :
nume câmp calculat=expr
exemplul 4
Având fişierul student.dbf, vom deschide o fereastră de editare în care vom
afişa doar câmpurile nume, vârstă, codl. Primul şi ultimul sunt cîmpuri ale bazei de
date, vârsta fiind un câmp calculat în funcţie de data naşterii (câmpul născut din fişier)
şi data curentă.
CLOSE ALL
USE student
BROWSE FIELDS nume vârstă=(date()-datan)/365,codl
USE

În sintaxă există posibilitatea ataşării fiecărui câmp a uneia sau mai multor
opţiuni :
:R -câmpul se poate vizualiza, nu şi modifica
:V=expr1 -permite validarea câmpului introdus. După ce câmpul s-a modificat şi
se iese din editarea acestuia, se evaluează expr1. Dacă expr1 este evaluată la .T.
data introdusă în câmp este corectă, iar dacă este evaluată la .F. data se consideră
incorectă, aflându-se un mesaj de eroare. În cazul când expresia este de tip numeric,
iar valoarea ei este 0, data introdusă în câmp este incorectă, afişându-se un mesaj de
eroare.
exemplul 5
USE student
BROWSE FIELDS nume:R,codl:V=codl=1100 AND codl =2000:F:E= ‘codl

:F - pentru a forţa evaluarea expresiei expr1 şi deci validarea,chiar


atunci când se trece cu cursorul prin câmp fără modificarea acestuia
:E=expC1 - se foloseşte pentru ca mesajul afişat în caz de eroare să fie altul decât
cel implicit şi anume expC1
:B=expr2,expr3 - se foloseşte pentru a specifica intervalul în care trebiue să se
afle câmpul după editări. expr2 reprezintă limita infeioară iar expr3 reprezintă
limita superioară. Aceste două expresii trebuie să fie de acelaşi tip cu câmpul editat.
În cazul când valoarea câmpului nu se încadrează între cele două expresii, se afişează
un mesaj de eroare.
:P=expC2 - se poate folosi un cod PICTURE
:H=expC3 -numele câmpului ce se afişează la partea superioară a ferestrei de
editare va fi înlocuit cu expC3
:W=expL1 - se permite intrarea în editarea câmpului doar dacă expresia logică
expL1 este evaluată la valoarea .T.

159
Modificarea conţinutului unei baze de date se poate face şi cu comanda
REPLACE care, spre deosebire de cea anterioară nu deschide o fereastră ci realizează
propriu-zis actualizarea bazei de date cu datele precizate prin comandă. Sintaxa este :
REPLACE
câmp1WITHexpr1[additive]
[,câmp2WITHexpr2[additive]…]
[domeniu][FORexpL1][WHILEexpL2]
[NOOPTIMIZE]
Comanda înlocuieşte vechea valoare din câmpul câmp1 cu valoarea
rezultată în urma evaluării expresiei expr1, vechea valoare din câmpul câmp2 cu
valoarea expresiei expr2 şi aşa mai departe. Pentru câmpuri numerice, dacă nu se
reuşeşte încadrarea valorii expresiei în câmpul respectiv, acesta va fi umplut cu
asteriscuri. Pentru câmpuri memo, specificând clauza ADDITIVE, acestea nu sunt
înlocuite, expresia fiind adăugată la sfârşitul lor. domeniu, FOR şi WHILE
specifică domeniul înregistrărilor la care se referă comanda REPLACE, domeniul
implicit fiind înregistrarea curentă.
Exemplu 6
USE student
Append blank
REPLACE nume WITH ‘Toma’
REPLACE codl WITH 1100
REPLACE ALL grpa WITH 231

Comanda CHANGE are sintaxa :


CHANGE
[FIELDS field list][scope][FORexpL1]
[WHILE expL2][FREEZEfield ][ KEYexpr1[,expr2]]
[LAST][LEDIT][REDIT][LPARTITION][NOAPPEND][NOCLEAR]
[NODELETE][NOEDIT][NOMODIFZ][NOLINK]
[NOMENU][NOOPTIMIZE][NORMAL] [NOWAIT] [PARTITIONexpN1]
[PREFERENCE expC1][REST][SAVE][TIMEOUTexpN2]
[TITLEexpC2][VALID[F:] expL3[ERRORexpC3]]
[WHENexpL4] [WIDTHexpN3][[WINDOWwindow name 1]
[IN[WINDOWwindow name 2  IN SCREEN]]
[COLOR SCHEME expN4]  COLORcolor pair list]

CHANGE permite editarea BD curent selectate în interiorul unei ferestre. Această


comandă este de asemenea disponibilă din interiorul ferestrei Browse. Puteţi salva
toate schimbările făcute şi părăsi fereastra de editare Change prin apăsarea Ctrl+W
sau Ctrl+End.
Comanda EDIT funcţionează identic cu comanda CHANGE.

Ştergerea înregistrărilor

Ştergerea unei înregistrări dintr-un fişier se poate realiza la două nivele şi anume :
- la nivel logic când înregistrarea nu este propriu-zis ştearsă din fişier ci ea este
marcată într-un anumit mod (‘marcată pentru ştergere’) indicând astfel această
stare a înregistrării.

160
- la nivel fizic când înregistrarea este ştearsă, efectiv din fişier, ea neputând fi în
nici un fel accesată sau refăcută. Marcarea pentru ştergere a uneia sau mai multor
înregistrări se face cu ajutorul comenzii DELETE:
DELETE [domeniu ][FOR expL1 ][WHILE expL2 ][NOOPTIMIZE]
domeniu ,FOR,WHILE identifică înregistrările ce vor fi marcate pentru
ştergere. Domeniul implicit al comenzii DELETE este înregistrarea curentă. Accesul
la înregistrările marcate pentru ştergere este controlat de comanda SET DELETED :
SET DELETED ON  OFF
Când se alege opţiunea ON, înregistrările marcate pentru ştergere nu vor fi accesibile
celorlalte comenzi care folosesc domeniul înregistrărilor (domeniu , FOR,WHILE )
iar când este aleasă opţiunea OFF, înregistrările sunt accesibile indiferent de marcajul
de ştergere.
Starea iniţială este OFF. Comenzile care acţionează asupra unei singure înregistrări
sau care au ca domeniul implicit înregistrarea curentă nu sunt afectate de această
comandă.
Exemplul 7
USE student
DELETE FOR MOD(RECNO(),2=0
SET DELETED OFF
LIST FOR DELETED()=.F.
USE
Acest exemplu este echivalent cu:

USE student
DELETE FOR MOD(RECNO(),2=0
SET DELETED ON
LIST
USE
În interiorul unui program testatrea marcajullui de ştergere a unei ănregistrări se face
cu funcţia DELETED (). Aceasta returnează valoarea logică adevărat, dacă
înregistrarea curentă este marcată pentru ştergere, altfel funcţia returnează fals.
O înregistrare marcată pentru ştergere nu este ştearsă fizic din fişier. Eliminînd
marcajul de ştergere, înregistrarea este refăcută, ea redevenind accesibilă pentru toate
comenzile, înlăturarea marcajului de ştergere se realizează cu comanda RECALL ce
are aceaşi sintaxă cu comanda DELETE.
Exemplul 8
USE student
DELETE FOR MOD(RECNO(),3<=0
LIST
RECALL ALL
LIST
USE
Pentru ştergerea la nivel fizic se foloseşte comanda PACK cu următoarea sintaxă :
PACK [MEMO][DBF]
Comanda realizează ştergerea fizică a tuturor înregistrărilor marcate pentru ştergere
din fişier. După aplicarea comenzii PACK înregistrările sunt şterse definitiv. Dacă o
bază date conţine un câmp de tip memo, informaţiile conţinute în acest câmp sunt
depozitate într-un fişier asociat bazei de date (cu acelaşi nume dar cu extensie FTP).
Clauza MEMO a comenzii PACK are ca efect eliminarea spaţiului nefolosit
din fişierul MEMO asociat, fără a afecta fişierul bazei de date propriu-zis. Clauza
DBF se foloseşte pentru a şterge fizic înregistrările marcate pentru ştergere din fişier,

161
fără a modifica fişierul MEMO asociat. Comanda PACK fără nici o clauză se referă
atât la fişierul bazei de date cât şi la fişierul MEMO asociat.
Exemplu 9
USE student
DELETE RECORD 5
PACK
LIST
USE
Comanda ZAP şterge fizic toate înregistrările din fişier activ fiind echivalentă cu
secvenţa de instrucţiuni:
DELETE ALL
PACK
Comanda ZAP este mult mai rapidă decât secvenţa anterioară de instrucţiuni.
Înregistrările şterse cu ZAP nu mai pot fi refăcute.
Înainte de execuţia comenzii dacă opţiunea SET SAFETY este ON se va mai afişa un
mesaj de confirmare a ştergerii înregistrărilor.

Accesul la înregistrări

Spre deosebire de ştergerea fizică a unei înregistrări, această metodă nu


elimină fizic această înregistrare, ci doar blochează accesul la ea. Această metodă de
control a accesului este dată de comanda SET FILTER ce are următoarea sintaxă :
SET FILTER TO[ expL]
Ca efect al comenzii în fişier vor apăera doar înregitrările care îndeplinesc condiţia
expL. SET FILTER TO fără condiţie, face ca toate înregistrările din fişier să poate
fi accesate.
Exemplul 10
USE stuent
LIST
SET FILTER TO codl=1100. && se elimină înregistrările cu cod <>1100(nu fizic)
LIST
USE
Pentru a afla condiţia de accesare a înregitrărilor (expresia filtru) se foloseşte funcţia
FILTER cu următoarea sintaxă :
FILTER(expN  expC> )
Unde expN respectiv expC> specifică fişierul la care se referă funcţia, prin alias-
ul acesteia, respectiv prin zona de lucru în care a fost deschisă. Rezultatul este tip şir
de caractere reprezentînd expresia filtru folosită la accesarea înregistrărilor şi stabilită
cu comanda SET FILTER.
Exemplul 11
CLOSE ALL
SELECT 1
USE stdent
SELECT 2
USE student AGAIN
SET FILTER TO codl=1100
LIST
? FILTER() &&codl=1100
SELECT 1
SET FILTER TO codl>1100
LIST

162
? FILTER() &&codl>1100
CLOSE ALL

Vizualizarea conţinutului unei baze de date

Afişarea informaţiilor se poate face pe ecran, la imprimantă sau la un fişier de pe disc


folosind comenzile LIST şi DISPLAY. Sintaxa celor două comenzi este identică şi are
forma :
DISPLAY/LIST
[[FIELDS] listă câmpuri ]
[ domeniu ][FOR expL1 ][ WHILEexpL2 ]
[OFF] [TO PRINTER  TO FILE fişier ]
[NOCONSOLE] [NOOPTIMIZE]
Clauza FIELDS se foloseşte cu scopul de a afişa doar câmpurile specificate în listă
câmpuri în ordinea apariţiei lor în această listă. Absenţa acestei cauze determină
afişarea tuturor câmpurilor bazei de date. Câmpurile memo vor fi afişate numai dacă
sunt explicit specificate în lista de câmpuri ale clauzei FIELDS. domeniu, FOR,
WHILE determină domeniul înregistrărilor ce vor fi afişate cu comanda DISPLAY.
Dacă aceste clauze lipsesc se va afişa doar înregistrarea curentă, acesta fiind domeniul
implicit al înregistrărilor pentru comanda DISPLAY.
Exemplul 12
USE stuent
DISPLAY ALL FOR codl=1100.
USE
Prezenţa clauzei OFF determină dispariţia din formatul de afişare a coloanei ()
reprezentând numărul de ordine al înregistrărilor din fişier. Pentru inhibarea afişării pe
ecranul monitorului se foloseşte clauza NOCONSOLE.
Exemplul 13
USE student
DISP ALL OF NOCONSOLE TO PRINTER
USE
Exemplul 13
USE student
DISP ALL TO FILE listare.text

Comanda LIST este asemănătoare cu DISPLAY cu următoarele diferenţe :


- domeniul implicit pentru DISPLAY este NEXT 1 (adică înregistrarea curentă) pe
când cel al comenzii LIST este ALL (toate înregistrările)
- comanda DISPLAY afişează ecran cu ecran
- comanda LIST nu afişează înregistrprile marcate pentru ştergere când avem SET
DELETED ON.
Formatul de afişare conţine pe prima linie un antet reprezentând denumirile
câmpurilor afişate. Pentru ca acest antet să nu apară în formatul de afişare se
foloseşte comanda set handing on  off unde ON determină afişarea antetului iar
OFF determină inhibarea afişării antetului. Opţiunea implicită este ON.
Exemplu 14
USE student
SET HEADING ON
LIST
SET HEADING OFF

163
LIST
USE
Indicatorul de înregistrări

Aflarea înregistrării curente dintr-un fişier, deci a conţinutului indicatorului de


înregistrări se face cu RECNO () care are sintaxa : RECNO ([ expN  expC ])
Această funcţie returnează un reultat numeric reprezentând numărul înregistrării
curente din fişier cu alias-ul expC sau deschisă în zona de lucru expN. Dacă
ambele expresii lipsesc funcţia se referă la fişier activ.
Exemplu 15
USE student
?RECNO()
1
LIST NEXT 2
?RECNO()
2
USE
Schimbarea înregistrării curente se realizează cu comenzile GOTO, SKIP. Comanda
GO sau GOTO poziţionează indicatorul de înregistrări pe o anumită înregistrare.
GO  GOTO [RECORD] expN1[INexpN2  expC]
GO  GOTO TOP  BOTTOM [INexpN2  expC]
Prima formă are ca efect poziţionarea indicatorului de înregistrări din fişier cu alias-
ul expC sau din zona de lucru expN2 pe înregistrarea cu numărul expN1.
Absenţa clauzei IN determină revenirea la fişier activ.
Clauza TOP - se poziţionează pe prima înregistare
BOTTOM - se poziţionează pe ultima înregistare
Exemplu 16
USE student
GOTO 2
?RECNO()
2
GO RECORD RECNO() + 1
DISPLAY NEXT 1
GO TOP
?RECNO()1
GO BOTTOM
?RECNO()
4
USE
Următoarele instrucţiuni sunt echivalente :
GO 1
GO RECORD 1
GO TOP IN SELECT()
GOTO 1
GO TOP
Comanda SKIP mută indicatorul peste un număr de înregistrări relativ la înregistrarea
curentă. Sintaxa este :
SKIP[expN1][expN2  expC]
În care expN1 este numărul de înregistrări peste care se sare. Poate fi şi negativ.

164
Dacă se sare peste ultima înregistrare, indicatorul de înregistrări va conţine numărul
de înregistrări +1, iar funţia EOF () va returna .T. . în cazl saltului înaintea primei
înregistrări, funcţia BOF () va returna .T. .
expN2  expC specifică fişier prin zona în care este deschisă sau prin alias-ul
corespunzător.
Comanda SKIP este echivalentă cu SKIP 1.
Exemplul 17
USE student
1
SKIP 2
DISP RECO RECNO()
SKIP-1
?RECNO()2
Următoarele comenzi sunt echivalente :
SKIP
SKIP 1
SKIP IN SELECT()
GOTO RECORD RECNO()+1
Pentru a insera o înregistrare blank pe poziţia a 2-a şi a 4-a a bazei de date se foloseşte
următoarea secvenţă de instrucţiuni:
USE agenda
GOTO 2
INSERT BLANK BEFORE
SKIP 2
INSERT BLANK BEFORE
USE
Funcţiile BOF() şi EOF() având sintaxele:
BOF()([expN  expC])
EOF()([expN  expC])
Testează dacă indicatorul de înregistrări se află la începutul, respectiv la sfârşitul
bazei de date active, sau a celeii specificate ca parametru. Rezultatul este de tip logic
(.T. dacă condiţia este îndeplinită şi .F. în caz contrar). Numărul de înregistrări este
returnat de funcţia RECCOUNT () cu sintaxa :
RECCOUNT([expN  expC])
Dimensiunea unei înregistrări se obţine folosind funcţia RECSIZE () cu sintaxa :
RECSIZE([expN  expC])
Dacă nu se specifică alt fişier ultimile duoă funcţii se referă la fişier activ.

Căutarea înregistrărilor într-un fişier

Găsirea unei înregistrări care respectă o condiţie dată se rezolvă cu comanda


LOCATE cu următoarea sintaxă :
LOCATE FOR expL1 [ domeniu ][WHILE expL2][NOOPTIMIZE]
Comanda caută prima înregistrare care respestă condiţia expL1 în fişier activ.
Domeniul înregistrărilor care se testează este dat de clauzele domeniu şi WHILE,
domeniu implicit fiind ALL. În caz de reuşită, adică la găsirea unei înregistrări care
respectă condiţia expL1, indicatorul de înregistrări se va poziţiona pe înregistrarea
respectivă, funcţia FOUND() va returna .T. iar funţia EOF() va returna .F.. În caz
contrar indicatorul de înregistrări va fi poziţionat după ultima înregistrare (numărul
total de înregistrări +1), FOUND() va returna .F. iar EOF() va returna .T.. Într-un

165
fişier pot exista mai multe înregistrări ce respectă o condiţie dată. Prima dintre acestea
va fi găsită de comanda LOCATE. Următoarele vor fi găsite folosind comanda
CONTINUE. Testarea reuşitei sau nereuşitei căutării se face ca la comanda LOCATE
cu funcţiile RECNO(), FOUND(),EOF().
Funcţia FOUND() cu sintaxa:
FOUND ([expN  expC])
Este folosită pentru testarea rezultatului unei căutări într-un fişier, returnând valoarea
adevărată în cazul unei căutări cu succes şi fals în caz contrar. expN şi expC
identifică fişierul la care se referă funcţia (zona de lucru sau alias-ul)
Exemplul 18
CLOSE ALL
USE student
LOCATE FOR grupa=231
?FOUND()
.T.
=EOF()
.F.
?RECNO()
1
CONTINUE
?FOUND()
.T.
?EOF()
.F.
?RECNO()
3
USE
Un alt tip de căutare într-un fişier este realizat cu funcţia LOOKUP (). Aceasta caută
într-un fişier prima apariţie a unei expresii date. În caz de reuşită indicatorul de
înregistrări se poziţionează pe înregistrarea pe care a fost găsită expresia, funcţia
returnând un anumit câmp al înregistrării respective. În caz de nereuşită indicatorul de
înregistrări se poziţionează după ultima înregistrare a bazei de date iar funcţia va
returna şirul vid. Sintaxa acestei funcţii este următoarea:
LOOKUP ( câmp1 , expr , câmp2 [, expC ])
în care câmp1 reprezintă câmpul a cărui valore va fi returnată de funcţie, în caz de
căutare reuşită. expr specifică expresia de căutat în fişier, câmp2 se foloseşte
pentru a realiza căutarea expresiei numai în acest cîmp ; expC se foloseşte pentru
baze de câmp indexate. Rezultatul este de tip şir de caractere, numeric,logic sau data
calendaristică, în funcţie de tipul de câmp returnat.
Exemplul 19
CLOSE ALL
LIST student
? LOOKUP (nume,231,grupă)
?RECNO()
2
USE
INDEXAREA TABELELOR

In prealabil baza de date care o sortez trebuie deschisa iar baza de date sortata
trebuie si ea deschiosa si sortata .

166
SORT ON< campul dupa care se sorteaza >[A/C/D]
TO<nume tabela sortata> FOR< conditie de sortare >

SORT TO<nume tabela sortata> ON <nume camp >


FIELDS<lista campuri >|FIELDS LIKE<conditie>
|FIELDS EXCEPT<conditie complementara>]

INDEX ON <campul dupa care se indexeaza >TO <fisierul simplu index ce se creaza
>|TAG <cheia principala daca am mai multe campuri de indexat>[ OF <fisierul de
unde iau campurile de indexare >][ FOR L<conditie de indexare >][COMPACT]
[ASCENDING][DESCENDING] [ADDITIVE]

Transformarea in sir de caractere a campurilor se face asa : STR <camp


numeric>,DTOS<camp dat>
Deschiderea fisierelor index simple se poate face o data cu baza de date initiala iar
cele compuse separat astfel :
USE<baza de date sursa >INDEX <fisierele index>
USE<baza de date sursa >TAG<fisierele index>
SET INDEX TO [<fisierele index ce se deschid |?][ORDER< numarul fisierului
index care se deschide primul>][OF< numele fisierului index compus>]
[ASCENDING|DESCENDING][ADDITIVE]
SET ORDER TO TAG < cheia ce se deschide >
In cazul alterarii informatiilor cu operatii diverse avem REINDEX.
Gasirea inregistrarilor se face asa:{GO [RECORD]<numarul inregistrarii>[IN<unde
caut>]
{GO TOP/GO BOTTOM [IN <unde caut>]
{SKIP<+-urca sau coboara cu atatea inregistrari >IN<unde>
{LOCATE FOR <conditie de localizare >[domeniu][WHILE<pana cand>]iae la
bazele de date indexate astfel:{SEEK<valoare pe care ma pozitionez din campul
indexat>{FIND <sirul de caractere pe care-l caut din campul indexat >
{SET FILTER TO <conditie de filtrare>}
INTEROGARI

Comanda SELECT
Proiectarea vizuala a interogarilor simple si incrucisate
Fisiere View
Query Designer

Sub numele de interogare sau cerere sunt referite acele solicitari de date in mod direct
fara indicarea de obtinere.
O cerere SQL se poate lansa din fereastra de comenzi sau din interiorul unui program
FoxPro pentru ca ea functioneaza ca orice alta comanda dar se poate proiecta intr-un mod
interactiv cu ajutorul utilitarului Query Designer.
Definirea interogarilor prin comanda SELECT
Comanda SELECT -SQL permite specificarea datelor care vor constitui iesirea din
interogare precum si sursa acestora . Cum se vor obtine aceste date ramane in sarcina
optimizatoruluide cereri Rushmore
Clauza ALL/DISTINCT determina prelucrarea tuturor inregistrarilor (ALL) sau
numai a articolelor unice (DISTINCT).
Clauza <col1>[AS <nume 1>]…permite definirea coloanelor care vor constitui iesirea din
interogare . Coloanele pot fi campuri apartinand tabelelor definite in clauza

167
FROM ,constante ,expresii,functii utilizatori .Coloanele pot primi un alt nume prin clauza
AS .
Pot fi utilizate functii cum sunt:
AVG(<exp>) calculeaza media aritmetica COUT(<art selectat>) numara selectiile,SUM (<art
-selectat>) calaculeaza suma,MIN(<art-selectat>),MAX(<art -selectat) determina extremul.
Clauza FROM specifica listalista fisierelor de intrare in prelucrare.
Destinatia rezultatelor se specifica prin dour clause:INTO/TO dintre care INTO este
prioritara.Clauza INTO <det_into> determina forma de stocare a datelor.<Dest_into> poate
fi:ARRAY <tablou>/CURSOR<fis>/DBF<fis.dbf>.Forma de stocare cursor este o tabela
temporara ,de tip “READ ONLY”,stearsa automat in momentul inchiderii ei.Clauza TO
<dest_to>se foloseste atunci cand lipseste clauza INTO.<Dest_into> poate fi :TO FILE
<>fis.txt>[ADDITIVE]/TO PRINTER [PROMPT]/TO SCREEN unde TO FILE
directioaneaza iesirea catra un fisier catre un fisier ASCII (fie prin suprascriere ,implicit,fie
prin adugarea datelor la vechiul contin daca este prezenta cluza ADDTIVE),TO PRIN catre
imprimanta,iar TO SCREEN catre ecran.
Exemplu:
1. Afisati elevii claselor la imptimanta. Select cls,nume from elevi to print
2. Copiati elevii intr-o alta baza da date. select cod,nume from elevi into dfb
manelevi.dbf
Clauza WHERE <cond> permite introducerea legaturilor intre tabele si a filtrelor .Conditiile
<cond> sugereaza sistemului FoxPro sa includa anumite inregistrari in rezultatele cererii.
Exemple:
Care sunt elevii cu medii intre 8si 10 din clasa select nume,med from elevi
A “12A”. where med between 8 and 10 and cls =”12A”
Care sunt elevii cu media 10 precum si numele select elevi.nume,elevi.cls,
Dirigintilor lor .Care sunt elevii dirigintelui X?clase.diriginte from elevi,clase
Where elevi.cls=clase.cls and elevi.med=10
Accept ‘nume professor diriginte?; to x
Select elevi .nume,elevi.med from elevi,
Clase where clase.cls=elevi.cls;
And clase.diriginte=x

Clauza GROUP BY <lista_camp> permite gruparea rezultatelor dupq lista de campuri


Clauza HAVING <cond> permite introducerea unor restrictii de afisare a grupului
Cluza ORDER BY <Mexp-ordo> “ASC/DESC” permite specificarea expresiei de ordonare ca
si sensul ordonarii.

Proiectarea vizuala a interogarilor


O interogare este o maodalitate de combinare adatelor provenind din mai multe surse
care sa serveasca la realizarea rapoartelor ,formularelor.Aceste date doar se vad nu se pot
modifica.Sunt mai multe tipuri de interogari:
Simple sau unidimensionale
Incrucisate sau bidimensionale
Tridimensionale
a.Proiectarea interogarilor cu Query Designer
Queriy Designer , numit generatorul de interogari , reprezinta o interfata pentru realizarea
interactivaa cererilor Select SQL.
Desi pentru intrebuintarea sa Queri Designer cere sa fim oarecum familiarizati cu modul de
lucru FOX, nu este nevoie sa cunoastem limbajul SQL. Acest utilitar poate fi chiar o
modalitate de a invata limbajul SQL fiindca prin butonul SEE SQL se poate vedea
instructiunea SELECT generata conform proiectului din ecranul utilitarului. Aplicatia este o
facilitate deosebita oferita utilizatorilor de a-si organiza direct mediul de lucru, de a indica
legaturile dintre fisiere, indecsii, ca si campurile sau expresiile dorite ca rezultat al cererii. Dar
-nu putem folosi QUERY DESIGN in aplicatiile executabile direct.
-sistemul trebuie sa faca fata la o supraincarcare considerabila a memoriei .

168
-trebuie lucrat direct cu numele de baze de date, campuri; nu dispune de nici un dictionar de
date.
Crearea unui fisier de cereri se face interactiv prin deschiderea ecranului de
proiectare QUERY DESIGN din meniul File-New-Query sau prin comanda
CREATE/MODIFY QUERY . Se va crea un fisier cu extensia(.qpr) pe care il vom numi fisier
de cereri si care va putea fi executat tot prin comanda DO (fis qpr) .
Pasul1 vom apela generatorul de interogari prin FILE -NEW-QUERY-NEW sau prin
comanda Create Query.
Se deschide o fereastra de proiectare cu mai multe parti si un meniu .
Meniul Query
Meniul contextual se deschide, asa cum stim , prin butonul drept al mouse-ului si contine
cateva actiuni legate de Query cum ar fi: executie(run), adaugarea unei tabele(add table),
stergerea unei tabele (remove table) , vizualizearea comenzi Select(view SQL), deschiderea
ferestrei cu butoane pentru alegrerea destinatiei Query(output setting)
Pasul 2. In fereastra de proiectare a interogarii vom deschide tabelele . Tabelele, incluse sau
nu intr-o baza de date , trebuie deschise pe rand in aceasta fereastra folosind fie meniul
contextual fie meniul principal Qyery.
Deci vom deschide fisierele Contracte si Facturi. Pentru ca legatura dintre ele era
definite la nivelul bazei de date observam conservarea ei. Legatura este Contracte-Facturi de
tip 1-n
Atentie-Daca dorim sa afisam structura sau datele dintr-un fisier deja trecut in fereastra de
proiectare , vom plasa cursorul pe titlul tabelei in meniul View aparand optiunea Browse care,
asa cum stim , asociaza si meniul Table folosit pentru modificare\ indexare\filtrare.
Pasul 3.Vom fixa coloanele rezultat ale cererii in tab-ul Fields prin mutarea campului selectat
din fereastra Available Fields sau a expresiei \ functiei construite cu generatorul de expresii in
fereastra Functions , in fereastra Select fields.
Pentru ca in dorim sa se afiseze nr. De facturi (gruparea pe contracte o vom defini
mai tarziu ) vom alege una dintre functiile numerice : COUNT ( facturi . nr_fact.) . Pentru
valoarea contractului vom defini expresia contracre. can+ contracte . prêt_promis. Pentru
facturata putem scrie SUM (facturi , cant+facturi . prêt) AS val-facturata atribuind un nume
coloanei.
In general pentru grupuri se pot folosi functiile urmatoare:
COUNT() -numara inregistrarilegrupului.
SUM(…) - insumeaza valorile pentru toate inregistrarile grupului.
AVG(…) - calculeaza media valorilor articolelor din grup.
MIN(…) - extrage valoarea minima a expresiei din grup .ul query-clue se face prin caseta
Number f
MAX(…) - extrage valoarea maxima din grup .
COUNT(DISTINCT) - numara aparitiile grupului .
SUM (DISTINCT) - insumeaza valorile pentru articolele distincte etc.
Pasul 4. Vom fixa conditia de legatura prin tab-ul Join.
Tipuri de legaturi:
INNER JOIN-numai articole commune care satisfac crtiteriul
LEFT OUTER JOIN-toate inregistrarile din tabela din stanga si cele care satisfac
criteriul din drapta
RIGHT OUTER JOIN-toate articolele dindreapta reklatiei si numai care satisfac
criteriul din tabela din stanga
FULL JOIN -toate articoleledin ambele tabele
Pasul 5.Vom fixa conditia de filtrare prin tab-ul Filter.
Pasul 6.Vom fixa campurile de ordonare prin tabul Order.
Pasul 7.Vom specifica grupul prin Group By.Calculele se fac prin
functiile:AVG,COUNT ,MAX,MIN,SUM.
Pasul 8. Vom fixa alte conditii ale interogarii prin tabul Miscellaneous
No duplicates
Cross tabulate

169
Stabilirea unui numar sau procent de vizualizare din rezultatul query-lui se face prin caseta
Number of records sau comutatorul Percent.Pasul 8.vom vizualiza comanda SELECT
generata de Query Designer fie prin meniul principal sau contextual fie prin butonul de pe
toolbar cu caleasi nume view sql.pasul
Pasul 9.Vom allege destinatia finala a rezulatatelor interogarii prin meniul principal ,prin
toolbar sau din meniul contextual.
Ecranul |Query destination permitre alegerea dintre:
a) browse-afisare in fereastra browse
b) cursor-afiasre intr-o tabela temporara
c) table/dbf-nformatiile sunt scrise intr-o tabela
d) garph-reprezentari grafice
e) screen-datele sunt afisate pe ecran
f) report-afisrea sub forma de raport
g) label-afiasrea sub forma unei etichete
Pasul 10.vom verifica modul de construire prin butonul run observand rezulatele din fereastra
browse
Pasul 11. Vom salva si vom inchide generatorul query designer
Pasul 12.vom lansa in executie prin comanda DO fis.qpr.
b. Proiectarea rapida a interogarilor cu Query Wisard
pentru proiecterea rapida a interogarilor dispunem de asistentul Query wisrd apela t din
Tools-wisard-query.In fereastra de dialog deschisa vom allege query wizard
Pasul 1. selectarea campurilor care vor forma iesirea dorita din interogare .
Pasul 2.Daca sunt mai multe tebele se cere specificarea relatiei.
Pasul 4.Se fixeaza campurile de ordonare.
Pasul 5. Se salveaza ca fisier .Qpr.
c. Poiectarea interogarilor incrucisate cu Cross Tab wizard
O incrucisare sete rezultat unei interogari speciale care permite analizarea relatiei
dintre un camp al tabelei de date si alt camp al aceluias table.
Proiecatrea fisierelor View
Spre deosebire de interogari vederile ,perspectivele sau imaginile sunt fisiere care se
pot modifica si transmit aceste corectii tabeleor sursa din care sunt create.Pespectivele sunt de
dour tipuri:locale sau la distanta
a. Proiectarea fisierelor vedere prin View Designer
Apelul utilitarului pentru crearea unui view sw face fie direct prin meniul system file -New-
View fie prin tastarea comenzii CREATE VIEW in fereastra de comenzi
Trebiue stiut ca :
Un camp cheie nu pote fi modificat
Se pot modiifca doar campurile marcate pentru aceasta operatie
Schimbarea setarii initiale a indicatorilor asociatia cooaneleor view-ului se face prin
pozitioanrea pe numele campului si selectarea comutatorului corespunzator
comutatorul Send SQL Updates care trebiue activat pentru a se putea folosi view-ul la
actaulizarea datelor din surse
partea dreapta a ferestrei update se foloseste pentru view0uri la distanta si o vom
discuta la lectia uarmatoare.
B.Proiectarea rapida a vederilor cu Local View Wizard
Pentru localizarea rapida a unei vederi se poate folosi asistentul Lacl View wizard
prin Tools-wizard -Query-local wiev.Utilitarul parcurge de fapt aceleasietape ce si vrajitorul
pentru interogari insa in loc sa salveze rezultatul intr-un fisier de interogare il salveaza in
definitia unei vederi in baza de date deschisa .Asistentul realizeaza de fapt o vedere care nu
este actualizabila.
Proiectarea interogarilor cu exteriorul aplicatiei
Accesarea datelor situate le distanta ,View Designer ,Remote View Wizard
Publicarea datelor pe internet ;Web Publishing Wizard
Proiectarea documentelor pentru E-mail
Prooiectarea fisierelor perspectiva cu date situate la distanta

170
Pasi:
1. Stabilirea unei conexiuni la distanta cu alta baza de date ,se realizeaza astfel:se
deschide aplicatia Control Panel si se selecteaza pictograma ODBC pentru a vedea ce surse de
date sunt disponibile
2. se deschide FoxPro.
3. se deschide o baza de date
4. se apeleaza File-New-Connectivity
5. se apeleaza generatorul de vederi prin File-New-remote view-new
6. se adauga tabelele necesare din baza de date
7. se dauga criteriile de selectie prin tab-ul join
8. se filtreaza ,se stabileste ordinea ,gruparea ,criteriile de catualizare la fel ca si in cazul
unei vederi locale
9. se precizeaza conditiile de acceptare a actalizarilor prin update criteri
Por exista anumite conflicte de cataulizrea tinand cont ca in conditiile existentei mai multor
utilizatori acceasi tabela poate fi solicitata la atualizare simultan de la mai multe
statii.Clauzele SQL WHERE ne ajuta in aceasta privinta:
 key fields only-se efectueaza actualizarile atata vreme cat campul cheie al tablei sursa
nu s-a modificat
 key and uptable fields-interzice atualizarea atunci cand oricare dintre campurile
marcate pentru actualizare si-a schimbat valoarea in tabela de la distanta
 key and modified fields- interzice actualizarea daca pentru un camp a carui valoare s-
a modificat local valoarea acestuia secshimbase si in tabela sursa
 key and timestamp-interzice atualizarea daca valoarea cheii sau a amrcii temporare a
fosta modificata in tabela initiala

Proiectarea rapida a vederilor cu Remote View Wizard


Pentru realizarea unei vederi cu surse de date diferite de cele ale lui Visual Fox
sepoate folosi si instrumentul Remote View Wizard care desfasoara aceleasi ferestre de dialog
ca si local view wizard cu exceptia primului pas cand se indica legatura cu sursa externa
Proiectarea paginilor web pentru vizualizarea datelor pe internet
Vom folosi utilitarul webpublishing wizard apelat din meniul tools-wizards-webpublishing
Pasul1 se seklecteaza baza de date sau tabela ale carei informatiii se pot vizualiza pe internet
Pasul 2.Se precizeaza ordinea de afisare a datelor prin indicarea a maxim 3 campuri de sortare
si a sensuui operatiei
Pasul 3. se seteaza caracteristicile de design ale paginii web
Pasul 4 Se salveaza documentul.
Proiectarea paginilor de cautare pe internet
Pasul 1. Se selecteaza tabela sau baza de date in care se vor cauta datele
Pasul 2.Se precizeaza indexul dupa care se face cautarea pasul 3>se introduc textele pentru
titlul paginii
Pasul 4.Se introduce o imagine de fundal si o imagine de anteta paginii
Pasul 5.Se precizeaza imaginile de fundal si antet pentru pagina rezultat al cautarii .
Pasul 6.se selecteaza campurile care se vor include in pagina de rezultate nr max=5
Proiectarea de documente si transmiterea lor prin e-mail .Utilitarul mail merge wizard
Pasul 1.Vom selecta campurile din tabela Agenda:numele si adresa de e-mail
Pasul2.Vom indica procesorul de texte pentru editarea scrisorii
Pasul 3.Vom selecta optiunea de creare adocumentului
Pasul 4 Vom allege form letter ca tip de document
Afisarea datelor sub forma de rapoarte
rapoarte.Generatorul de rapoarte Report Designer
Etichete .Generatorul de etichete Label Designer
Grafice.Utilitarul GENGRAPH
crearea interogarilor se face cu FILE /NEW QUERY/NEW FILE:
se stabilesc tabelele si legaturile dintre ele:

171
pot sa fac grupari,filtrari de date ,functii statistice si sa anulez duplicatele sa aduc tabele:

9.5 Relaţii între baze de date


Noţiuni şi termeni tehnici uzuali
 
a. a.       O entitate este reprezentată din datele de acelaşi tip ale unui obiect
specific. Obiectele pot fi fixate în clase de obiecte numite entităţi
asociate. Un tip de entitate reprezintă o semnificaţie, pe când o
instanţă de entitate reprezintă fapte.
b. b.      Fiecare entitate este descrisă de o mulţime de proprietăţi esenţiale
numite atribute. Pentru diferitele elemente ale entităţii, atributele pot
să primească valori din anumite mulţimi numite domeniul atributului
respectiv.
c. c.       Un atribut sau o mulţime de atribute pentru care valorile asociate
determină în mod unic orice element al entităţii respective se numeşte
cheie. Orice entitate admite cel puţin o cheie, deci toate elementele
unei entităţi sunt distincte. În cazul în care există elemente care să
aibă aceleaşi valori pentru toate atributele, se ia drept cheie un atribut
suplimentar reprezentat de numărul asociat elementului în entitatea
respectivă, care defineşte în mod unic elementul.
d. d.      Numim relaţie între entităţile E1,E2,………,Ek orice submulţime a
produsului cartezian al mulţimilor elementelor celor k entităţi, adică
mulţimi de elemente de forma (e 1,e2,……...,ek), unde e1 este un element
din E1, e2 este un element din E2 ş.a.m.d. O astfel de relaţie o notăm
REL(E1,E2,……...,Ek), unde REL este numele asociat relaţiei, şi putem
spune că relaţia are arietatea k. De cele mai multe ori k=2, deci se
lucrează cu relaţii binare.
În cazul relaţiilor binare, se poate face o clasificare a lor în funcţie de
câte elemente corespund fiecărui element dintr-o entitate în cealaltă
entitate, după cum urmează:
1. 1.      relaţie unu-la-unu (notată 1:1), în cazul în care fiecărui element
din prima entitate îi corespunde cel mult un element din a doua
entitate şi reciproc;

172
2. 2.      relaţie unul-la-mai-mulţi (notată 1:N), în cazul în care fiecărui
element al primei entităţi îi pot corespunde mai multe elemente din
a doua entitate, dar fiecărui element din a doua entitate îi
corespunde cel mult un element din prima entitate.
3. 3.      relaţie mai-mulţi-la-mai-mulţi (notată M:N), în cazul în care
fiecărui element al primei entităţi îi pot corespunde mai multe
elemente din a doua entitate şi reciproc.
e. e.       Informaţiile privind structura unei vederi sunt sintetizate grafic
într-o diagramă entitate-relaţie, care pune în evidenţă entităţile ce
intervin, reprezentate prin dreptunghiuri, atributele asociate lor
reprezentate prin elipse, şi diferite relaţii ce se stabilesc între entităţi
reprezentate prin săgeţi (cu vârf dublu către entitatea pe care pot
apărea mai multe elemente în relaţie cu un element din cealaltă
entitate).

RELATII INTRE FISIERE BAZE DE DATE


Posibilitatea de a stabili relatii este una dintre facilitatile care confera putere FOXPRO-ului.O relatie
este o legatura intre doua fisiere deschise,bazata pe o referinta comuna cum ar fi un camp sau numarul
de articole.Se creaza relatii pentru a conecta temporar articole din diferite baze de date,ceea ce permite
accesul simultan la informatiile continute de acestea.
Sunt valabile consideratiile prezentate la instructiunea SET RELATION.
Cand se stabileste o relatie,nu conteaza daca baza de date parinte este indexata sau nu.In schimb
baza de date fiu trebuie sa fie indexata daca nu doriti sa se faca prin numarul de articole.

a. Relatia printr-un camp comun


Cand baza de date fiu este indexata,expresia de legatura pe care-o creati trebuie sa fie de
aceasi forma,tip si lungime cu expresia chei de indexare a bazei de date fiu.FOXPRO evalueaza
expresia de legatura pentru articolul curent din baza de date parinte si apoi cauta articolul
corespunzator(cu aceeasi valoare a chei de indexare) din baza de date fiu.

b. Relatia prin numar de articol


Cand baza de date fiu nu este indexata,expresia de legatura pe care o creati trebuie sa fie
numerica,deoarece ea va fi folosita pentru a gasi un numar de articol.Daca expresia de legatura
nu este numerica,va apare mesajul de eroare “Database is not indexed”.FOXPRO evalueaza
expresia de legatura penrtu articolul curent din baza de date parinte si apoi cauta articolul cu
numarul de ordine corespunzator in baza de date fiu.

STABILIREA RELATIILOR

Inainte de a incepe legarea bazelor de date trebuie sa va asigurati ca sunteti in forma ecran
“View” a ferestrei “View”.Toate fisierele pe care doriti sa le legati trebuie sa fie deschise in zone de lucru
distincte.
Din lista zonelor de lucru,selectati baza de date care va deveni baza de date parinte.Alegeti
butonul Relations.Numele bazei de date parinte va apare in lista Relations cu o sageata care pleaca din
el.In continuare,din lista zonelor de lucru,selectati baza de date legata.
Daca baza de date legata este indexata si are stabilit indexul principal,va fi activat
generatorul de expresii.Daca baza de date legata este ordonata dupa un camp care exista identic in
baza de date parinte,FOXPRO va introduce automat acel camp in expresia de legatura.Puteti schimba
acest camp sau puteti crea alta relatie de legatura.
Daca baza de date legata este indexata dar nu are stabilit indexul principal,va apare un
dialog Set Index Order pentru a stabili indexul principal in maniera discutata la indexare.
Daca baza de date legata nu este indexata,FOXPRO presupune ca doriti sa creati o expresie
de legatura bazata pe numarul de articole.
Cand expresia de legatura are forma dorita,alegeti optiunea <<OK>> si observati in fereastra
“View” stabilirea relatiei.
UTILIZAREA INFORMATIILOR DIN
MAI MULTE BAZE DE DATE

173
O aplicatie complexa lucreaza cu informatii multiple,aranjate in mai multe baze de date.Scopul
fragmentarii este acela de a conferi viteza de lucru,de a nu gestiona inutil,in diferite parti ale
aplicatiei,informatii care nu se prelucreaza si,nu in ultimul rand,acela de a conferi siguranta datelor
manipulate.Vulnerabilitatea datelor scade prin fractionarea lor.
Informatiile atasate unei aplicatii pot exista in mai multe baze de date,dar,in general,aceste baze
de date sunt legate pe baza unui camp comun,unic in fiecare articol.Acest camp se numeste camp
cheie si are rol esential in utilizarea informatiilor distribuite in mai multe baze de date.
FOXPRO permite utilizarea simultana a maximum 25 de baze de date.Pentru fiecare baza de
date,sistemul de gestiune rezerva o zona de lucru curenta,numerotata de la 1 la 25 (sau de la A la J si
de la 11la 25).Programatorul are acces la un moment dat numai la o singura zona de lucru;aceasta
zona de lucru se numeste “zona de lucru curenta”.Zona de lucru curenta poate fi modificata de
programator prin selectare.Vom explica cele spuse anterior printr-un exemplu.

Exemplu:
Consideram doua fisiere baza de date CLIENTI.DBF cu structura:

Cod_client N 7
Den_client C 35
Cont_banca C 15
Den_banca C 20
Cont_cec C 15
Adresa C 25
Den_loc C 20
Telefon C 12
Fox C 12
Si FACTURI.DBF cu structura

Nrf N 8
Dataf D 8
Cod_ben N 7
Val_fact N 14 2

Aceste fisiere pot fi deschise in doua zone de lucru astfel:

SELECT 1
USE CLIENTI
SELECT 2
USE FACTURI

Deci instructiunea de selectare a zonei de lucru este SELECT si poate avea urmatoarea sintaxa:

SELECT n|alias

Implicit este activa zona de lucru 1.Puteti selecta o anumita zona de lucru precizandu-i numarul prin
n.SELECT 0 are ca efect
selectarea zonei de lucru ne folosite cu cel mai mic numar de ordine.
Dupa deschiderea unei baze dedat intr-o anumita zona,acesta poate fi selectata prin aliasul
sau.Aliasul implicit al unei baze de date este numele sau (fara extensia.DBF).Se poate atribui bazei de
date un alt nume _alias decat numele implicit prin specificarea lui in comanda USE astfel:
USE…ALIAS nume_alias
Un nume_alias poate fi format din maximum 10 caractere (litere,cifre si liniuta de subliniere) si
incepe obligatoriu printr-o litera sau cu liniuta de subliniere.
Specificarea campurilor dintr-o baza de date deschisa in alta zona de lucru decat zona curenta se
face cu ajutorul numelui_alias astfel:alias.camp sau alias->camp.
Inchiderea bazelor de date deschise in diferite zone de lucru se face prin selectarea fiecarei zone
in parte si inchiderea bazei de date din zona respectiva astfel:

SELECT 1
USE

174
SELECT 2
USE

Sau utilizand comanda CLOSE ALL.


Scopul deschiderii mai multor baze de date este prelucrarea simultana a articolelor din bazele de
date deschise .Doua sau mai multe baze de date se pot lega :

1. Pe baza numarului de secventa a articolelor din bazele de date in cauza (se presupune de
regula,ca bazele de date au acelasi numar de articole);este o legatura fizica intre bazele de date;
2. Pe baza unei chei de indexare;prin acest procedeu,frecvent utilizat,se stabileste o legatura logica
intre articolele din bazele de date deschise simultan.

In ambele cazuri,sistemul gestioneaza pointeri de articol pentru fiecare zona de lucru .Pointerii se
pot sincroniza prin comanda:SET RELATION.
Formatul comenzii este:

SET RELATION TO|expr_1INTOn1|alias1


|,expr_2 INTOn2| alias2…| [additive]|

Comanda SET RELATION stabileste o relatie intre doua baze de date deschise.Inainte de a
stabili relatia,o baza de date (baza de date parinte sau principala ) trebuie deschisa in zona de lucru
curenta iar cealalta(baza de date fiu sau legata) sa fie deschisa in alta zona de lucru.
Dupa crearea relatiei, o mutare a pointerului de articol in baza de date parinte,este insotita de
mutarea pointerului de articol in baza de date legata pe articolul corespunzator.Daca nu se gaseste un
articol corespondent in baza de date legata,pointerul de articol din baza de date fiu este pozitionat la
sfarsitul bazei de date.
Expresia de legatura expr_1este de obicei cheia de indexare a indexului principal al bazei de date
fiu.
INTO n1 | alias1,indica prin numar sau alias,zona de lucru in care este deschisa baza de date fiu.
Comanda SET RELATION TO anuleaza toate relatiile de legatura ale bazei de date din zona de
lucru curenta .
Se pot crea mai multe relatii de legatura intre baza de date din zona de lucru curenta si baze de
date deschise in alte zone de lucru prin precizarea mai multor relatii separate prin virgula in forma
comenzii.
Utilizarea clauzei ADDITIVE are ca efect pastrarea tuturor relatiilor stabilite in zona de lucru
curenta,anterior.In caz contrar acestea sunt anulate.

Exemplu:

Considerand bazele de date descrise anterior si tinand cont de faptul ca in baza de date
FACTURI campul cod_ben constituie codul unui client,printr-o relatie intre cele doua baze de date
astfel:

SELE 1
USE clienti
INDEX ON cod_client TO codcind
SELE 2
USE facturi
SET RELA TO cod_ben INTO clienti
BROW FIELDS nrf,dataf,clienti.den_client,valf

Un caz particular al relatiilor intre bazele de date il constituie legatura”Unu la n” (1-To –Many).O
legatura”Unu la n”,pune in corespondenta mai multe articole din baza de date fiu,unui singur articol din
baza de date parinte .
Cand se prelucreaza baze de date legate prin legatura”Unu la n”,pointerul de articol ramane pozitionat
pe un articol din baza de date parinte,pana se prelucreaza toate articolele care ii corespund in baza de
date fiu.
Stabilirea unei relatii”Unu la n” se realizeaza intr-o maniera similara cu cea pentru stabilirea unei
relatii “Unu la unu”.Se incepe cu stabilirea unei relatii normale “Unu la unu” intre fiu si parinte (prin

175
comanda SET RELATION) dupa care se foloseste comanda SET SKIP pentru a transforma legatura
stabilita intr-o legatura”Unu la n”.]
Sintaxa comenzii SET SKIP este urmatoarea :

SET SKIP TO |alias1 |,alias2|…|

Daca baza de date parinte este legata de mai multe baze de date fiu (care au aliasurile alias1,
alias2, …) atunci relatiile respective pot fi transformate in relatii”Unu la n”printr-o comanda SET SKIP.
In comenziile care au efect asupra unui anumit domeniu de articole
(DISPLAY,LIST,etc.),articolele din baza de date parinte se vor repeta pentru fiecare articol
corespondent din baza de date fiu.
Anularea unei relatii “Unu la n” se realizeaza cu comanda SET SKIP TO (fara parametrii).
Exemplu:
In exemplul antertior s-a considerat ca parinte baza de date FACTURI iar baza de date CLIENTI
a fost considerata baza de date fiu.Daca schimbam modul de abordaresi consideram baza de date
CLIENTI ca baza de date parinte si baza de date facturi ca baza de date fiu si tinem cont de faptul ca
unui client ii pot corespunde mai multe facturi putem evidentia o relatie “Unu la n” astfel:
SELE 1
USE CLIENTI
SELE 2
USE FACTURI
INDEX ON cod_ben to FACTBEN
SELE CLIENTI
SET RELA TO cod_client INTO FACTURI
SET SKIP TO FACTURI
BROWSE FIELDS facturi.nrf,facturi.dataf,;den_client,facturi.valf

11.Reţele. Internet
11.1 Reţele de calculatoare, clasificarea reţelelor, protocoale
de reţea (noţiuni generale)
Structura reţelelor de calculatoare

Două sau mai multe calculatoare pot să facă schimb de date între ele prin două modalităţi:

      Off line – schimbul de date realizându-se prin intermediul dischetelor;

      On line – schimbul de date realizându-se prin intermediul unui cablu electric sau linii de
comunicaţie.

O reţea se formează atunci când mai multe PC sunt conectate unele la altele, astfel încât să
poată comunica între ele.

Dacă reţeaua este compusă din PC aflate în acelaşi loc este numită reţea locală (LAN).
Acestea sunt calculatoare care de obicei se afla în acelaşi departament, secţie de lucru sau sediu de
firma. O reţea locală a unei firme este denumită intranet, pentru a face distincţia de internet. Accesul la
intranet este în general limitat la angajaţii unei firme. Informaţiile existente în intranet sunt informaţii ale
firmei, şi deci intră din punct de vedere juridic şi organizatoric sub incidenţa secretului de serviciu.

In cazul în care calculatoarele sunt răspândite pe o arie mult mai mare, reţeaua este numită
reţea de mari dimensiuni (WAN). Aceste reţele pot fi alcătuite din calculatoare aflate în oraşe sau ţări
diferite.

176
Internet-ul este un conglomerat la scară mondială de reţele de calculatoare. Internetul nu este
proprietatea nici unei firme şi nu este coordonat de nici o firmă şi reprezintă o reţea de reţele de
calculatoare care pot comunica între ele.

Majoritatea reţelelor sunt formate din câte un server şi clienţii conectaţi la reţea.

O reţea de calculatoare oferă o gamă largă de avantaje, printre care putem enumera:

   Comunicarea prin posta electronică;

   Datele centralizate pot fi accesate de calculatoarele din reţea;

   Resursele pot fi partajate între calculatoare (de exemplu modemuri, imprimante, etc);

   Posibilitatea de a crea copii de siguranţă în server.

Intr-o reţea locală de componente similare (tip Peer-to- peer) toate staţiile de lucru sunt
interconectate şi partajează imprimantele, fişierele, dosarele şi alte resurse. Toate persoanele care
folosesc reţeaua îşi salvează fişierele în propriile calculatoare, ceea ce face ca gestionarea fişierelor să
fie dificilă. Aceste reţele nu trebuie să includă mai mult de 10 calculatoare.

Intr-o reţea client-server, informaţiile sunt stocate mult mai eficient, prin intermediul calculatorului
principal folosit ca server de fişiere, în care toţi utilizatorii reţelei îşi salvează propriile date. Serverul de
fişiere este de regulă un calculator ce se află de obicei într-o cameră specială separată şi nu este folosit
individual.

Reţeaua locală este configurată de persoane specializate şi este condusă de un administrator de


reţea.

Utilizatorii trebuie doar să ştie să se conecteze la reţea şi să acceseze resursele care sunt puse
la dispoziţie de către administrator. In Windows 95, dacă este folosită o reţea, pe suprafaţa de lucru
apare pictograma denumita Network Neighborhood, care prin activare afişează punctele de acces la
calculatoarele şi imprimantele din reţea. Dosarul Entire Network, a cărui pictogramă apare în dosarul
Network Neighborhood, afişează punctele de acces la resursele de calculatoare din afara grupei de
lucru.

La executarea dublu clic pe pictograma Network Neighborhood, acesta se deschide şi apar


pictogramele tuturor PC din sistem, cu denumirea fiecărui calculator sub pictograma respectivă.

După deschiderea ferestrei Network Neighborhood, se execută dublu clic pe un server sau alt
calculator din fereastră, pentru a vedea ce resurse sunt la dispoziţie pentru solicitant. Apoi se activează
dosarul sau un periferic cu care se lucrează ca şi cum ar aparţine calculatorului solicitant. Pentru
aceasta se foloseşte bara orizontală superioară.

Pentru închiderea ferestrei Network Neighborhood se foloseşte aceeaşi metodă ca pentru orice
fereastră Windows 95, selectând din meniul File opţiunea Close din meniul ferestrei sau executând clic
pe butonul Close (X) din coltul din dreapta sus al ferestrei. Inchiderea ferestrei nu determină
deconectarea de la reţea, decât atunci când se comandă întreruperea legăturii sau este închis
calculatorul.

177
11.2 Reţeaua Internet – descriere generală, adresarea în
Internet
Utilizarea internetului

a. Scurt istoric

Predecesorul Internetului este prima reţea de comunicaţii cu calculatoare ARPAnet, creata de


Ministerul Apărării – SUA în 1969, care ulterior în 1983 s-a divizat în două sisteme diferite: MILNET
exclusiv pentru operaţiunile militare şi respectiv ARPAnet rezervat domeniilor civile. Cele două mari
reţele au rămas conectate, astfel încât utilizatorii să poată schimba informaţii, şi astfel acest sistem
interconectat a fost cunoscut sub numele de Internet.

In 1986, Fundaţia Naţională pentru ştiinţă a SUA a creat NSFNET (National Science Fondation
Network) pentru a conecta supercalculatoarele de mare viteză din SUA, aceasta din raţiuni ştiinţifice.
Această ultimă reţea a preluat şi reţelele ARPAnet.

Reţeaua Internet-ul este descentralizată şi parţial anarhică. Nu există un organism administrativ


fix sau alte organisme care să fixeze regulile de funcţionare, cu excepţia ISOC – care este o
organizaţie cu caracter voluntar şi scopul său este promovarea schimbului global de informaţii.

Dezvoltarea reţelei Internet a fost spectaculoasă, astfel că în 1985 erau conectate aproximativ
2.000 de calculatoare, în 1997 cca. 9 milioane de calculatoare.

In prezent oricare posesor al unui calculator conectat la o linie telefonica poate avea acces la
Internet.

Pentru conectarea la Internet, trebuie îndeplinite următoarele condiţii minimale: un PC


performant, dotat cu Windows 95 sau unul mai performant dotat cu un modem specializat pentru
aceasta, o linie telefonică şi un abonament la un furnizor de servicii Internet independent sau un serviciu
comercial on-line.
 

b. Facilităţi asigurate de INTERNET 

Internetul în prezent asigură accesul la următoarele servicii şi facilităţi:

   World Wide Web (WWW) sau pe scurt Web, este uriaşă colecţie de documente care conţin
informaţii ce sunt păstrate pe calculatoare răspândite în toată lumea. WWW a fost creat în
Elveţia la Centre Europeen de Recherche Nucleare (CERN). Documentele sunt create cu o
tehnologie specială, numită hipertext. Mulţi pun semnul egalităţii între Internet şi Web,
întrucât Web-ul are cea mai mare pondere în serviciile Internet. De altfel a apărut expresia Surf
in Web, care înseamnă plimbare prin Internet.

   Use Net, protocol ce poate fi folosit pentru cuplarea la grupurile de discuţii, pentru a colabora
cu alţi colaboratori conectaţi la Internet.

   File Transfer Protocol, permite transferarea de fişiere de pe un calculator-gazdă pe altul.

   Internet Relay Chat, poate fi folosit pentru a purta conversaţii în direct, chiar se pot organiza
conferinte video şi audio.

   Posta electronică (e-mail), prezentată la paragraful 8.2.


 

c. Protocoale folosite pe internet pentru a lucra în WWW  

178
Pentru a lucra în Web sunt folosite mai multe protocoale:

   Internet protocol (IP), fiind cel mai simplu protocol de comunicare între calculatoare;

   Transmission Control Protocol (TCP), care este mai performant decât cel de mai sus
întrucât asigură corectarea erorilor de transmisie.

Deoarece cele două protocoale prezentate mai sus sunt folosite de regulă împreună, ele sunt
menţionate mereu împreună sub forma TCP / IP.

   File Transfer Protocol (FTP), defineşte modul în care este transferat un fişier generic dintr-
un calculator în altul. fişierul poate fi de forma: document, program, o imagine, etc.

   Hyper Text Markup Language (HTML), care defineşte o metodă de adăugare a atributelor
de formatare în fişierele de text, pentru a fi vizualizate fişierele de text citite ca nişte titluri,
paragrafe centrate şi imagini înglobate.

   Hyper Text Transfer Protocol (HTTP), defineşte modul în care calculatoarele transmit
fişierele HTML în ambele direcţii.
 

d. Utilizarea reţelei Web 

WWW este o colecţie de milioane de documente cu diferite informaţii care sunt păstrate pe
calculatoare răspândite în întreaga lume. Pentru a uşura accesul la aceste informaţii se dau în
continuare câteva definiţii:

   Pagina Web reprezintă un document Web;

   Situl Web este o colecţie de pagini Web, care aparţin aceleaşi instituţii sau persoane;

   Pagina sursă (Home Page) este pagina principală dintr-un sit Web;

   Hipertextul reprezintă metoda folosită pentru a organiza informaţia în reţeaua Web.
Folosindu-se această metodă, textele sau imaginile evidenţiate într-un document reprezintă
trimiteri la alte documente care conţin informaţii suplimentare;

   Hypermedia reprezintă o extindere a metodei hypertext, prin care trimiterile sunt extinse şi la
alte medii cum sunt sunetele şi imaginile video;

   URL (Uniform Resource Locator) reprezintă adresa unei locaţii cu informaţii din reţeaua
Internet. Aceasta este formată din trei părţi:

      Numele protocolului. Precizează tipul resursei Internet. In tabelul 8.3 sunt prezentate
câteva tipuri de resursă.

      Numele gazdei. Prezintă numele calculatorului pe care este stocată informaţia.

      Calea fişierului. Precizează numele fişierului în care se găseste informaţia şi calea de
cataloage până la catalogul în care se află fişierul.

   Browserul este un program care ajută la găsirea şi citirea informaţiilor în documentele html
ale reţelei Web şi asigură următoarele operaţii mai importante:

      Deplasarea printre documentele web şi vizualizarea lor;

179
      Folosirea semnelor de carte şi a istoricului pentru regăsirea rapidă a informaţiilor;

      Copierea informaţiilor în fişiere în calculatorul propriu.

Cele mai cunoscute browsere sunt:

      Internet Explorer a fost creat de Microsoft şi inclus în sistemele de operare Windows 95
şi 98.

      Netscape Navigator, care a fost creat de Netscape Communication Corporation, poate fi
folosit în sistemele windows 95 şi 98.

11.3 (*) Serviciile reţelei Internet (transferarea fişierelor prin


ftp, poşta electronică, www,
telnet)
Utilizarea poştei electronice 

Poşta Internet – Email-ul este o formă modernă de comunicare, ce combină rapiditatea unui apel
telefonic cu înregistrarea şi expedierea unei scrisori. Transmiterea scrisorii durează doar câteva
secunde, iar destinatarul poate răspunde când doreşte şi în plus nu trebuie contactat direct destinatarul
pentru transmiterea scrisorii.

Un alt avantaj al poştei electronice este preţul scăzut al abonamentului, de cca. 2…3 $ pe lună şi
respectiv costul scăzut al transmisiei şi recepţiei scrisorilor prin E-mail, care se taxează pentru
impulsurile telefonice de câteva secunde dintre abonat şi server, server care se află de obicei în acelaşi
oraş cu abonatul.

Dezavantajul poştei electronice este că nu asigură inviolabilitatea corespondentei.

O adresă de E-mail are două părţi, Prima parte este numele utilizatorului sau orice alt nume ales de
utilizator urmată de semnul @ şi a doua parte este numele contului de la posta electronică urmat adesea de
simbolul tării în care se află serverul. De obicei numele contului se confundă cu numele serverului la care
este abonat calculatorul gazdă. Deci o adresă poate fi scrisă sub forma: aalecu@fx.ro unde aalecu
reprezintă numele utilizatorului calculatorului gazdă., fx numele serverului şi ro prescurtarea de la România.
In caz că nu apare numele tării, se subînţelege că serverul se află în SUA şi în general aparţine de una din
următoarele şapte domenii de organizaţie diferite, aşa cum se observă din Tabelul 8.1

Tabelul 8.1.

Cod Domeniu
.com Entităţi comerciale
.edu Instituţii educaţionale
.gov Instituţii guvernamentale non-militare ale SUA
.int Instituţii internaţionale (NATO).
.mil Instituţii militare SUA.

180
.net Resurse de reţea
.org Organizaţii non-profit.

Comunicarea prin posta electronică

Pentru utilizarea poştei electronice, firma gazdă la care se face abonamentul pentru E-mail
livrează clientului pachetul de programe care asigură funcţia de agent utilizator, printre care enumerăm:

   Outlook Express Mail;

   Eudora.

Cu Outlook Express Mail se poate trimite mesaje prin E-mail oricărei persoane a cărei adresă de
E-mail există pe Internet, intranet şi post individual abonat la un server. Se pot trimite în plus fişiere,
rapoarte, scrisori şi foi de calcul tabelar – sub formă de anexe la mesajele transmise. De obicei
programul Outlook Express Mail este folosit de clienţii abonaţi la Internet.

Eudora este un pachet de programe folosit de obicei de clienţii abonaţi la o postă electronică (un
server), numai pentru E-mail.

Un program de postă asigură în general următoarele operaţii:

   Compunerea, transmiterea şi recepţia mesajelor;

   Administrarea mesajelor primite: vizualizarea, arhivarea pe disc sau tipărirea lor, ştergerea;

   Retransmiterea către alţi destinatari a mesajelor primite;

   Confirmarea trimiterii mesajului;

   Confirmarea de către destinatar a recepţionării mesajului;

   Folosirea fişierelor cu semnături;

   Ataşarea unor fişiere ;

Un mesaj E-mail este format din patru elemente:

   Antetul (Header), care este un text cu care începe mesajul. Conţine informaţii despre destinatar,
autor, subiect şi ora transmisiei;

   Corpul (Body), care reprezintă mesajul propriu zis;

   Semnătura (Signature), care este un text care se adaugă la sfârşitul mesajului poştal, şi
cuprinde cel puţin numele autorului. Mulţi autori introduc de obicei în plus numele firmei şi
numărul de telefon unde pot fi contactaţi.

   Anexele ataşate mesajului (Attach binary file), prezentate la pct..8.2.2.

181
La compunerea unui mesaj, este bine să se ţină cont de anumite facilităţi pe care programele
de postă electronică le asigură, prezentate în

Tabelul 8.2.

Facilitatea Semnificaţia
Pseudonim (Alias) Permite să se definească nume alternative, scurte
şi familiare pentru anumiţi utilizatori.
Copii (Carbon Copy) Permite să se transmită mesajul la mai multe
adrese.
Inserarea de fişiere Permite înserarea de fişiere în corpul mesajului.
(Including File)
Lista de adrese Se defineşte o lista de adrese sau grupuri de
(Mailing List) adrese cărora li se pot trimite mesaje prin
E-mail-uri .
Confirmarea primirii Permite trimiţătorului unui mesaj să primească
(Receipt Notification) confirmarea sosirii la destinaţie a mesajului.

Transmiterea unui mesaj se realizează în acelaşi mod, indiferent de clientul de postă (serverul)
folosit:

      Se apelează butonul aferent (New, Compose) pentru a se deschide o nouă fereastră de
mesaj;

      Se completează următoarele câmpuri:

-           To – Se scrie adresa de E-mail sau se activează săgeata din dreapta câmpului şi apare
lista de adrese din care se alege destinatarul mesajului

-           Cc – Se scrie o listă de adrese la care se pot trimite copii ale mesajului;

-           From – Automat, adresa expeditorului şi data transmiterii sunt completate de computer.

-           Subject – se completează opţional de expeditor cu o scurtă descriere a mesajului;

-           Body – se construieşte mesajul de transmis.

      Se execută clic pe un buton din fereastră pentru a expedia mesajul. Acest buton este
denumit de obicei Send;

      Se face conectarea la reţea şi se execută clic pe comanda de expediere ( Send / Send
Only), şi / sau pe cea de expediere şi primire mesaje (Get All) sau alte comenzi similare pe
care le asigură programul. După ce s-a transmis mesajul, conţinutul acestuia este mutat
automat în dosarul Send items.

      Dacă se doreşte doar primirea unor mesaje depuse la server, se face conectarea la reţea
prin comanda Get Mail sau alta asemănătoare, funcţie de programul folosit.

182
Se poate răspunde la un mesaj în mai multe moduri:

   Răspuns către expeditor (Reply). In acest caz adresa destinatarului este completată automat,
fiind preluată din adresa expeditorului la al cărui mesaj se răspunde. Răspunsul poate fi de
două feluri, cu păstrarea textului sosit sau fără păstrarea lui în răspuns. La clicarea pe
butonul (Reply), apare mesajul (Quote original message) la care se poate răspunde cu
(Yes) sau (No).

   Reexpedierea mesajului (Forward), acţiune prin care mesajul este retransmis către un alt
destinatar. Adresa expeditorului iniţial este înlocuită cu adresa utilizatorului care reexpediază
mesajul;

   Redirecţionarea mesajului (Redirect), prin care mesajul este transmis către un alt destinatar,
păstrându-se ca adresă de expeditor, adresa expeditorului iniţial.

Gestionarea fişierelor ataşate la mesajele E-mail 

Dacă este folosită posta electronică, nu este nevoie de fax sau oficiu poştal pentru a trimite
documente. Acestea pot fi ataşate la un mesaj şi trimise destinatarului.

Gestionarea fişierelor constă din:

   Ataşarea fişierelor la mesajele transmise;

   Extragerea fişierelor ataşate din mesaje;

   Folosirea WinZip-ului pentru a lucra cu fişierele atasate şi arhivate;

a. Ataşarea unui fişier la un mesaj

Pentru a ataşa un fişier la un mesaj, se trage cu mouse-ul fişierul din Windows Explorer şi se
plasează în corpul mesajului cu care trebuie transmis. Va apare o pictogramă şi numele fişierului în
corpul mesajului. Se pot ataşa oricâte fişiere în corpul unui mesaj.

In cazul utilizării programului Outlook Express Mail, se alege din meniul principal Insert, opţiunea
File Attachment. Apoi se alege fişierul dorit din caseta de dialog File Attachment şi în final se execută
clic pe Attach. Va apare un panou în partea de jos a ferestrei în care se află textul mesajului, care va
conţine câte o pictogramă pentru fiecare fişier ataşat la mesaj.

b. Extragerea fişierelor ataşate, din mesaje

Extragerea se obţine prin clicarea pe pictograma agrafă a mesajului. Opţional se poate


copia/muta fişierul în dosarul dorit.

In cadrul programului Outlook Express, se poate afişa conţinutul unui fişier ataşat, efectuând
dublu clic pe icoana aferenta..

c. Folosirea WinZip-ului pentru a lucra cu fişierele ataşate şi arhivate

183
Se pot economisi timp, efort şi bani, comprimând fişierele înainte de a le ataşa la un mesaj de
postă. Pentru a crea un fişier Zip şi a adăuga fişiere în el, se vor executa următoarele manevre:

      In Window Explorer vor fi selectate fişierele care trebuiesc comprimate.

      Se execută apoi clic-dreapta pe fişierele selectate şi în continuare se va alege comanda Add
to Zip. Dacă această comandă nu apare, înseamnă că programul WinZip nu este instalat pe
PC.

      Se scrie calea şi numele fişierului ZIP în câmpul Add to Archive.

      Se execută apoi clic pe Add, iar WinZip va adăuga fişierele selectate în fişierul ZIP.

      După examinarea conţinutului fişierului ZIP, se închide WinZip executând clic pe butonul X
din bara de titlu. Acum fişierul comprimat poate fi ataşat la mesajul E-mail.

Extragerea unui fişier ZIP ataşat la un mesaj de postă E-mail, se face după cum urmează:

      Se execută dublu-clic pe pictograma fişierului ZIP din cadrul mesajului. Programul WinZip va
afişa conţinutul fişierului.

      Se alege din meniul principal Action, Extract şi se va vizualiza caseta de dialog Extract.

      Se închide programul WinZip.

      Se execută dublu-clic pe fişierul ZIP din mesajul E-mail şi în cadrul programului WinZip va fi afişat
conţinutul fişierului ZIP.

Facilităţi asigurate de INTERNET 

Internetul în prezent asigură accesul la următoarele servicii şi facilităţi:

   World Wide Web (WWW) sau pe scurt Web, este uriaşă colecţie de documente care conţin
informaţii ce sunt păstrate pe calculatoare răspândite în toată lumea. WWW a fost creat în
Elveţia la Centre Europeen de Recherche Nucleare (CERN). Documentele sunt create cu o
tehnologie specială, numită hipertext. Mulţi pun semnul egalităţii între Internet şi Web,
întrucât Web-ul are cea mai mare pondere în serviciile Internet. De altfel a apărut expresia Surf
in Web, care înseamnă plimbare prin Internet.

   Use Net, protocol ce poate fi folosit pentru cuplarea la grupurile de discuţii, pentru a colabora
cu alţi colaboratori conectaţi la Internet.

   File Transfer Protocol, permite transferarea de fişiere de pe un calculator-gazdă pe altul.

   Internet Relay Chat, poate fi folosit pentru a purta conversaţii în direct, chiar se pot organiza
conferinte video şi audio.

   Posta electronică (e-mail), prezentată la paragraful 8.2.


 

c. Protocoale folosite pe internet pentru a lucra în WWW  

Pentru a lucra în Web sunt folosite mai multe protocoale:

184
   Internet protocol (IP), fiind cel mai simplu protocol de comunicare între calculatoare;

   Transmission Control Protocol (TCP), care este mai performant decât cel de mai sus
întrucât asigură corectarea erorilor de transmisie.

Deoarece cele două protocoale prezentate mai sus sunt folosite de regulă împreună, ele sunt
menţionate mereu împreună sub forma TCP / IP.

   File Transfer Protocol (FTP), defineşte modul în care este transferat un fişier generic dintr-
un calculator în altul. fişierul poate fi de forma: document, program, o imagine, etc.

   Hyper Text Markup Language (HTML), care defineşte o metodă de adăugare a atributelor
de formatare în fişierele de text, pentru a fi vizualizate fişierele de text citite ca nişte titluri,
paragrafe centrate şi imagini înglobate.

   Hyper Text Transfer Protocol (HTTP), defineşte modul în care calculatoarele transmit
fişierele HTML în ambele direcţii.
 

d. Utilizarea reţelei Web 

WWW este o colecţie de milioane de documente cu diferite informaţii care sunt păstrate pe
calculatoare răspândite în întreaga lume. Pentru a uşura accesul la aceste informaţii se dau în
continuare câteva definiţii:

   Pagina Web reprezintă un document Web;

   Situl Web este o colecţie de pagini Web, care aparţin aceleaşi instituţii sau persoane;

   Pagina sursă (Home Page) este pagina principală dintr-un sit Web;

   Hipertextul reprezintă metoda folosită pentru a organiza informaţia în reţeaua Web.
Folosindu-se această metodă, textele sau imaginile evidenţiate într-un document reprezintă
trimiteri la alte documente care conţin informaţii suplimentare;

   Hypermedia reprezintă o extindere a metodei hypertext, prin care trimiterile sunt extinse şi la
alte medii cum sunt sunetele şi imaginile video;

   URL (Uniform Resource Locator) reprezintă adresa unei locaţii cu informaţii din reţeaua
Internet. Aceasta este formată din trei părţi:

      Numele protocolului. Precizează tipul resursei Internet. In tabelul 8.3 sunt prezentate
câteva tipuri de resursă.

      Numele gazdei. Prezintă numele calculatorului pe care este stocată informaţia.

      Calea fişierului. Precizează numele fişierului în care se găseste informaţia şi calea de
cataloage până la catalogul în care se află fişierul.

   Browserul este un program care ajută la găsirea şi citirea informaţiilor în documentele html
ale reţelei Web şi asigură următoarele operaţii mai importante:

      Deplasarea printre documentele web şi vizualizarea lor;

      Folosirea semnelor de carte şi a istoricului pentru regăsirea rapidă a informaţiilor;

185
      Copierea informaţiilor în fişiere în calculatorul propriu.

Cele mai cunoscute browsere sunt:

      Internet Explorer a fost creat de Microsoft şi inclus în sistemele de operare Windows 95
şi 98.

      Netscape Navigator, care a fost creat de Netscape Communication Corporation, poate fi
folosit în sistemele windows 95 şi 98.

11.3 (*) Căutarea informaţiei pe Internet – motoare de


căutare

Căutarea informaţiei se poate realiza după:

      Adresa URL a paginii Web;

      Cuvinte cheie care descriu subiectul cercetat;

      Semne de carte.

Tabelul 8.3.

Diferite tipuri de adrese URL


 

Format Exemplu
http:// http:// www.pub.ro
telnet:// telnet://onramp.net
Gopher:// gopher:// gopher.umc.edu
ftp:// ftp:// ftp.mcp.com/que
file:/// file:/// cIwindows/readme.bat

Reţeaua Web funcţionează pe baza relaţiei client-server, serverul fiind calculatorul pe care se
găsesc unul sau mai multe situri Web, iar clientul este calculatorul de pe care se emite cererea de
informaţii.

In continuare este prezentat un exemplu de căutare a unor informaţii folosind browserul Internet
Explorer în cadrul unui calculator utilat cu sistemul de operare Windows 95 şi conectat la un server la
care este abonat.

   Se execută un clic pe caseta Internet explorer din suprafaţa de lucru a mediului Windows 95.

186
   Va apare pe ecran tabloul Dial-up Connection. Se vor completa rubricile: User name şi
Password cu cuvintele din protocolul de închiriere pentru folosirea reţelei Internet încheiat cu
serverul. Apoi se antrenează tasta Connect.

   Va apare o suprafaţă de lucru pentru Internet. Se introduce în bara orizontală superioară
adresa unei locaţii în care se caută anumite informaţii.

In cazul prezent se va scrie www.pub.ro care reprezintă adresa în Web pentru Universitatea
Politehnică Bucuresti.

   Va apare pagina sursă. Se va clica pe caseta relansin şi vor apărea o serie de informaţii
referitoare la programul de cercetare Relansin.

   La închiderea lucrului, se clichează pe X şi se părăseşte suprafaţa de lucru Internet Explorer.

   Apare din nou suprafaţa de lucru a mediului Windows 95. Se clichează caseta cu două
monitoare cuplate din bara orizontală de jos şi apare un tablou şi se va clica pe tasta
Disconnect.

e. Atenţionări şi codul de conduită 

Alegeţi cu atenţie mesajele necesare de pe Internet. Circulă şi multe informaţii neinteresante


(gunoaie) sau obscene.

Orice fişier copiat de pe Internet trebuie mai întâi devirusat.

Informaţiile care circulă pe Internet trec de la un calculator la altul, şi pot fi interceptate de


persoane din lanţul de transmitere. Deci evitaţi să transmiteţi informaţii personale ca: adresă, număr de
telefon, numărul cardului de plată, etc.

Nu daţi adresa cutiei poştale unor persoane necunoscute, pentru ca să nu aveţi surprize
neplăcute.

Utilizatorii de Internet folosesc codul de conduită numit Netiquette. Dintre regulile sale se
enumera în continuare:

      Nu fiţi nepoliticos şi nu utilizaţi inutil resursele reţelei Internet;

      Transmiteţi informaţii cât mai concise;

      Nu scrieţi mesajele cu majuscule, sunt mai greu de citit şi dau impresia de nepoliteţe.

      Nu declanşaţi un război al insultelor.

187
      Furnizorul de servicii Internet la care sunteţi abonat poate închide conexiunea, dacă prea
mult timp fiind conectat on-line, nu o folosiţi.

      Nu folosiţi munca altora fără a le cere permisiunea. Astfel unii utilizatori preiau din reţea
texte, imagini şi videoclipuri asupra cărora acţionează legea dreptului de autor.

Dacă doriţi să citaţi o sursă on-line în propriile lucrări, informaţi-vă care sunt modalităţile legale
prin care se obţine aprobarea pentru citare.

Pentru citarea în lucrarea proprie a unor paragrafe sau informaţii culese on-line, Asociaţia
Americană de Fiziologie a propus aşa cum se vede din Tabelul 8.3, următorul standard pentru
integrarea citatelor: Autor (i), Data publicării, Titlul documentului, Tipul documentului, URL, Data
vizionării.

Tabelul 8.4.
 

Titlul Conţinutul
Autor ( i ) Numele fiecăruia dintre autorii documentului. Dacă pagina
Web conţine doar / şi o adresă de e-mail sau un pseudonim,
treceţi-le şi pe acestea.
Data publicării Data la care a fost publicat documentul. De obicei la sfârşitul
documentului se găseşte data celei mai recente actualizări a
unei pagini Web.
Titlul Titlul paginii Web aşa cum apare în bara de titlu a
documentului browserului.
Tipul Poate fi unul din tipurile de documente enumerate în Tabelul
documentului 8.5.
URL Adresa URL completată, poate fi una din adresele
enumerate în Tabelul 8.3.
Data vizitării Data la care aţi găsit materialul citat în vizita pe Internet.
Este bine să fie menţionat deoarece informaţiile Internet se
schimbă în mod frecvent.

Tabelul 8.5.

Tipuri de documente care pot fi citate

Tipul documentului Descriere


Database Bază de date on-line
Digitized Image Imagine digitală, fişier grafic (GIF,JPG, etc)
Digitized Sound File Sunet digital, fişier audio (WAV,AU, etc.)
Digitized Video File Video clip digital, fişier video (AVI,MOV, etc.)
Electronic Data File Alte fişiere
FTP Archive Dosar dintr-o arhivă FTP
Gopher Menu Meniu Gopher, locaţie dintr-un document.
On-line News Posting Mesaj dintr-un grup de discuţii UseNet

188
On-line Search Query Rezultatul unei interogări on-line
On-line Serial Mesaj distribuitor periodic prin e-mail
On-line Service Serviciu accesat prin Telnet
PostScript File Fişier Postcript.
Text File Fişier de text simplu.
WAIS Database Bază de date WAIS cu acces public
WAIS Query Rezultatul unei interogări WAIS
WWW document Pagină Web

Bibliografie:
1. Manuale de informatică aprobate de Ministerul Educaţiei şi Cercetării
2. Albeanu G., Sisteme de operare, Ed. Petrion, 1996
3. Albeanu G., Programarea în Pascal ºi Turbo Pascal, Ed. Tehnică, 1994
4. Andonie R., Gârbacea I., Algoritmi fundamentali, o perspectivã C++, Ed. Libris,
1995
5. Barbu Gh., Văduva I,. Boloşteanu M., Bazele informaticii, Ed. Tehnică, 1997
6. Bălănescu T., Gavrilă S., Georgescu H., Gheorghe M., Sofonea L., Văduva I.,
Pascal ºi
Turbo Pascal, Ed. Tehnică, Bucureşti, 1992
7. Beu T., Analiza numericã în Turbo Pascal, Ed. Microinformatica, Cluj Napoca,
1992
8. Bulăceanu C., Reþele locale de calculatoare, Ed. Tehnică, 1995
9. Cadar C., Gheorghiţă V., Tehnologia informaþiei - manual pentru clasa a IX-a, Ed.
L&S

189
Infomat, 1999
10. Calude C., Complexitatea calculului. Aspecte calitative, Ed. Ştiinţifică şi
Enciclopedică,
Bucureşti, 1982
11. Calude C., Teoria algoritmilor, Ed. Universităţii Bucureşti, 1987
12. Cerchez, E., Internet – manual opþional pentru liceu, Ed. Polirom Iaşi, 2000
13. Cerchez, E., Informatica – Culegere de probleme pentru liceu, Ed. Polirom Iaşi,
2002
14. Cerchez, E., Şerban, M. Informatica – manual pentru clasa a X-a. Ed. Polirom
2000, Iaşi
15. Cerchez, E., Şerban, M. PC pas cu pas. Ed. Polirom 2001, Iaşi
16. Cormen T., Leiserson Ch., Rivest R., Introducere în algoritmi, Ed. Computer
Libris
Agora, Cluj
17. Cristea V., Kalisz E., Athanasiu I., Pănoiu S., Turbo Pascal, Ed. Teora, 1992
18. Dima G., Dima M., FoxPro, Ed. Teora, 1994
19. Frâncu C., Informatica economicã - Fox Pro, Ed. L&S Infomat, Bucureşti, 1998
20. Georgescu H., Livovschi L., Analiza ºi sinteza algoritmilor, Ed. Ştiinţifică şi
Enciclopedică, Bucureşti, 1986
21. Giumale C., Negreanu L., Călinoiu S., Proiectarea ºi analiza algoritmilor.
Algoritmi de
sortare, Ed. All, 1997
22. Grigoriu, D., ş.a. – Informatica – subiecte rezolvate de bacalaureat date în anii
1999-
2001, Ed. Niculescu, Bucureşti 2002
23. Horowitz E., Fundamentals of Data Structures in C++, Computer Science Press,
1995
24. Horowitz E., Fundamentals of Programming Languages, Springer Verlag, 1983
25. Ionescu C., Zsako I., Structuri arborescente, Ed. Tehnică, Bucureşti,1990
26. Ivaşc C., Prună M., Bazele informaticii, Ed. Petrion, 1995
27. Ivaşc C., Prună M., Mateescu E., Bazele Informaticii (Grafuri ºi elemente de
combinatoricã) - Caiet de laborator, Ed. Petrion, 1997
28. Ivaşc C., Prună M., Tehnici de programare (Aplicaþii), Ed. Petrion, 1999
29. Ivaşc C., Prună M.,ş.a. Informatica – manual pentru clasa a XI-a, Ed. Petrion,
Bucureşti
2001
30. Jamsa K., Succes cu C++, Ed. All, 1997
31. Knuth D. E., Tratat de programarea calculatoarelor, vol. I, II, III, Ed. Teora
Bucureşti
2002
32. Lica D., Onea E., Informatica, manual pentru clasa a IX-a, Ed. L&S Infomat,
1999
33. Lica D., Onea E., Informatica, manual pentru clasa a X-a, Ed. Prognosis, 2000
34. Lica. D., Popescu, D.A., ş.a. – Bacalaureat la informaticã – Ed. L&S Infomat,
Bucureşti
2002
35. Lungu I., Muşat N., Velicanu M., Sistemul FoxPro 2.6 - Prezentare ºi aplicaþii,
Ed. All,
1996

190
36. Lupulescu M., Munteanu M., Giulvezan C., FoxPro, de la iniþiere la
performanþã, Ed. de
Vest, Timişoara, 1994
7
37. Mateescu G. D., C++, limbaj ºi programare, Ed. Petrion, 1998
38. Mateescu G. D., Analiza numericã, Ed. Petrion, 1995
39. Mârşanu R., Voicu A, şa, Tehnologia informaþiei, manual pentru clasa a IX-a, Ed.
All,
Bucureşti, 1999
40. Miloşescu M., Sisteme de calcul, Editura Teora, 1998
41. Mitrana V., Provocarea algoritmilor, Ed. Agni, Bucureşti, 1994
42. Negrescu L., Limbajul C ºi C++, Ed. Microinformatica. Cluj
43. Niculescu S., Pintea R., Tehnologia informaþiei ºi Informaticã-Tehnologii asistate
de
calculator - manual pentru clasa a IX-a, Ed. E.D.P., 1999
44. Niculescu S., Butnaru L., Butnaru V., Informaticã- manual pentru clasa a IX-a,
Ed.
E.D.P, 1999
45. Niculescu R., Albeanu G., Domocoş V., Programarea calculatoarelor - probleme
rezolvate în limbajul Turbo Pascal, Ed. Tempus, 1992
46. Odăgescu I., Copos C., Luca D., Furtună F., Smeureanu I., Metode ºi tehnici de
programare, Ed. Intact, Bucureşti, 1994
47. Odăgescu I., Furtună F., Metode ºi tehnici de programare, Editura Computer
Libris
Agora, 1998
48. Panţiru M., Panţiru I., Baze de date, Ed. L&S Infomat, Bucureşti, 1999
49. Panţiru M., Panţiru I., Informatica – manual pentru clasa a XII-a, Ed. L&S
Infomat,
Bucureşti, 2002
50. Pătrăşcoiu O., Marian Gh., Mitroi N., Informaticã - elemente de grafuri ºi
combinatoricã,
metode, algoritmi ºi programe, Ed. All, Bucureşti,
51. Pătruţ B., Miloşescu M., Informaticã - manual pentru clasa a IX-a, Ed. Teora,
1999

191

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