Sunteți pe pagina 1din 40

Structuri de Date și Algoritmi

- Introducere și Recapitulare - Partea I –

Conf. univ. Dr. Ing. Victor ASAVEI


victor.asavei@cs.pub.ro
As. univ. drd. Ing. Ana-Maria Țugulea
ana_maria.tugulea@upb.ro
Obiective
• Modelarea datelor folosind tipurile fundamentale:
liste, stive, cozi, arbori și grafuri

• Proiectarea de algoritmi pentru rezolvarea de


probleme tipice

• Dezvoltarea de aplicații în limbajul C ce folosesc


tipurile de date fundamentale: liste, stive, cozi,
arbori și grafuri

• Testarea și depanarea programelor dezvoltate

1
Administrativ
• Curs
– Sincron pe MS Teams: susținere curs
– Asincron pe Moodle: suport curs în format electronic

• Laborator
– Sincron pe MS Teams:
• rezolvare sarcini laborator
• se va folosi limbajul C și mediul de dezvoltare CodeBlocks
– Asincron pe Moodle:
• suport laborator în format electronic (schelet cod + document
sarcini de realizat)
• activități de încărcare (”assignments”) pentru sarcinile fiecărui
laborator

2
Notare la disciplina SDA
• Punctaj și evaluare
– 2 puncte activitate laborator:
• realizarea sarcinilor de lucru în cadrul fiecărui laborator
• încărcarea pe Moodle în cadrul unei activități dedicate pentru fiecare
laborator a rezolvării sarcinilor de lucru
– 2 puncte Quiz-uri pe Moodle:
• 2 Quiz-uri
• întrebări tip grilă cu un singur răspuns corect
• 1 Quiz se poate da de 2 ori
– 3 puncte proiect despre o structură de date/algoritm:
• temă aleasă dintr-o listă de subiecte (se pot propune și alte teme)
• echipe de maxim 3 persoane
• Încărcare pe Moodle în cadrul unei activități dedicate
– 3 puncte examen:
• examen fizic la sediul facultății
• tip grilă
– Total punctaj: 10 puncte
Cuprins
• Noțiuni introductive
– structuri de date fundamentale
– clasificare generală structuri de date

• Recapitulare noțiuni fundamentale limbajul C


– tipuri de bază
– funcții
– transmitere parametri prin valoare/referință
– înregistrări
– vectori
– pointeri
– alocare dinamică memorie
– recursivitate
4
Cuprins
• Eficiența structurilor de date și algoritmilor

• Tablouri unidimensionale și bidimensionale


– alocare dinamică tablouri
– exemple algoritmi cu vectori și matrici

• Liste
– liste simplu înlănțuite
– liste dublu înlănțuite

HEAD NULL

INFO INFO INFO

5
Cuprins
• Stive TOP

NULL

• Cozi

HEAD TAIL NULL

1 2 3 4

6
Cuprins
• Algoritmi de căutare și sortare
– căutarea binară
– sortarea prin metoda bulelor (bubblesort)
– sortarea prin inserție (insertion sort)
– sortarea prin selecție (selection sort)
– sortarea prin interclasare (merge sort)

7
Cuprins
• Arbori
– arbori binari
– parcurgerea arborilor

(a+b)*c+7
8
Cuprins
• Grafuri
– orientate
– neorientate

9
Bibliografie și resurse utile (1)
• Cărți
– Kernighan B., Ritchie D., The C Programming Language,
Ed. Prentice Hall
– Cormen T.H, Leiserson C.E, Rivest R.L, Introducere în
algoritmi, (traducere a primei ediții), Ed. Agora, 2000
– Moraru F., Structuri de date și algoritmi, Ed. Bren
– Sedgewick R., Wayne K., Algorithms, Ed. Addison-
Wesley, Professional, 4th Edition

10
Bibliografie și resurse utile (2)
• Resurse utile online
– CodeBlocks IDE: http://www.codeblocks.org/
– Vizualizarea structurilor de date și algoritmilor prin animație:
https://visualgo.net/en
– Vizualizarea structurilor de date:
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
– Repository de rezolvări de probleme și descriere implementări
algoritmi: https://infoarena.ro/
• Platforma Moodle de eLearning a cursului
– Curs Structuri de date și algoritmi:
https://curs.upb.ro/2021/course/view.php?id=7840
• Platforma MS Teams
– Curs Structuri de date și algoritmi: link direct 11
Structuri de date fundamentale (1)
• De ce structuri de date
– rezolvarea unei probleme presupune: reprezentarea
datelor problemei, modalități de transformare a datelor
problemei, soluție cu un criteriu de succes / finalizare

• Structuri de date
– gruparea / organizarea datelor pentru a le accesa în mod
eficient
– prima structură de date: vector
– matrice (vector de vectori în limbajul C)
– gruparea în entități de tip înregistrare (”struct” în limbajul
C): liste înlănțuite (Linked Lists), arbori

12
Structuri de date fundamentale (2)
• Exemple structuri de date în limbajul C
int vec[100];
int mat[100][100];
struct persoana
{
char *nume;
char *prenume;
};
struct element
{
char *informatie;
struct element *urmator;
};

13
Structuri de date fundamentale (3)
• Structuri de date fundamentale în C
– vectori
– pointeri
– structuri

• Structuri de date fundamentale independent de


limbaj
– vectorii, listele înlănțuite, arborii
– celelalte structuri de date prin combinația celor anterioare
– exemplu, reprezentarea unui graf
• prin matrice de adiacență
• prin liste de adiacență (vectori de pointeri la liste înlănțuite)

14
Structuri de date fundamentale (3)
• Reprezentarea unui graf orientat prin

15
Clasificare generală structuri de date
• Structurile de date pot fi caracterizate prin:
– relațiile dintre elementele structurii de date
– operațiile cu elementele structurii de date
• În funcție de relațiile dintre elemente
– structuri de date liniare: tablouri, liste, stive, cozi
– structuri de date neliniare
• structuri de date ierarhice sub formă de arbore în care un element
poate avea mai mulți succesori dar un singur predecesor
• structuri de date de tip graf în care un element poate avea mai
mulți predecesori și mai mult succesori
• În funcție de operațiile cu elemente
– structuri de căutare (mulțimi, dicționare, arbori de căutare,
etc.), structuri de stocare (liste, stive, cozi, etc.), etc.
16
Structuri de date abstracte
• O structură de date abstractă reprezintă descrierea logică a
organizării datelor și definirea operațiilor de bază a utilizării
acestora
• Se realizează abstractizarea operațiilor de bază fără a se
preciza modul concret de implementare (limbaj de programare,
alocare statică sau dinamică a elementelor, etc.)
– Exemple:
• push(stiva, element)
• pop(stiva, element)
• enqueue(coada, element)
• dequeue(coada, element)
• Etape dezvoltare program
– etapă de proiectare: alegere structuri abstracte de date
– etapă de implementare: implementarea concretă a structurilor de
date prin scrierea de cod
17
Ce este un algoritm
• Conceptul de algoritm există și a fost folosit încă din
antichitate
– împărțirea a două numere întregi
– ciurul lui Eratostene
– algoritmul lui Euclid pentru calculul celui mai mare divizor
comun
• Termenul de algoritm
– provine de la numele lui Muhammad ibn Musa al-
Khwarizmi (matematician persan din secolul 9)
– o secvență de pași, bine definită, cu o finitudine și
finalitate practică pentru rezolvarea unei probleme sau a
unei categorii de probleme

18
Recapitulare noțiuni limbaj C (1)
• Tipuri de date
– tipuri de date de bază: tipuri de date aritmetice
• întregi (”integer”)
• virgulă mobilă (”floating-point”)
– tipuri de date derivate
• vectori
• pointeri
• structuri
• funcții
– tipul enumerare
– tipul void

19
Recapitulare noțiuni limbaj C (2)
• Tipuri de date de bază întregi
Tip Dimensiune maximă Interval valori
char 1 octet
(8 biți)
unsigned char 1 octet
(8 biți)
short 2 octeți
(16 biți)
unsigned short 2 octeți
(16 biți)
int 4 octeți
(32 biți)
unsigned int 4 octeți
(32 biți)
long 8 octeți
(64 biți)
unsigned long 8 octeți
(64 biți)
• Pentru obținerea dimensiunii unui tip sau variabile (dependentă de
platformă): sizeof(tip)
20
Recapitulare noțiuni limbaj C (3)
• Exemplu citire variabilă int și afișare valoare și
dimensiune tip
#include <stdio.h>
#include <stdlib.h>

int main()
{
int a;

printf("Introduceti o valoare intreaga:");


scanf("%d", &a);

printf("Variabila are valoarea %d iar dimensiunea tipului este de %d octeti\n", a,


sizeof(a));
return 0;
}

Output:
Introduceti o valoare intreaga:10
Variabila are valoarea 10 iar dimensiunea tipului este de 4 octeti

21
Recapitulare noțiuni limbaj C (4)
• Tipuri de date de bază reale (reprezentate în virgulă mobilă)

Tip Dimensiune Interval valori Precizie


float 4 octeți [1.17549e-038, 3.40282e+038] 6 zecimale
(32 biți)
double 8 octeți [2.22507e-308, 1.79769e+308] 15 zecimale
(64 biți)
long minim 10 octeți dependent de platformă și compilator 19 zecimale
double (80 biți)

• Similar ca la tipurile de date întregi, pentru obținerea dimensiunii unui tip


sau variabile (dependentă de platformă): sizeof(tip)

22
Recapitulare noțiuni limbaj C (5)
• Exemplu citire variabilă double și afișare valoare și
dimensiune tip
#include <stdio.h>
#include <stdlib.h>
int main()
{
double b;

printf("Introduceti o valoare de tip double:");


scanf("%lf", &b);

printf("Variabila are valoarea %lf iar dimensiunea tipului este de %d octeti\n", b,


sizeof(b));

return 0;
}
Output:
Introduceti o valoare de tip double:1.2
Variabila are valoarea 1.200000 iar dimensiunea tipului este de 8 octeti

23
Recapitulare noțiuni limbaj C (6)
• Tipul void: reprezintă practic absența unei valori
– Este folosit în următoarele cazuri uzuale:
• ca valoare întoarsă de o funcție: o funcție care nu produce nicio
ieșire va întoarce void
– Exemplu: void afiseaza_nume(char nume[10]);
• daca o funcție nu are nevoie să primească parametri
– Exemplu: int initializare(void);
• ca pointer la void: un pointer de tip * void va reprezenta o adresa
din memorie însă fără a avea asociat un tip. În acest fel se poate
face cast la orice tip de date necesar a fi folosit în funcție de
situație. Exemplu când se vor prezenta pointerii

24
Recapitulare noțiuni limbaj C (7)
• Funcții
– grupare logică a unui număr de instrucțiuni
– orice program C are cel puțin funcția main()
– pentru lizibilitate cod și modularizare este de dorit de
împărțit codul în funcții separate ce pot fi apelate mai ales
în cazul în care codul din corpul unei funcții devine prea
mare și dacă se repetă în cadrul aceleiași funcții calupuri
de cod similare
– o funcție are:
• declarație: precizează numele funcției, tipul returnat de funcție
și parametrii primiți de funcție
• definiție: alături de nume, tip returnat și parametri conține și codul
propriu-zis al funcției

25
Recapitulare noțiuni limbaj C (8)
• Declarația unei funcții
– Este alcătuită dintr-un header (antet) și are forma:
tip_returnat nume_functie(lista parametri);
– Conține:
• tip de date returnat: o funcție poate să întoarcă o valoare sau nu (atunci
va întoarce void)
• nume funcție
• parametri: lista parametrilor identificați prin tip și nume în ordinea dorită;
la apelul funcției se vor trimite valorile propriu-zise ale parametrilor; nu
este obligatoriu ca o funcție să aibă parametri (pot să lipsească)
• corpul funcției: codul propriu-zis al instrucțiunilor executate de funcție
– În C se poate separa declarația de codul propriu-zis al acesteia
(definiția). Astfel pentru ca o funcție să fie folosită este de ajuns să fie
declarată înainte de codul care o apelează și definiția acesteia să fie
făcută ulterior în cod (fișierul sursă curent sau alt fișier sursă parte din
program)
• Exemplu:
void afiseaza_semn_numar(int numar);
26
Recapitulare noțiuni limbaj C (9)
• Definirea unei funcții
– Este alcătuită dintr-un header (antet) al funcției și corpul
funcției și are forma:
tip_intors nume_functie(lista parametri)
{
corpul functiei
}
– Conține:
• tip de date returnat, nume funcție și parametri: similari ca cei de la
declarație
• corpul funcției: codul propriu-zis al instrucțiunilor executate de funcție

void afiseaza_semn_numar(int numar)


{
if (numar < 0)
printf("Numarul %d este negativ\n", numar);
else
printf("Numarul %d este pozitiv\n", numar);
}
27
Recapitulare noțiuni limbaj C (10)
• Apel funcții
– Pentru a se folosi o funcție aceasta trebuie să fie apelată
– Când se apelează o funcție, controlul programului este dat funcției apelate iar
controlul este redat înapoi când funcția s-a terminat (s-a executat return în
funcție sau s-a ajuns la sfârșitul acesteia)
void verifica_nota_student(int nota)
{
switch (nota)
{
case 1:case 2:case 3:case 4:
printf("Nota %d nu este o nota care sa permita promovarea\n", nota);break;
case 5:case 6:case 7:case 8:case 9:
printf("Nota %d este o nota care permite promovarea\n", nota);break;
case 10:
printf("Nota %d este o nota care permite promovarea. Felicitari pentru nota maxima !\n",
nota);break;
default:
printf("Nota %d nu este o nota valida\n", nota);
}
}
int main()
{

verifica_nota_student(8);
}
Output:
Nota 8 este o nota care permite promovarea
28
Recapitulare noțiuni limbaj C (11)
• Transmitere parametri: la apelul unei funcții se
transmit parametrii acesteia iar dacă funcția
întoarce o valoare se poate utiliza această valoare
– transmitere parametri prin valoare: se fac copii ale
variabilelor primite de funcție și orice modificare în cadrul
funcției va folosi aceste copii (nu se modifică variabilele
inițiale din codul apelant); astfel dacă se dorește a se
prelua o modificare asupra unei variabile în cadrul funcției
se poate folosi return și funcția să întoarcă valoarea
modificată dacă se dorește acest lucru
– transmitere parametri prin referință: copiază adresele
variabilelor și astfel se pot modifica direct acestea în
funcție; exemplu când se vor prezenta pointerii

29
Recapitulare noțiuni limbaj C (12)
• Exemplu transmitere parametri prin valoare
void suma_doua_numere_varianta_1(int numar1, int numar2, int suma)
{
suma = numar1 + numar2;
return;
}
int suma_doua_numere_varianta_2(int numar1, int numar2)
{
int suma;
suma = numar1 + numar2;
return suma;
}
int main()
{
int suma = 0;int numar1 = 3;int numar2 = 2;

suma_doua_numere_varianta_1(numar1, numar2, suma);


printf("Varianta1: Suma numerelor %d si %d este %d\n", numar1, numar2, suma);

suma = suma_doua_numere_varianta_2(numar1, numar2);


printf("Varianta2: Suma numerelor %d si %d este %d\n", numar1, numar2, suma);
return 0;
}
Output:
Varianta1: Suma numerelor 3 si 2 este 0
Varianta2: Suma numerelor 3 si 2 este 5
30
Recapitulare noțiuni limbaj C (13)
• Tipul Enumerare
– se pot defini nume particularizate pentru valori numerice întregi
– definire (ce este între [] este opțional):
enum [nume_enumerare] { Identificator1 [= valoare], Identificator2 [= valoare], …}
[variabila1,variabila2,..];
Exemplu:
enum luni_an { Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie };
enum luni_an luna;
// SAU
//enum luni_an {Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie} luna;
// SAU
//enum {Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie } luna;
enum sporturi { Fotbal = 1, Baschet = 5, Volei = 7 };
enum sporturi sport;
int main()
{
sport = Baschet;
printf("Sportul cu numele 'Baschet' are valoarea %d\n", Baschet);
printf("Lunile din an:");
for (int i = Ianuarie; i <= Decembrie; i++)
printf("%d ", i);
}
Output:
Sportul cu numele 'Baschet' are valoarea 5
Lunile din an:0 1 2 3 4 5 6 7 8 9 10 11
31
Recapitulare noțiuni limbaj C (14)
• Înregistrări folosind struct și typedef
• Structuri: tipuri de date ce permit gruparea de
variabile de tipuri
• Definire:
struct [nume_structura]
{
Membru1,
Membru2,
...
} [variabila1,variabila2,..];
Exemplu:
struct student
{
char prenume[20];
char nume[20];
int an;
};

struct student s1 = { "John","Doe",1 };


32
Recapitulare noțiuni limbaj C (15)
• Se poate trimite ca parametru al unei funcții o structură similar ca
orice variabilă sau pointer
void afiseaza_student(struct student s);
• Accesarea unui membru al structurii se face folosind operatorul ”.”
struct student s2;
strcpy(s2.prenume, "Gheorghe");
strcpy(s2.nume, "Popescu");
• Se pot asigna nume simbolice unor tipuri de date predefinite sau
unor tipuri de date definite de utilizator folosind typedef
typedef tip_date nume_simbolic;
Exemplu:
typedef unsigned char OCTET;
OCTET a;

typedef struct student


{
char prenume[20];
char nume[20];
int an;
} STUDENT;
STUDENT s1 = { "John","Doe",1 };

33
Recapitulare noțiuni limbaj C (16)
• Exemple de utilizare:
typedef struct
{
int X; int Y;
} S1; // typedef pentru numele S1, se poate utiliza numele 'S1'

struct S2
{
int X; int Y;
}; // este un typedef pentru struct S2, se poate utiliza ca 'struct S2'

struct
{
int X; int Y;
} S3; // se declara variabila S3, fara tip; se poate utiliza doar ca variabila S3

typedef struct S4
{
int X; int Y;
} S4; // typedef pentru numele S4 cat si pentru struct S4; se poate utiliza numele 'S4’
// cat si 'struct S4’
int main()
{
S1 val1; // CORECT
struct S2 val2; // CORECT
S2 val3; // INCORECT
S3 val4; // INCORECT
struct S4 val5; // CORECT
S4 val6; // CORECT

}
return 0;
34
Recapitulare noțiuni limbaj C (17)
• Vectori (tablou uni-dimensional): un vector este o
colecție liniară de variabile de același tip
• Elementele dintr-un vector pot fi accesate în mod
unic printr-un index specific
• Indexul este un număr întreg pozitiv
• Indexarea în limbajul C începe cu valoarea 0
• Declarația unui vector:
tip nume_vector [dimensiune_vector];
dimensiune_vector: o constantă întreagă mai mare decât 0
Exemple:
int a[10];
float b[10];
#define NUM_ELEM 10
int c[NUM_ELEM];

35
Recapitulare noțiuni limbaj C (18)
• Dimensiunea vectorilor o constantă la compilare
pentru a se putea aloca memoria necesară
• Valorile unui vector se pot inițializa una câte una
sau direct la declararea vectorului:
int a[4] = { 1,2,3,4 }; // Initializare completa
float b[] = { 0.1, 0.2,0.3 }; // La compilare se determina dimensiunea de 4 a
// vectorului
int c[10] = { 1,2,3,4 }; // Se initializeaza doar primele 4 valori

• Atenție, elementele neinițializate pot avea valori


oarecare și deci programatorul trebuie să aibă grijă
să facă inițializarea corectă
• Accesarea unui element se face prin
nume_vector[index]
Exemple:
int a[10];
a[1] = 3;
a[2] = 5;
36
Recapitulare noțiuni limbaj C (19)
• Exemplu simplu lucru cu vectori
#include <stdio.h>
#include <stdlib.h>

int main()
{
int a[10]; // vectorul va avea maxim 10 elemente
int numar_elemente; // numarul de elemente din vector

printf("Introduceti numarul de elemente al vectorului:");


scanf("%d", &numar_elemente); // citeste de la tastatura numarul de elemente

if (numar_elemente > 10) // daca numarul de elemente mai mare decat maximul
{
printf("Ati introdus un numar de elemente prea mare pentru vector\n");
return 0;
}

for (int i = 0; i < numar_elemente; i++) // citeste element cu element


{
printf("Introduceti elementul [%d] din vector:", i + 1);
scanf("%d", &a[i]);
}

printf("Vectorul are urmatoarele elemente:");


for (int i = 0; i < numar_elemente; i++) // afiseaza elemente vector
printf("%d ", a[i]);

return 0;
}
Output:
Introduceti numarul de elemente al vectorului:2
Introduceti elementul [1] din vector:1
Introduceti elementul [2] din vector:5
Vectorul are urmatoarele elemente:1 5
37
Recapitulare noțiuni limbaj C (20)
• Matrice (tablou bi-dimensional): o matrice este o colecție
bi-dimensională de variabile de același tip
• Elementele dintr-o matrice pot fi accesate în mod unic
folosind doi indecși specific, pozitivi, începând de la 0
• Declarația unei matrice:
tip nume_matrice [dimensiune_1][dimensiune_2];
dimensiune_1, dimensiune_2: constante întregi mai mari decât 0
de obicei, dimensiune_1 = numărul de linii, dimensiune_2 = numărul de coloane
Exemple:
int a[10][10];
float b[10][10];
#define NUM_ELEM 10
int c[NUM_ELEM][NUM_ELEM];

• Accesarea unui element se face prin


nume_matrice[index_linie] [index_coloana]
Exemple:
int a[10][10];
a[1][2] = 3;
a[2][0] = 5;
38
Recapitulare noțiuni limbaj C (21)
• Exemplu simplu lucru cu matrice
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[10][10]; // matricea va avea maxim 10x10 elemente
int n; // numarul de linii si coloane (va fi egal, matrice patratica)

printf("Introduceti numarul de linii si coloane al matricei:");


scanf("%d", &n); // citeste de la tastatura numarul de linii si coloane

if (n > 10) // daca numarul de linii si coloane mai mare decat maxim
{
printf("Ati introdus un numar de linii si coloane prea mare pentru matrice\n");
return 0;
}

for (int i = 0; i < n; i++) // citeste element cu element


for (int j = 0; j < n; j++)
{
printf("Introduceti elementul [%d][%d] din matrice:", i + 1, j + 1);
scanf("%d", &a[i][j]);
}
// afiseaza elemente matrice
printf("Matricea are urmatoarele elemente:");
for (int i = 0; i < n; i++)
{ Introduceti numarul de linii si coloane ale matricei:2
printf("\n"); Introduceti elementul [1][1] din matrice:1
for (int j = 0; j < n; j++) Introduceti elementul [1][2] din matrice:2
printf("%d ", a[i][j]); Output: Introduceti elementul [2][1] din matrice:3
} Introduceti elementul [2][2] din matrice:4
Matricea are urmatoarele elemente:
return 0; 1 2
} 3 4 39

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