Sunteți pe pagina 1din 23

Programarea

calculatorului
Noţiunea de pointer şi variabile
dinamice de date
 Alocarea dinamică este metoda prin care unei
variabile de memorie sau unei structuri de
dată i se alocă spațiu sau se eliberează spațiul
de memorie ocupat de ea în timpul execuției
programului, în funcție de necesități.
  Variabilele care folosesc alocarea dinamică se
numesc variabile dinamice. Variabilele
dinamice nu se declară, nu au nume și se
folosesc în program prin intermediul
variabilelor de tip pointer alocate static.
Un pointer este o variabilă care are ca valoare
o adresă de memorie.

Spunem că variabila pointer indică locaţia de


memorie de la adresa pe care o conţine.
 
O variabilă de tip pointer se caracterizează
prin faptul că valorile pe care le poate memora
sunt adrese de memorie. 
Declararea variabilelor pointer:

tipul datei socată operatorul numele variabil de


la adresa indicată de referință tip pointer
de pointer
În momentul în care în program trebuie
folosită o variabilă dinamică, se cere sistemului
să I se aloce spațiu în Heap. 
Pentru a aloca memorie dinamică se folosește
operatorul new:
nume = new tip; 
iar pentru eliberarea spațiului de memorie
alocat în Heap se folosește operatorul
delete:

delete nume;
Lista
Lista simplu inlănţuită poate fi
reprezentată grafic astfel:

Pentru a identifica o listă simplu înlănţuită este suficient să reţinem adresa


primului element al listei într-un pointer separat, denumit Prim.

Într-o listă simplu înlănţuită mai există un element special: ultimul nod.
Acest nod va conţine în partea de legătură pointerul NULL.
Declararea unui nod din listă

Informaţia utilă Informaţia de legătură

Pentru comoditate în aplicaţiile ulterioare, vom defini tipul de date


Lista care este adresa unui nod din listă:

typedef struct nod * Lista;


Operaţiile fundamentale care se
pot executa asupra unei liste
simplu înlănţuite
Inserarea
unui nod în Parcurgerea
listă; unei liste;

Ştergerea
unui nod
din listă.
Adaugarea unui nod în listă
Pentru inserare vom implementa o funcţie Adaug cu trei parametri:
1. Prim – pointer care conţine adresa primului nod din lista în care se va insera; acest
parametru va fi transmis prin referinţă, deoarece în urma inserării începutul listei se poate
modifica;
2. p – pointer care conţine adresa nodului din listă după care se face inserarea;
dacă p este NULL, atunci inserarea noului nod se va face la începutul listei;
3. x – informaţia utilă a nodului care urmează să fie inserat în listă.

Vom aloca dinamic memorie pentru un nou nod, a cărui adresă o vom reţine în variabila
pointer q. În câmpul inf al noului nod vom memora valoarea x (q->inf=x sau (*q).inf=x).

Notă!
În cazul aplicării funcţiei Adaug la
inserare apar două cazuri distincte:
Dacă p=NULL, noul nod va fi
inserat la începutul listei;
dacă p!=NULL, inserarea se va
face în interiorul listei.
Exemplul 1. Adăugarea unui nou nod la
începutul listei

Să ilustrăm pas cu pas inserarea la începutul acestei liste a unui nou nod,
cu informaţia x (==7), a cărei adresă va fi memorată în pointerul q:
 1. Se alocă memorie din Heap pentru noul element (Lista q=new nod;).
 2. Se iniţializează zona de informaţie utilă a acestuia (q->inf=x).
 3. Se iniţializează zona de legătură cu adresa nodului care a fost anterior primul în listă,
adresă alocată în variabila Prim (q->urm=Prim).
 4. Se reiniţializează variabila Prim cu adresa noului element alocat (Prim=q;).
Exemplul 2. Inserarea unui nod
în interiorul listei

Să ilustrăm pas cu pas inserarea, în lista înlănţuită


iniţială din exemplul precedent, a unui nou nod cu
informaţia x (==7), după nodul a cărui adresă este
memorată în parametrul p (p->inf==9).
Algoritmul:
1. Se alocă memorie pentru noul element (Lista q=new nod;).
2. Se iniţializează zona de informaţie utilă a acestuia (q->inf=x).
3. Se iniţializează zona de legătură a noului nod cu adresa care se află în zona de
legătură a variabila p (q->urm= p->urm;).
4. Se reiniţializează variabila *p cu adresa noului element alocat (p->urm=q;).
Observaţii
1. Crearea unei liste se
realizează prin inserări succesive
de elemente.
Parcurgerea elementelor unei 2. Funcţia de inserare creată
liste (Adaug) este generală,
fucţionează pentru toate cazurile
posibile: inserare la începutul
listei, inserare în interiorul listei
şi inserare la sfârşitul listei.
Ştergerea unui nod dintr-o listă
simplu înlănţuită
Pentru ştergere vom implementa o funcţie denumită Elimin cu doi parametri:
1. Prim –pointer care conţine adresa primului nod al listei din care se face ştergerea; acest
parametru va fi transmis prin referinţă, deoarece în urma ştergerii, începutul listei se poate
modifica;
2. p –pointer care conţine adresa nodului (din listă) care precedă nodul ce urmează a fi şters (se
transmite adresa nodului precedent şi nu adresa nodului de şters pentru a putea restaura corect
legăturile în listă); dacă p este NULL deducem că va fi şters primul nod din listă.
Şi la ştergere apar două cazuri distincte.
Dacă p==NULL, va fi şters primul nod din listă;
dacă p!=NULL, va fi şters un nod din interiorul listei.
Exemplul .1
Ştergerea primului nod din listă.

Să ilustrăm pas cu pas ştergerea primului nod al listei din exemplul precedent, adică din lista:
1. Memorăm în variabila q adresa nodului ce urmează a fi şters (q=Prim).
2. Adresa primului element din listă se schimbă (Prim=Prim->urm).
3. La sfârşit eliberăm zona alocată nodului ce a fost eliminat din listă (delete q).
Exemplul 2. Ştergerea unui nod
din interiorul listei.

Să ilustrăm pas cu pas ştergerea din lista din exemplul


precedent a nodului cu informaţia 9, adică din lista:
Algoritmul:
1. Memorăm în variabila q adresa nodului ce urmează a fi
şters (q=p->urm;).
2. Modificăm legătura care există de la *p la *q
(elementul de şters) şi o transformăm într-o legătură la
nodul care urmează după cel ce va fi şters (p-
>urm = q->urm).
3. Eliberăm zona de memorie alocată nodului ce a fost
eliminat din listă (delete q).
Liste simplu înlănţuite circulare
O listă simplu înlănţuită este circulară dacă după ultimul element din listă urmează
primul element al listei.

Observaţii
1. Nici unul dintre nodurile unei liste
circulare nu conţine valoarea NULL în partea
de legătură. Operaţiile elementare asupra
listelor simplu înlănţuite circulare vor fi
implementate ţinând cont de această
observaţie.
2. Pentru a identifica o listă simplu înlănţuită
circulară putem reţine adresa oricărui element
din listă.
Adăugarea unui element
în lista circulară
Pentru inserare vom implementa o funcţie
AdaugC cu trei parametri:
1. Prim –pointer care conţine adresa primului
nod din lista în care se face inserarea; acest
parametru va fi transmis prin referinţă, deoarece
în urma inserării începutul listei se poate
modifica;
2. p –pointer care conţine adresa nodului din
listă după care se face inserarea;
3. x –informaţia utilă a nodului care
urmează să fie inserat în listă.

Vom aloca dinamic memorie pentru un nou nod, a cărui adresă o vom reţine în variabila
pointer q. În câmpul inf al noului nod vom memora valoarea x (q->inf=x sau (*q).inf=x).
La inserare apar două cazuri distincte.
Dacă Prim=NULL (lista este vidă), noul nod inserat va fi singurul element din listă
(deci în partea de legătură vom reţine adresa sa);
Dacă Prim!=NULL, inserarea se face în interiorul listei.
Ştergerea unui nod dintr-o listă
simplu înlănţuită circulară
Pentru ştergere vom implementa o funcţie
denumită EliminC cu doi parametri:
1. Prim –pointer care conţine adresa primului nod
al listei din care se face ştergerea; acest parametru
va fi transmis prin referinţă, deoarece în urma
ştergerii, începutul listei se poate modifica;
2. p –pointer care conţine adresa nodului (din
listă) care precedă nodul ce urmează a fi şters (se
transmite adresa nodului precedent şi nu adresa
nodului de şters pentru a putea restaura corect
legăturile în listă).
Şi la ştergere apar două cazuri distincte.
Dacă p->urm==Prim, va fi şters primul nod din listă, deci valoarea parametrului Prim
va fi actualizată (va primi adresa următorului nod din listă sau NULL dacă lista este
formată dintr-un singur nod);
Dacă p->urm!=Prim va fi şters un nod din interiorul listei.
Parcurgerea unei liste simplu
înlănţuite circulare
Pentru a parcurge o listă simplu
înlănţuită circulară, vom utiliza un pointer
p, căruia îi vom atribui iniţial adresa
primului element din listă. La fiecare pas,
se vizitează nodul curent, apoi se treaca la
nodul următor (p=p->urm), până când se
revine la nodul de plecare.
Funcţia alăturată realizează parcurgerea
unei liste simplu înlănţuite circulare cu
afişarea informaţiilor din noduri
Liste dublu înlănţuite back info next

O listă dublu înlănţuită este o structură de date constituită dintr-o succesiune de


elemente denumite noduri.
Fiecare nod din listă conţine trei părţi: o parte de informaţie utilă (în care se
memorează informaţiile corespunzătoare nodului, specifice problemei) şi două părţi de
legătură (în care este memorată adresa precedentului element din listă şi respectiv adresa
următorului element din listă)
Nod - un tip de date structurat
info câmpuri pentru informatia utilă, 
back pentru adresa precedentă
next  pentru adresa următoare.

Exmplu: Listă bidirecţională formată din trei noduri ce conţin numere întregi
Sfârşit

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