Sunteți pe pagina 1din 27

Ministerul Educaţiei, Culturii și Cercetării al Republicii

Moldova

Universitatea Tehnică a Moldovei


Departamentul Tehnologia Informatiei

RAPORT

Lucrarea de laborator nr. 5-6 „ARBORI BINARI DE CĂUTARE”


„REPREZENTAREA ŞI TRAVERSAREA GRAFURILOR”

Chişinău – 20XX
Ex 3.1
/* pr_05_3_1
3.1 De la tastatura se citesc cuvinte ( siruri de caractere ). Sa se
scrie un program care creeaza un arbore de cautare, care contine in
noduri cuvintele
si frecventa lor de aparitie. Sa se afiseze apoi cuvintele in ordine
lexicografica crescatoare si frecventa lor de aparitie.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct nod


{
char *cheie; // cheia este un cuvant
int frecventa; // frecventa cuvantului
struct nod *st; // pointer la nodul fiu din stanga
struct nod *dr; // pointer la nodul fiu din dreapta
} NOD;
NOD *rad; // radacina arborelui

/* functia citeste de la tastatura in memoria heap un cuvant si


returneaza pointerul
spre cuvantul respectiv sau 0 la sfarsit de fisier */
char *citeste_cuvant()
{
int c, i; char t[255], *p;
// Salt peste caracterele care nu sunt litere
while( (c = getchar()) < 'A' || (c > 'Z' && c < 'a') || c > 'z' )
{
if(c == EOF) // s-a citit EOF
{
return 0;
}
}
// am citit prima litera
// citim cuvantul si il pastram in t
i = 0;
do
{
t[i++] = c;

} while( (c = getchar()) >= 'A' && c <= 'Z' || c >= 'a' && c <=
'z' );
t[i++] = '\0';

if( ( p = (char *)malloc( i ) ) == 0 ) // alocam memorie p/u


cuvantul citit
{
printf("Memorie insuficienta\n"); exit(1);
}
strcpy(p, t); // copiem cuvantul citit in memoria heap alocata
p/u el
return p;
} // sfarsit functie citeste_cuvant()
void inserare_nod(char *key)
{
NOD *p, *q;
int n = sizeof(NOD);
p = (NOD *)malloc(n); // alocam memorie p/u nod
p -> cheie = key;
//printf("p -> cheie = %s\n", p -> cheie);
p -> st = 0; p -> dr = 0; // este nod frunza
if( rad == 0 ) // arborele este vid; inca nu este nici-un nod
{
rad = p; rad -> frecventa = 1; return;
}
q = rad; // arborele nu este vid
for( ; ; ) // cautam locul unde poate fi inserat nodul
{
if( strcmp( key, q -> cheie ) == 0 ) // nodul cu cheia key
exista; marim frecventa cu 1
{
q -> frecventa += 1; // marim frecventa cu 1
return;
}

if( strcmp( key, q -> cheie ) < 0 ) // cautarea se face in


subarborele stang
{
if( q -> st == 0 ) // inserare, deoarece nodul q -> st
nu exista; frecventa se pune 1
{
q -> st = p; p -> frecventa = 1; return;
}
else // nodul q -> st exista; trecem la el
{
q = q -> st; continue;
}
}

if( strcmp( key, q -> cheie ) > 0 ) // cautarea se face in


subarborele drept
{
if( q -> dr == 0 ) // inserare, deoarece nodul q -> dr
nu exista
{
q -> dr = p; p -> frecventa = 1; return;
}
else // nodul q -> dr exista; trecem la el
{
q = q -> dr; continue;
}
}
} //sfarsit ciclu for; am inserat nodul si actualizat frecventa
}

// functia de parcurgere a arborelui in inordine: recursiv =


subarborele stang, radacina, apoi subarborele drept
void inordine(NOD *p)
{
if( p != 0 )
{
inordine( p -> st);
printf("%s\t%d\n", p -> cheie, p -> frecventa);
inordine( p -> dr );
}
}

int main()
{
char *p;
while( p = citeste_cuvant() )
{
inserare_nod( p );
}
inordine( rad );
return 0;
}

Ex 3.6
/* pr_5_3_6
3.6 Informatiile pentru medicamentele unei farmacii sunt: nume
medicament, pret, cantitate, data primirii, data expirarii.
Evidenta medicamentelor se tine cu un program care are drept
structura de date un arbore de cautare dupa nume medicament.
Sa se scrie programul care executa urmatoarele operatii:
creeaza arborele de cautare;
cauta un nod dupa campul nume medicament si actualizeaza
campurile de informatie;
tipareste medicamentele in ordine lexicografica;
elimina un nod identificat prin nume medicament;
creeaza un arbore de cautare cu medicamentele care au data
de expirare mai veche decat o data specificata de la terminal.
=> nu pot fi 2 medicamente cu acelasi nume; => pentru fiecare
medicament data primirii este aceeasi pentru toata cantitatea,
la fel data expirarii este aceeasi pentru toata cantitatea.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct nod


{
char *nume_medicament; // pointer la numele
medicamentului; aceasta va fi si cheia
double pret; // pretul medicamentului
int cantitate; // cantitatea medicamentului
char data_primirii[9]; // ziua, luna si anul primirii
medicamentului ( 02.11.20 )
char data_expirarii[9]; // ziua, luna si anul expirarii
medicamentului ( 12.01.21 )
struct nod *st; // pointer la nodul fiu din stanga
struct nod *dr; // pointer la nodul fiu din dreapta
} FARM;
FARM *rad = 0, *rad1 = 0; // pointeri la radacina arborelui (initial
si cel cu medicamente expirate)
int ie = 0; // p/u numararea nodurilor cu medicamente expirate
char data[9]; // pentru data de control
FARM *LISTA[25]; // Vector = lista la pointerii nodurilor cu
medicamentul expirat

/* Functia citeste medicamentul si informatia despre el (informatia


p/u 1 nod)
returneaza adresa nodului in care s-a citit informatia;
la EOF returneaza 0
*/
FARM *citeste_medicament()
{
FARM *p; char nm[256];
printf("\nIntroduceti numele medicamentului: ");
scanf("%s", nm); if( feof( stdin ) ) return 0;
p = ( FARM * )malloc( sizeof( FARM ) ); // Alocam memorie p/u
1 nod
p -> nume_medicament = (char *)malloc( sizeof( nm ) );
strcpy(p -> nume_medicament, nm);
printf("\nIntroduceti pretul medicamentului: ");
scanf("%lf", &p -> pret);
printf("\nIntroduceti cantitatea: ");
scanf("%d", &p -> cantitate);
printf("\nIntroduceti data primirii medicamentului: ");
scanf("%s", p -> data_primirii);
printf("\nIntroduceti data expirarii medicamentului: ");
scanf("%s", p -> data_expirarii);
if (compara_2_date_calendaristice(p -> data_primirii, p ->
data_expirarii) >= 0 )
{ printf("Medicamentul este expirat!\n"); return 0; }
return p;
}

// Functia extrage informatia din nodul de cheia r


void extrage_info_nod(FARM *r)
{
printf("\nNume medicament: %s\n", r -> nume_medicament);
printf("Pretul medicamentului: %.2lf\n", r -> pret);
printf("Cantitatea medicamentului: %d\n", r -> cantitate);
printf("Data primirii medicamentului: %s\n", r ->
data_primirii);
printf("Data expirarii medicamentului: %s\n", r ->
data_expirarii);
}

// Functia compara 2 date calendaristice; returneaza -1, daca


data1 < data2,
// returneaza 0, daca data1 == data2, returneaza +1, daca data1 <
data2
int compara_2_date_calendaristice(char *data1, char *data2)
{
int d1, m1, y1, d2, m2, y2;
sscanf(data1, "%2d %*c %2d %*c %2d", &d1, &m1, &y1);
sscanf(data2, "%2d %*c %2d %*c %2d", &d2, &m2, &y2);
if( y1 < y2 ) return -1; if( y1 > y2 ) return +1;
if( m1 < m2 ) return -1; if( m1 > m2 ) return +1;
if( d1 < d2 ) return -1; if( d1 > d2 ) return +1;
return 0;
}

void inserare_nod( FARM *p) // Functia insereaza in arborele cu


radacina rad nodul la care arata pointerul p.
{
FARM *q;
p -> st = 0; p -> dr = 0;
if( rad == 0 ) // Arborele este vid; nu este nici-un nod.
{
rad = p; return;
}
q = rad;
for( ; ; ) // Cautam locul unde poate fi inserat nodul p.
{
if( strcmp( p -> nume_medicament, q ->
nume_medicament) == 0 ) // Nodul p exista deja.
{
q -> cantitate += p -> cantitate; // Marim cantitatea.
return;
}

if( strcmp( p -> nume_medicament, q ->


nume_medicament ) < 0 ) // Cautarea se face in subarborele stang.
{
if( q -> st == 0 ) // Inserare, deoarece nodul q -> st
nu exista.
{ q -> st = p; return; }
else // Nodul q -> st exista; trecem la el.
{ q = q -> st; continue; }
}

if( strcmp( p -> nume_medicament, q ->


nume_medicament ) > 0 ) // Cautarea se face in subarborele drept.
{
if( q -> dr == 0 ) // iIserare, deoarece nodul q -> dr
nu exista.
{ q -> dr = p; return; }
else // Nodul q -> dr exista; trecem la el.
{ q = q -> dr; continue; }
}
} // Sfarsit ciclu for; am inserat nodul si actualizat cantitatea.
}

void inserare_nod_expirat( FARM *p ) // Functia insereaza in


arborele cu radacina rad1 nodul la care arata pointerul p.
{
FARM *q;
p -> st = 0; p -> dr = 0;
if( rad1 == 0 ) // Arborele este vid; nu este nici-un nod.
{ rad1 = p; return; }
q = rad1;
for( ; ; ) // Cautam locul unde poate fi inserat nodul p.
{
if( strcmp( p -> nume_medicament, q ->
nume_medicament ) < 0 ) // Cautarea se face in subarborele stang.
{
if( q -> st == 0 ) // Inserare, deoarece nodul q -> st
nu exista.
{ q -> st = p; return; }
else // Nodul q -> st exista; trecem la el.
{ q = q -> st; continue; }
}

if( strcmp( p -> nume_medicament, q ->


nume_medicament ) > 0 ) // Cautarea se face in subarborele drept.
{
if( q -> dr == 0 ) // Inserare, deoarece nodul q -> dr
nu exista.
{ q -> dr = p; return; }
else // Nodul q -> dr exista; trecem la el.
{ q = q -> dr; continue; }
}
} // Sfarsit ciclu for; am inserat nodul expirat.
}

// Functia de parcurgere a arborelui in inordine; p este radacina.


void inordine( FARM *p )
{ if( p != 0 )
{ inordine( p -> st );
extrage_info_nod( p );
inordine( p -> dr );
}
}
// Parcurgem arborele (initial) cu radacina rad si cautam
medicamentele expirate, pe care le punem in vectorul LISTA[].
void lista_nodurilor_expirate( FARM *p )
{
if( p != 0 )
{
lista_nodurilor_expirate( p -> st );
if( compara_2_date_calendaristice( data, p ->
data_expirarii ) >= 0 )
{
LISTA[ ie ] = (FARM *)malloc( sizeof(FARM) );
LISTA[ ie ] = p;
ie++;
}
lista_nodurilor_expirate( p -> dr );
}
}

// Functia cauta nodul de cheia key in arborele cu radacina rad si


returneaza adresa nodului în caz de gasire
// sau 0 în caz ca nu exista; key este numele medicamentului de
cautat.
FARM *cautare_nod(char *key)
{
FARM *p;
if (rad == 0) // Arborele este vid, nu avem unde cauta.
{
printf("Arborele este vid !\n");
return 0;
}
// Daca arborele nu este vid, cautarea începe din radacina rad.
p = rad;
while (p != 0)
{
if( strcmp( key, p -> nume_medicament ) == 0 ) return p; //
Am gasit nodul.
if( strcmp( key, p -> nume_medicament ) < 0 ) p = p -> st; //
Cautarea se face in subarborele stang.
else p = p -> dr; // Cautarea se face in subarborele drept.
}
printf("\nNu exista nod de cheia key = %s\n", key);
return 0; // Nu exista nod de cheia key.
}

// Functia sterge nodul de cheia key din arborele cu radacina rad.


void sterge_nod( char *key )
{
FARM *p, *tata_p; // p este nodul de sters, iar tata_p este
tatal lui
FARM *nod_inlocuire, *tata_nod_inlocuire; // Nodul care il va
inlocui pe p si tatal sau.
int directie; // st = 1; dr = 2.
if(rad == 0) { printf("Arborele este vid !\n"); return; } //
Arborele este vid, nu avem ce sterge.
p = rad; tata_p = 0;
while( ( p != 0 ) && ( strcmp( p -> nume_medicament, key ) !=0
) ) // Cautam nodul de cheia key.
{
if( strcmp( key, p -> nume_medicament ) < 0 ) // Cautam
in stanga.
{ tata_p = p; p = p -> st; directie = 1; }
else // Cautam in dreapta.
{ tata_p = p; p = p -> dr; directie = 2; }
} // Am terminat cautarea nodului de cheia key.

if( p == 0 ) // Nu exista nod de cheia key.


{ printf("\nNu exista nod de cheia key = %s\n", key); return; }
if( p -> st == 0) nod_inlocuire = p -> dr; // Nodul de sters p nu
are fiu sting.
else
{
if( p -> dr == 0) nod_inlocuire = p -> st; // Nodul de sters
p nu are fiu drept.
else // Nodul de sters p are fiu stang si fiu drept.
{
tata_nod_inlocuire = p;
nod_inlocuire = p -> dr; // Se cauta in subarborele
drept.
while( nod_inlocuire -> st != 0 )
{
tata_nod_inlocuire = nod_inlocuire;
nod_inlocuire = nod_inlocuire -> st;
}
if( tata_nod_inlocuire != p )
{
tata_nod_inlocuire -> st = nod_inlocuire -> dr;
nod_inlocuire -> dr = p -> dr;
}
nod_inlocuire -> st = p -> st;
}
}
printf("\nNodul de cheie = %s care trebuie sters a fost
gasit!\n", key);
free(p);
printf("\nNodul de cheie = %s a fost sters!\n", key);
if( tata_p == 0) rad = nod_inlocuire; // s-a sters chiar radacina
initiala
else
{
if( directie == 1 ) tata_p -> st = nod_inlocuire;
else tata_p -> dr = nod_inlocuire;
}
if( rad == 0 ) printf("Arborele a ramas vid dupa stergere !\n");
}

int main() {
FARM *p; char cheie[] = "med3"; int i;
while( p = citeste_medicament() )
{
inserare_nod( p );
}
inordine( rad );
p = cautare_nod( cheie );
if( p == 0)
{
printf("\nNu exista nod de cheia %s\n", cheie);
}
else
{
extrage_info_nod(p);
}
sterge_nod( cheie );
inordine( rad );
printf("\nIntroduceti data de control: ");
scanf("%s", data);
printf("\ndata de control: %s\n", data);
p = rad;
lista_nodurilor_expirate( p );
p = rad1;
rad1 = 0;
for(i = 0; i < ie; i++)
{
p = LISTA[ i ];
inserare_nod_expirat( p );
}
printf("\nMedicamentele expirate:\n");
inordine( rad1 );
if( rad1 == 0 )
{
printf("Nu exista medicamente expirate.\n");
}

return 0;
}
Laborator 6
/* pr_6_3_1
3.1. Pentru un graf orientat G =(V, E) sa se gaseasca subgraful
indus G' =(V', E'), unde V' este o submultime
de noduri din multimea de noduri V ale grafului G. Elementele
din V si V' se citesc de la tastatura.
E este multimea de arce a grafului G.
*/

#include <stdio.h>
#include <stdlib.h>

int main()
{
/*
Fie graful orientat G are n varfuri, numerotate cu
numerele 0, 1, 2, ..., n - 1.
Notam prin A[n][n] matricea de adiacenta a grafului G.
Atunci A[i][j] = 1,
daca in E exista arcul (i, j), adica arcul de la nodul i spre
nodul j si A[i][j] = 0,
in caz contrar, adica in E nu exista arc de la nodul i spre
nodul j.
n si A[i][j] le introducem de la tastatura.
*/
int n, m, i, j, k, t, r, p, bi, bj;
int A[25][25]; // Matricea de adiacenta a grafului G;
Presupunem ca vor fi nu mai mult de 25 noduri.
int B[25][25]; // Matricea de adiacenta a subrafului G'.
int C[25][25]; // Aici va fi o copie a matricei A.
int V[25]; // Varfurile V'. O submultime de numere din V
(adica din numerele 0, 1, 2, ..., n - 1).

printf("\nIntroduceti numarul de noduri pentru graful G.\nn =


");
scanf("%d", &n); printf("Graful G are %d noduri.\n", n);
printf("\nIntroduceti arcele ( 0 sau 1 ):\n");
for( i = 0; i < n; i++ )
{
for( j = 0; j < n; j++ )
{ printf("A[%d][%d] = ", i, j); scanf("%d", &A[i][j]); C[i][j] =
A[i][j]; }
}
// Am introdus A[][] - matricea de adiacenta a grafului G.
Graful este "construit". C[][] este o copie a matricei A[][].

printf("\nIntroduceti numarul de noduri pentru subgraful


G'.\nm = ");
scanf("%d", &m); printf("Subgraful G' are %d noduri.\n", m);
printf("Introduceti numerele nodurilor (numere din multimea
0, 1, 2, ..., n - 1), care vor fi in subraful G':\n");

for(i = 0; i < m; i++) { printf("V[%d] = ", i); scanf("%d", &V[i]); }


printf("In subraful G' vor ramane nodurile cu numerele din
G:\n");
for(i = 0; i < m; i++) { printf("%d\t", V[i]); } printf("\n\n");

// Construim matricea B[m][m] - matricea de adiacenta a


subrafului G'.
for(i = 0; i < n; i++) // linia i o facem -1, daca nu-i printre
nodurile ce raman...
{
p = 0;
for(r = 0; r < m; r++)
{ if( i != V[r] ) { p++; }
if( p == m ) for(j = 0; j < n; j++) { C[i][j] = -1; } }
}

for(j = 0; j < n; j++) // coloana j o facem -1, daca nu-i printre


nodurile ce raman...
{
p = 0;
for(r = 0; r < m; r++)
{ if( j != V[r] ) { p++; }
if( p == m ) for(i = 0; i < n; i++) { C[i][j] = -1; } }
}

bi = 0; // bi va fi indicele pentru liniile matricei B[][].


for(i = 0; i < n; i++)
{
k = 0;
for(j = 0; j < n; j++)
{ if( C[i][j] == -1) { k += 1; } }
if( k == n ) { continue; }
bj = 0; // bj va fi indicele pentru coloanele matricei B[]
[].
for(t = 0; t < n; t++)
{ if( C[i][t] != -1 ) { B[bi][bj] = C[i][t]; bj += 1; } }
bi +=1;
}

for(i = 0; i < n; i++)


{
for(j = 0; j < n; j++)
{ printf("C[%d][%d] = %d\t", i, j, C[i][j]); }
printf("\n");
}

printf("\n");
for(i = 0; i < m; i++)
{
for(j = 0; j < m; j++)
{ printf("B[%d][%d] = %d\t", i, j, B[i][j]); }
printf("\n");
}

return 0;
}

Ex 6.2
/* pr_6_3_2_cu_liste_de _adiacenta
3.2. Sa se scrie cate o functie de construire pentru un graf G
=(V, E),
conform celor 3 reprezentari posibile.

Fie multimea V contine n varfuri ( noduri ), le notam prin 0, 1,


2, ..., n - 1.
Multimea E este multime de arce. Fie ea consta din m arce, le
notam prin 0, 1, 2, ..., m - 1.

Matricea de incidenta sau matricea varfuri-arce (noduri-arce)


este o matrice B[n][m].
Un element b[i][j] al matricei are valoarea 1, daca varful i este
extremitate initiala
pentru arcul (i, j), valoarea 0, daca varful i nu este niciun fel
de extremitate si
valoarea -1, daca varful i este extremitate finala pentru arcul
respectiv.
*/

#include <stdio.h>
#include <stdlib.h>

typedef struct nod


{
int nd; // Nr. nodului.
struct nod *urm; // Pointer la un nod adiacent(spre care este
arc).
} LA;
LA *L[25]; // L este un vector de 25 pointeri (pointeri la listele de
adiacenta).

int **f1(int m) // Functia construieste matricea A[m][2] cu cele m


arce ale grafului.
{
int i; int **A; // A este pointer pentru matricea cu cele m arce
ale grafului.
// Alocam memorie pentru multimea de arce E a grafului G =
(V,E).
A = (int **)malloc(m * sizeof(int)); // Alocam memorie pentru
cele m linii(arce) ale matricei A.
for(i = 0; i < m; i++) // Alocam memorie pentru cele m linii ale
matricei A.
{
// Alocam memorii pentru linia i a matricei A adica
pentru cele 2 extremitati(varfuri) ale arcului i.
A[i] = (int *)malloc(2 * sizeof(int));
}
// Introducem arcile grafului G (multimea E).
printf("Introduceti elementele multimii E, adica arcile grafului
G : \n");
for(i = 0; i < m; i++)
{
printf("Arcul %d : ", i);
scanf("%d %d", &A[i][0], &A[i][1]);
printf("Ati introdus arcul %d : (%d, %d)\n", i, A[i][0], A[i]
[1]);
} // Am introdus E - Multimea arcelor grafului G.
return A;
}

int **f2(int n, int m) // Functia construieste matricea de incidenta


B[n][m].
{
int i,j,k;
int **A, **B;
B = (int **)malloc(n * sizeof(int *)); // Alocam memorie pentru
cele n linii ale matricei de incidenta.
for(i = 0; i < m; i++)
{
B[i] = (int *)malloc(m * sizeof(int)); // Aici alocam memorie
pentru cele m elemente ale liniei i din matricea B.
}
A = f1(m); // Am construit matricea A[m][2] - cele m arce ale
grafului.
// Acum sa construim matricea de incidenta (Matricea varfuri-
arce) - B[n][m].
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
B[i][j] = 0;
for(k = 0; k < m; k++)
{
if(i == A[k][0])
{
B[i][k] = 1;
}
else
{
if(i == A[k][1])
{
B[i][k] = -1;
}
else
{
B[i][k] = 0;
}
}
}
}
}
return B;
}

void f3(int n, int m, int **C) // Functia extrage la ecran matricea


C[n][m].
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
printf("%d\t", C[i][j]);
}
printf("\n");
}
printf("\n");
}

int main()
{
int n,m,i,j,k;
int **B; // Pointerul B este pentru matricea de incidenta.
int **A; // Pointerul A este pentru matricea de adiacenta.
printf("Introduceti Nr. de noduri pentru graful G : n = ");
scanf("%d", &n);
printf("Graful G are n = %d noduri.\n", n);
printf("Introduceti Nr. de arce ale grafului G : m = ");
scanf("%d", &m);
printf("Graful G are m = %d arce.\n", m);

B = f2(n,m); // Am construit matricea de incidenta.


f3(n,m,B); // Am extras la ecran matricea de incidenta B[n]
[m].

A = g1(n); // Am construit matricea de adiacenta.


return 0;
}

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