Sunteți pe pagina 1din 41

UMFST „G.E.P.” Tg.

Mureș

Grif Horațiu Ștefan

Structuri de date și algoritmi


Notițe de curs
Pentru uzul studenților

2022

0
1
Cuprins
NOȚIUNI INTRODUCTIVE ................................................................................................................................ 4

NOȚIUNI DE C/C++ ................................................................................................................................................ 4


Variabila simplă ............................................................................................................................................ 4
Tabloul .......................................................................................................................................................... 4
Structura ....................................................................................................................................................... 5
Pointerul ....................................................................................................................................................... 6
ALGORITMUL ........................................................................................................................................................ 8

LISTE ÎNLĂNȚUITE ........................................................................................................................................... 9

1. INTRODUCERE.................................................................................................................................................... 9
2. LISTA SIMPLU ÎNLĂNȚUITĂ .................................................................................................................................... 9
2.1 Introducere ............................................................................................................................................. 9
2.2 Crearea listei simplu înlănțuite ............................................................................................................. 10
2.3 Inserarea unui nod în lista simplu înlănțuită ........................................................................................ 11
2.3.1 Inserarea unui nou nod la începutul listei simplu înlănțuite .......................................................................... 11
2.3.2 Inserarea unui nou nod la sfârșitul listei simplu înlănțuite (Var. 1) ............................................................... 12
2.3.3 Inserarea unui nou nod la sfârșitul listei simplu înlănțuite (Var. 2) ............................................................... 13
2.3.4 Inserarea în interiorul listei simplu înlănțuite după un nod specificat........................................................... 14
2.3.5 Inserarea în interiorul listei simplu înlănțuite înaintea unui nod specificat ................................................... 16
2.4. Parcurgerea unei liste simplu înlănțuite .............................................................................................. 17
2.5. Ștergerea unui nod din lista simplu înlănțuită ..................................................................................... 18
2.5.1 Ștergerea la începutul listei simplu înlănțuite (ștergerea primului nod din listă) .......................................... 18
2.5.2 Ștergerea la sfârșitul listei simplu înlănțuite (ștergerea ultimului nod din listă) ........................................... 19
2.5.3 Ștergerea în interiorul listei simplu înlănțuite ............................................................................................... 20
3. LISTA DUBLU ÎNLĂNȚUITĂ ................................................................................................................................... 21
3.1 Introducere ........................................................................................................................................... 21
3.2 Crearea listei dublu înlănțuite .............................................................................................................. 22
3.3 Inserarea unui nod în lista dublu înlănțuită.......................................................................................... 24
3.3.1 Inserarea unui nod la începutul listei dublu înlănțuite .................................................................................. 24
3.3.2 Inserarea unui nod la sfârșitul listei dublu înlănțuite..................................................................................... 25
3.3.3 Inserarea unui nod în interiorul listei dublu înlănțuite .................................................................................. 25
3.4 Parcurgerea listei dublu înlănțuite ....................................................................................................... 27
3.4.1 Parcurgerea directă a listei dublu înlănțuite .................................................................................................. 28
3.4.2 Parcurgerea inversă a listei dublu înlănțuite ................................................................................................. 28
3.5 Ștergerea unui nod din lista dublu înlănțuită ....................................................................................... 28

2
3.5.1 Ștergerea la începutul listei dublu înlănțuită (ștergerea primului nod din listă)............................................ 29
3.5.2 Ștergerea la sfârșitul listei dublu înlănțuită (ștergerea ultimului nod din listă) ............................................. 31
3.5.3 Ștergerea în interiorul listei dublu înlănțuită ................................................................................................. 32

COADA (QUEUE) ........................................................................................................................................... 33

STIVA (STACK)............................................................................................................................................... 36

ARBORI BINARI ............................................................................................................................................. 38

3
Noțiuni introductive

Noțiuni de C/C++
Variabila simplă
O variabilă este o locație de memorie utilizată pentru a stoca o valoare care poate fi modificată
prin program.[Schildt1995] Cu alte cuvinte putem spune ca unei variabile ii sunt atașate un nume, un
tip de dată predefinit sau definit de utilizator, o zona de memorie (a cărei dimensiune depinde de
tipul de dată) iar valoarea salvata în zona de memorie atașată poate fi modificată în timpul execuției
programului.
Forma generală de declarare a unei variabile este:
tip nume_variabila;

unde
- tip reprezintă tipul de dată al variabilei;
- nume_variabila – numele variabilei.
Exemplu
int x; //variabila x de tip int (întreg cu semn)
char a; //variabila a de tip char (caracter)
float y ; //variabila z de tip float (număr real în virgulă mobilă simplă precizie)
double z; //variabila z de tip double (număr în virgulă mobilă real dublă precizie)
Pentru determinarea dimensiunii în număr de octeți a unei variabile se realizează cu ajutorul
operatorului unar sizeof.
Exemplu
cout << “Dimensiunea lui y: ” <<sizeof(y)<< “ octeti.”;

pe ecran va fi afișat mesajul:


Dimensiunea lui y: 4 octeti.

Tabloul
Un tablou este un ansamblu de variabile de același tip la care se face referire folosindu-se
același nume. Un anume element din tablou este indicat prin intermediul unui indice. [Schildt1995]
Forma generală de declarare a unui tablou unidimensional este:
tip nume_variabila[dimensiune];

unde
- tip reprezintă tipul de dată al variabilei;
- nume_variabila – numele variabilei;

4
- dimensiune reprezintă numărul de elemente ale tabloului.
Exemplu
int t[10]; //declaratia unui tablou de 10 întregi
float media[5]; //declaratia unui tablou cu 5 elemente de tipul float

Structura
O structura este un ansamblu de variabile (nu neaparat de acelasi tip) la care se face referire
cu un singur nume. Astfel, structura reprezintă un mijloc confortabil de a menține la un loc informații
din aceeași sfera [Schildt1995] (de ex o lista de corespondență care conține nume, adresă, telefon se
poate implementa foarte convenabil folosind structuri de date). Variabilele care alcătuiesc o structura
sunt denumite membrii sau elemente sau câmpuri. Pentru crearea unei structuri în C/C++ se folosește
cuvântul cheie struct.
Forma generala de declarare a unei tip de data utilizator de tip structura:
struct eticheta{
tip1 variabila1;
tip2 variabila2;
……………………..
};
Forma generala a unei variabile:
struct eticheta nume_variabila;

unde:
struct eticheta – tipul de data utilizator definit mai sus
nume_variabila – numele variabilei
Exemplul 1
Definirea unei structuri de date pentru definirea tipului de data utilizator student pentru
declararea de variabile pentru stocarea unor informații specifice studenților. Structura va avea cinci
câmpuri pentru memorarea: numelui, prenumelui, secției, anului de studiu si media unui student.
După definirea structurii student se vor declara două variabile: una simplă numită s1 și una de tip
tablou unidimensional cu 11 elemente, tabloul având cu numele listaETI.
struct student {
char nume[25];
char prenume[25];
char sectia[6];
int anul;
float media;
};
struct student s1,listaETI[11];

5
Pointerul
Un pointer este o variabilă care conține o adresă de memorie. Această adresă reprezintă locația
unui alt obiect (cel mai adesea o altă variabilă) din memorie. De exemplu, dacă o variabilă conține
adresa unei alte variabile prima variabilă se zice că indică (engl. point) către cealaltă. [Schildt1995]
Forma generală de declarare a unui pointer este:
tip *nume_variabila;

unde
- tip reprezintă tipul de bază al pointerului (poate fi orice tip de variabilă din C);
- nume_variabila – numele variabilei pointer;
Exemplu
1 int *p;
2 int x=10;
3 p=&x;
4 cout<<x<<endl;
5 cout<<*p<<endl;
În linia 1 s-a declarat pointerul p cu tipul de baza int.
În linia 2 s-a declarat o variabila x de tipul int care s-a inițializat cu valoarea “10”. Presupunem
ca variabila x se află la adresa de memorie “1050”.

În urma execuției liniei 3 variabila pointer p va primi ca valoare adresa variabilei x, operatorul
& este operatorul “adresă” (adresa lui……).
Execuția liniei 4 determină afișarea conținutului variabilei x folosind chiar valabila însăși.
Linia 5 de program este o alternative la linia 4, adică se afișează valoarea variabilei x folosind
pointerul p și operatorul de dereferențiere *.
* si & sunt operatori unari, adică se aplică unui singur operand.
&x = adresa lui x.

6
*p = valoarea de la adresa memorată în pointerul p.
Daca în p este memorată adresa de memorie “1050” => *p este valoarea memorată la adresa
1050.
Observație
Tipul de bază al pointerului definește tipul de variabile care pot fi indicate prin acel pointer.
Tehnic vorbind, orice tip de pointer poate indica oriunde în memorie. Cu toate acestea, toate
operațiile cu pointeri se referă la tipul lor de bază, astfel că este important ca un pointer să fie declarat
corect.

Se va considera tipul de data utilizator struct student definit mai sus pe care îl vom redenumi
cu numele ST:
typedef struct student ST;

În exemplul următor se va declara un pointer de tipul de dată definit mai sus, ST, se alocă în
mod dinamic memorie și se vor completa, citind de la tastatură, câmpurile structurii de tip ST alocată
dinamic. Pentru alocarea dinamica a memoriei se alege în continuare operatorul new. Eliberarea
memoriei alocată dinamic cu operatorul new se realizează cu ajutorul operatorului delete.
Exemplu
1 #include <iostream>
2 using namespace std;

3 struct student
4 {
5 char nume[25];
6 char prenume[25];
7 char sectia[6];
8 int anul;
9 double media;
10 };

11 typedef struct student ST;

12 int main(void)
13 {
14 ST* s = new ST;

//introducere date de la tastatura


15 cout << "Nume: ";
16 cin >> s->nume;
17 cout << "Prenume:";
18 cin >> s -> prenume;
19 cout << "Sectia: ";
20 cin >> s->sectia;
21 cout << "Anul: ";

7
22 cin >> s->anul;
23 cout << "Media:";
24 cin >> s->media;

25 cout << endl << endl;

//afisare date
26 cout << "Nume: "<< s->nume <<endl;
27 cout << "Prenume:" << s->prenume << endl;
28 cout << "Sectia: " << s->sectia << endl;
29 cout << "Anul: " << s->anul << endl;
30 cout << "Media:" << s->media << endl;

31 delete s;

32 return 0;
33 }

Linia 14: se declară pointerul s de tipul ST, se alocă spațiul de memorie pentru o structura de
tipul ST si se salvează adresa de memorie de început corespunzătoare acestui spațiu de memorie în
variabila pointer s.
Liniile 1524 sunt folosite pentru completarea câmpurilor structurii alocate cu date citite de la
tastatura:
o Liniile 15, 17, 19, 21, 23 sunt folosite pentru afișare de mesaje sugestive pentru
utilizatorul programului;
o Liniile 16, 18, 20, 22, 24 sunt folosite pentru citirea de la tastatura a informațiilor și
salvarea acestora în câmpurile variabilei s.
Liniile 2630 sunt folosite pentru afișarea informațiilor salvate în câmpurile variabilei s.
Linia 31: se realizează dealocarea zonei de memoriei indicată de variabila pointer s.

Algoritmul
Algoritmul este un set de instrucțiuni ce se execută pas cu pas în vederea rezolvării unei
probleme date.
Exemplu
Se dorește stabilirea unui algoritm pentru realizarea unei căni de Nesquik cu lapte. Pentru a
prepara porția de Nesquik cu lapte se vor urmări pașii
1. Se ia o cană.
2. Se ia laptele (din frigider):
a. Este lapte?
i. Dacă DA, torn în cană.
ii. Dacă NU, se merge la magazin pentru a cumpăra lapte?

8
1. Dacă DA, se merge la magazin pentru a cumpăra lapte.
2. Dacă NU, nu se mai prepară băutura și se încheie algoritmul.
3. Se încălzește laptele.
a. .....
4. Se adaugă în lapte, după preferință, Nesquik și se amestecă.
5. Algoritm încheiat

Liste înlănțuite

1. Introducere
O lista înlănțuită reprezintă o colecție de elemente numite noduri care împreuna formează o
ordonare liniara de date. Fiecare nod are doua părți principale:
- o parte utilizată pentru stocarea informației utile (relevante);
- o parte pentru stocarea informației de legătură cu următorul nod (lista simplu înlănțuită) sau
informații de legătură cu nodurile succesor si predecesor nodului curent.

2. Lista simplu înlănțuită


2.1 Introducere
Fiecare nod (exceptând ultimul nod) al unei astfel de liste va conține pe lângă informația
relevantă sau utilă și adresa următorului nod din listă.
Reprezentare grafica a unui nod al listei simplu înlănțuite este prezentată în Fig. 1. Informația
utilă este stocată într-o variabilă sau într-un set de variabile de orice tip de data: predefinite (ale
limbajului de programare) sau definite de utilizator. Informația de legătura cu următorul nod este
stocată într-un pointer de tipul structurii nodului.
Informația de legătură
cu următorul nod
Informația utilă

Fig. 1 Reprezentarea unui nod al listei simplu înlănțuită


Forma generală de reprezentare a unei liste simplu înlănțuite este prezentată în Fig. 2. Adresa
primului nod din lista este salvata întotdeauna intru-un pointer numit primul sau cap. Ultimul nod va
avea întotdeauna câmpul de legătură cu următorul nod setat cu valoarea NULL.
primul

Fig. 2 Forma generală a unei liste simplu înlănțuite

9
În continuare pentru studierea metodelor (funcțiilor) de prelucrare (procesare) ce se aplică în
cazul unei liste simplu înlănțuite se va defini pentru nodurile listei înlănțuite un tip de dată utilizator
sub forma unei structuri numită nod cu doua câmpuri:
- un câmp, numit info, pentru stocarea informației utile reprezentată printr-o variabila de tipul
int;
- un câmp, numit succ, pentru stocarea informației de legătură cu următorul nod (nodul
succesor) sub forma unei variabile pointer de tipul structurii nodului.
Codul sursă pentru definirea acestui tip de dată este cel următorul:
struct nod
{
int info;
struct student *succ;
};

Pentru a avea o denumire sugestivă pentru tipul de dată al nodurilor listei simplu înlănțuite se
va redenumi tipul de data utilizator struct nod cu numele LSI (prescurtare la „Lista Simplu
Inlantuita”):
typedef struct nod LSI;

In fig. 3 este reprezentat un exemplu de listă simplu înlănțuite ale cărei noduri

primul

20 5 32 15

Fig. 3 Un exemplu de listă simplu înlănțuită

2.2 Crearea listei simplu înlănțuite


Lista simplu înlănțuită se consideră că este creată în momentul în care s-a creat primul nod al
listei. Pentru a avea o listă simplu înlănțuită este nevoie întotdeauna de un pointer care sa indice primul
nod din lista. Acestui pointer ii vom da numele primul. Pentru realizarea acestei funcții sau metode
se vor urma pașii algoritmului de mai jos.
Algoritmul pentru creare a listei simplu înlănțuite
Pas 1. Alocarea memoriei pentru noul nod, adresa noului nod se salvează într-o variabilă pointer
temporară numită tmp;

10
Pas 2. Completarea cu informație a câmpului / câmpurilor pentru stocarea informației utile
(relevante)
Pas 3. Completarea câmpului succ cu valoarea NULL;
Pas 4. Completarea pointerului primul cu adresa acestui nod nou.(variabila pointer primul primește
ca valoare adresa noului element care este salvată temporar în variabila pointer tmp).

Fig. 4 Crearea listei simplu înlănțuite


Codul C corespunzător algoritmului este următorul
LSI* tmp; //declarea unui pointer temporar

tmp = new LSI; //alocare memorie pentru noul nod


tmp->info = info; //completarea campului pentru informatii utile
tmp->next = NULL; //completarea campului de legatura cu valoarea 0 (NULL)

primul = tmp; //pointerul primul memorează adresa noului nod

2.3 Inserarea unui nod în lista simplu înlănțuită


2.3.1 Inserarea unui nou nod la începutul listei simplu înlănțuite

11
2.3.2 Inserarea unui nou nod la sfârșitul listei simplu înlănțuite (Var. 1)
Pentru realizarea acestei funcții se vor urma pașii algoritmului de mai jos.
Algoritmul pentru inserarea unui nou nod la sfârșitul listei simplu înlănțuite
Pas 1: Se utilizează un pointer temporar (tmp) pe care îl inițializăm cu adresa primului nod din lista
(salvată în pointerul primul).
Pas 2: Se parcurge lista nod cu nod până se ajunge la ultimul nod, pointerul tmp trebuie să indice
acest ultim nod.
Pas 3: Se aloca memorie pentru un nou nod și se completează câmpul succ cu adresa acestui nou
nod.
Pas 4: Se completează câmpul pentru stocarea informației utile.
Pas 5: Se completează câmpul succ al noului nod cu valoarea NULL.

Fig. 5 Inserarea unui nod la sfârșitul listei simplu înlănțuite

12
2.3.3 Inserarea unui nou nod la sfârșitul listei simplu înlănțuite (Var. 2)

13
2.3.4 Inserarea în interiorul listei simplu înlănțuite după un nod specificat

14
15
2.3.5 Inserarea în interiorul listei simplu înlănțuite înaintea unui nod specificat

Cod sursă:

16
2.4. Parcurgerea unei liste simplu înlănțuite

17
2.5. Ștergerea unui nod din lista simplu înlănțuită

2.5.1 Ștergerea la începutul listei simplu înlănțuite (ștergerea primului nod din
listă)

18
2.5.2 Ștergerea la sfârșitul listei simplu înlănțuite (ștergerea ultimului nod din
listă)

19
2.5.3 Ștergerea în interiorul listei simplu înlănțuite
Subiect realizat de studenți sub formă de temă

20
3. Lista dublu înlănțuită
3.1 Introducere

21
3.2 Crearea listei dublu înlănțuite

22
23
3.3 Inserarea unui nod în lista dublu înlănțuită
3.3.1 Inserarea unui nod la începutul listei dublu înlănțuite

24
3.3.2 Inserarea unui nod la sfârșitul listei dublu înlănțuite

3.3.3 Inserarea unui nod în interiorul listei dublu înlănțuite

25
3.3.3.1 Inserarea unui nod în interiorul listei dublu înlănțuite înaintea unui nod
specificat

26
3.3.3.2 Inserarea unui nod în interiorul listei dublu înlănțuite după un nod
specificat
Subiect realizat de studenți sub formă de temă

3.4 Parcurgerea listei dublu înlănțuite

27
3.4.1 Parcurgerea directă a listei dublu înlănțuite

3.4.2 Parcurgerea inversă a listei dublu înlănțuite

3.5 Ștergerea unui nod din lista dublu înlănțuită

28
3.5.1 Ștergerea la începutul listei dublu înlănțuită (ștergerea primului nod din
listă)
3.5.1.1 Ștergerea la început cu pointer temporar (tmp)

29
3.5.1.2 Ștergerea la început fără pointer temporar (tmp)

30
3.5.2 Ștergerea la sfârșitul listei dublu înlănțuită (ștergerea ultimului nod din listă)

31
3.5.3 Ștergerea în interiorul listei dublu înlănțuită

32
Coada (queue)

33
34
35
Stiva (stack)

36
Implementarea stivei cu ajutorul unui tablou de pointeri este realizat de studenți sub formă de
temă

37
Arbori binari

38
39
40

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