Sunteți pe pagina 1din 8

Universitatea Tehnic a Moldovei

Catedra Automatica si Tehnologii Informationale

RAPORT
lucrarea de laborator #2

TEMA: ALGORITMUL DE CUTARE N ADNCIME SI LARGIME


V. II

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.

Elaborarea procedurii de cutare n adncime si largime.

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.

1. Elaborai procedura care va realiza algoritmul de parcurgere a grafului n lrgime;


2. Folosind procedurile din lucrrile precedente, elaborai programul care va permite:
introducerea grafului n calculator;
parcurgerea grafului n lrgime;
extragerea datelor la display i printer.

CONSIDERAII TEORETICE:

Structuri de date: liste


Fiecare tip de list definete o mulime de iruri finite de elemente de tipul declarat. Numrul de elemente
care se numete lungimea listei poate varia pentru diferite liste de acelai tip. Lista care nu conine nici un
element se va numi vid. Pentru list sunt definite noiunile nceputul, sfritul listei i respectiv primul i
ultimul element, de asemenea elementul curent ca i predecesorul i succesorul elementului curent. Element
curent se numete acel unic element care este accesibil la momentul dat.
Structuri de date : fire de ateptare
Firele de ateptare (FA, rnd, coad, ir de ateptare) se vor folosi pentru a realiza algoritmul de prelucrare a
elementelor listei n conformitate cu care elementele vor fi eliminate din list n ordinea n care au fost
incluse n ea (primul sosit - primul servit).
Operaiile de baz cu firele de ateptare:
Formarea unui FA vid;
Verificare dac FA nu este vid;
Alegerea primului element cu eliminarea lui din FA;
Introducerea unei valori noi n calitate de ultim element al FA.
Structuri de date: stive
Stiva se utilizeaz pentru a realiza algoritmul de prelucrare a elementelor dup principiul "ultimul sosit -
primul prelucrat" (LIFO).
Operaiile de baz cu stivele sunt urmtoarele:
Formarea unei stive vide;
Verificare la vid;
Alegerea elementului din topul stivei cu sau fr eliminare;
Introducerea unui element nou n topul stivei.
Structuri de date - arbori
Se va defini o mulime de structuri fiecare din care va consta dintr-un obiect de baz numit vrf sau
rdcina arborelui dat i o list de elemente din mulimea definit, care (elementele) se vor numi subarbori
ai arborelui dat. Arborele pentru care lista subarborilor este vid se va numi arbore trivial, iar rdcina lui -
frunz.
Rdcina arborelui se va numi tatl vrfurilor care servesc drept rdcini pentru subarbori; aceste vrfuri se
vor mai numi copiii rdcinii arborelui: rdcina primului subarbore se va numi fiul cel mai mare, iar
rdcina fiecrui subarbore urmtor n list se va numi frate.
Operaiile de baz pentru arbori vor fi:
Formarea unui arbore trivial;
Alegerea sau nlocuirea rdcinii arborelui;
Alegerea sau nlocuirea listei rdcinilor subarborilor;
Operaiile de baz care sunt valabile pentru liste.

Algoritmul de cutare n lrgime

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.

Se vor forma dou fire de ateptare vide O1 i O2;

Introduce rdcina n FA O1;

WHILE cel puin unul din firele de ateptare O1 sau O2 nu va fi vid DO

IF O1 nu este vid THEN

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

n calitate de O1 se va lua FA O2, care nu este vid,


iar n calitate de O2 se va lua FA vid O1;

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:

Viziteaz rdcina arborelui i introdu-o n stiva vid S;


WHILE stiva S nu este vid DO
BEGIN

fie p - vrful din topul stivei S;


IF fiii vrfului p nc nu au fost vizitai
THEN viziteaz fiul mai mare al lui p i introduce-l n S
ELSE BEGIN

elimin vrful p din stiva S


IF p are frai THEN viziteaz pe fratele lui p i introduce-l n stiva S
END
END

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).

Introdu n stiv vrful iniial i marcheaz-l;


WHILE stiva nu este vid DO
BEGIN
extrage un vrf din stiv;
IF exist vrfuri nemarcate adiacente cu vrful extras
THEN marcheaz-le i introduce-le n stiv;
END

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.

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