RAPORT
lucrarea de laborator #2
A ndeplinit: st.
gr. C-132 Solotchi Radu
A verificat: G.
Marusic
Chiinu 2014
SCOPUL LUCRRII:
Studierea algoritmilor de cutare n graf i a diferitor forme de pstrare i prelucrare a datelor.
SARCINA DE BAZ:
1. Elaborai procedura cutrii n adncime ntr-un graf arbitrar;
2. Elaborai un program cu urmtoarele posibiliti:
introducerea grafului n calculator,
parcurgerea grafului n adncime, vizualizarea rezultatelor la display i imprimant.
CONSIDERAII TEORETICE:
Parcurgerea grafului n lrgime, ca i parcurgerea n adncime, va garanta vizitarea fiecrui vrf al grafului
exact o singur dat, ns principiul va fi altul. Dup vizitarea vrfului iniial, de la care va ncepe cutarea
n lrgime, vor fi vizitate toate vrfurile adiacente cu vrful dat, apoi toate vrfurile adiacente cu aceste
ultime vrfuri .a.m.d. pn vor fi vizitate toate vrfurile grafului. Evident, este necesar ca graful s fie
conex. Aceast modalitate de parcurgere a grafului (n lrgime sau postordine), care mai este adesea numit
parcurgere n ordine orizontal, realizeaz parcurgerea vrfurilor de la stnga la dreapta, nivel dup nivel.
Algoritmul de mai jos realizeaz parcurgerea n lrgime cu ajutorul a dou fire de ateptare O1 i O2.
BEGIN
fie p vrful din topul FA O1;
viziteaz vrful p eliminndu-l din O1;
viziteaz pe toi fiii lui p n FA O2, ncepnd cu cel mai mare;
END
ELSE
Vom nota c procedura parcurgerii grafului n lrgime permite s realizm arborele de cutare i n acelai
timp s construim acest arbore. Cu alte cuvinte, se va rezolva problema determinrii unei rezolvri sub
forma vectorului (a1, a2,...) de lungime necunoscut, dac este cunoscut c exist o rezolvare finit a
problemei.
Algoritmul pentru cazul general este analogic cu cel pentru un graf n form de arbore cu o mic modificare
care const n aceea c fiecare vrf vizitat va fi marcat pentru a exclude ciclarea algoritmului.
Cutare n adncime
La cutarea n adncime (parcurgerea unui graf n sens direct, n preordine) vrfurile grafului vor fi
vizitate n conformitate cu urmtoarea procedur recursiv:
mai nti va fi vizitat rdcina arborelui q, apoi, dac rdcina arborelui nu este frunz - pentru fiecare
fiu p al rdcinii q ne vom adresa recursiv procedurii de parcurgere n adncime pentru a vizita vrfurile
tuturor subarborilor cu rdcina p ordonate ca fii ai lui q.
n cazul utilizrii unei stive pentru pstrarea drumului curent pe arbore, drum care ncepe din rdcina
arborelui i se termin cu vrful vizitat n momentul dat, poate fi realizat un algoritm nerecursiv de forma:
Acest algoritm poate fi modificat pentru a putea fi utilizat la parcurgerea tuturor vrfurilor unui graf arbitrar.
n algoritmul de mai jos se va presupune c este stabilit o relaie de ordine pe mulimea tuturor vrfurilor
grafului, iar mulimea vrfurilor adiacente cu un vrf arbitrar al grafului este de asemenea ordonat:
WHILE va exista cel puin un vrf care nu a fost vizitat DO
BEGIN
fie p - primul din vrfurile nevizitate;
viziteaz vrful p i introduce-l n stiva vid S;
WHILE stiva S nu este vid DO
BEGIN
fie p - vrful din topul stivei S;
IF m vrfuri ale lui p sunt vrfuri adiacente nevizitate
THEN BEGIN
fie z primul vrf nevizitat din vrfurile adiacente cu p;
parcurge muchia (p,z), viziteaz vrful z i introduce-l n stiva S;
END
ELSE elimin vrful p din stiva S
END
END
n cazul n care se va lucra cu un graf conex arbitrar cu relaia de ordine lips, nu va mai avea importan
ordinea de parcurgere a vrfurilor. Propunem un algoritm care utilizeaz mai larg posibilitile stivei, cea ce
face programul mai efectiv n sensul diminurii timpului de calcul necesar. De exemplu, acest algoritm n
varianta recursiv este pe larg utilizat n programele de selectare global n subdirectori (cazul programelor
antivirus).
Listingul Programului:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
//----------------------------
void Prezt()
{ clrscr();
_setcursortype(_NOCURSOR);
getch();
}
//---------------------------
void main()
{int i,j,k,l,n,s,x,y,h;
char ch;
//---------------------------
Prezt();
L1:static int a[30][20],b[30];
clrscr();
_setcursortype(_NORMALCURSOR);
printf("\n\t");
printf("Introduceti numarul de virfuri ale arborelui : ");
scanf("%i",&n);
printf("\n\t");
printf("Introduceti lista de adiacenta :\n\n ");
for(i=0;i<n;i++)
{
printf("\r%2i|",i+1);
scanf("%i",&a[i][0]);
for(j=1;j<n+1;j++)
if(a[i][j-1]!=0) scanf("%i",&a[i][j]);
else break;}
//----------------------------
for(i=0;i<n;i++) b[i]=i+1;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(a[i][j]!=0)
if(b[a[i][j]-1]!=0&&0<a[i][j]&&a[i][j]<=n) b[a[i][j]-1]=0;
else goto l2; // Eror!
else break;
for(i=0,x=0;x<n;x++)
if(b[x]!=0) {b[0]=x+1; i++;}
if(i>1) goto l2; // Eror!
x=y=0;
printf("\n\n\r");
printf("Parcurgerea in largime :\n\r");
printf("\n %d,",b[0]);
for(i=1;i<n;i++)
{ if(a[b[x]-1][y]==0) {x++; y=0; i--;}
else {b[i]=a[b[x]-1][y]; y++;
printf(" %d,",b[i]);
if(i%15==0) printf("\n");
}
}
goto l4;
l2:printf("\n\n\t\t\t");
printf("Eroare!");
goto l3;
//-------------------------------
l4:printf("\n\n\n\r");
printf("Parcurgerea in adimcime:\n");
i=b[0]-1;j=s=h=0;
printf("\n %d,",b[0]);
while(h<n-1)
{k=i;
if(a[k][j]!=0)
{ printf(" %i,",a[k][j]);
i=a[k][j]-1;
}
l1:if(a[k][j]==0)
{ if(s==0)l=k+1;
if(s==1)l=x+1;
for(x=0;x<n;x++)
for(y=0;y<n+1;y++)
{ if(a[x][y]==l&&a[x][y+1]!=0)
{ printf(" %i,",a[x][y+1]);
i=a[x][y+1]-1;
s=0;
goto l5; }
if(a[x][y]==l&&a[x][y+1]==0)
{ s=1;goto l1;}
}
}
l5:h++;
if(h%15==0) printf("\n");
}
//-----------------------------
l3:_setcursortype(_NOCURSOR);
printf("\n\n\n");
printf(" Enter -> reincarca programul...\n\n");
printf(" Esc -> iesire din program!");
while(1)
{ ch=getch();
if(ch==27) exit(0);
if(ch==13) goto L1; }}
Rezultat:
!Concluzie: Efecuand aceasta lucrare de laborator, am invatat sa efectuam metodele de reprezentare ale
grafului atit in adincime cit si in largime, precum si metodele lui de stocare in memoria calculatorului.
Ca si la prima lucrare, pentru introducerea datelor am folosit lista de adiacenta, ea fiind cea mai simpla
metoda de introducere a grafului de la tastatura, care si piermite utilizatorului sa aleaga cu usurinta
virfurile necesare,de asemenea aceasta metoda utilizeaza si cel mai putin din memoria calculatorului.