Documente Academic
Documente Profesional
Documente Cultură
unde:
- info1, info2, …, infon reprezintă informația memorată în fiecare dintre
cele n noduri;
- adr1, adr2, …, adrn sunt adresele din memorie ale nodurilor listei.
struct nod {
tip_date info;
nod *next;
};
nod *baza;
z y x
Fig. 4.2
struct nod {
char data;
nod *next;
};
nod *baza, *temp;
baza = NULL;
a temp b temp
baza baza
c d
temp temp
Fig. 4.3
Instrucțiunea
temp = new(nod);
creează un nou nod a cărui adresă este memorată în variabila de tip pointer
temp.
Situația creată este prezentată în figura 4.3a. Pasul următor constă în
atribuirea unei valori noii componente:
baza = temp;
baza
temp x
temp = new(nod)
temp
x
a
d b
baza baza
x x
temp -> data = ’y’ temp->next = baza
temp temp
c y y
d
baza
e x
baza = temp
temp
Fig. 4.4
temp = new(nod);
temp -> data = ’valoare’;
temp -> next = baza;
baza = temp;
p = p -> next;
void afiseaza() {
nod *p;
while (p) {
cout << p -> data << ” ”;
p = p -> next;
}
cout << endl;
}
Putem imagina o funcție care realizează înserarea unui nod dick înaintea
nodului existent tom. In această situație trebuie găsit pointerul care indică către
nodul anterior lui tom. Pentru a găsi acest pointer, pe care să-l denumim prec,
trebuie traversată lista în modul următor:
unde valoarea inițială a pointerului prec va fi baza. La ieșirea din ciclu, prec va
indica spre nodul ce precede componenta tom.
dick
baza
tom
a
1) dick -> next = tom -> next
dick
baza
tom
b
Fig. 4.6
O funcție care înserează un nod dick înaintea unui alt nod tom trebuie să
depisteze situația în care tom este primul nod al listei. Ținând seama de aceste
considerente, o funcție insereaza_inainte ar putea fi scrisă precum urmează:
Dacă tom indică primul nod al listei (tom = baza), atunci, prin înserarea
nodului dick, acesta devine primul nod al listei. In fig. 4.7a și b este prezentată
situația înainte și după înserarea nodului dick, în cazul în care tom este prima
componentă a listei.
Dacă tom nu este prima componentă a listei, atunci lista este traversată
în scopul găsirii valorii pointerului prec. In continuare este înserat nodul dick
în fața nodului tom (figura 4.7c).
dick
a
baza
tom
dick
tom
c
1) prec -> next = dick
prec
tom
Fig. 4.7
prec
a
prec -> next = prec -> next -> next
prec
Fig. 4.8
Remarcăm notația inedită în acest context
dar, dacă ținem seama că prec -> next este un pointer, atunci această notație
devine firească.
De obicei însă, noi avem un pointer chiar către nodul care trebuie șters,
fie acesta tom și, în acest caz, trebuie să parcurgem lista pentru a găsi valoarea
pointerului prec. Operațiile menționate sunt realizate de funcția următoare:
Funcția sterge face distincție între situația în care trebuie șters primul nod
și cea în care se șterge un nod oarecare din listă.
prim
z y x
ultim
Fig. 4.9
prim ultim
z y x
Fig. 5.1
O listă circulară poate fi obținută numai dintr-o structură de tip șir (figura
4.9), deoarece este necesară cunoașterea adresei ultimului nod. Închiderea
listei se realizează prin instrucțiunea:
Prin acest aranjament lista poate fi parcursă perpetuu, fapt care poate
constitui un avantaj în unele aplicații.
Lista dublu înlănțuită este o listă în care fiecare nod are două legături: o
legătură către nodul precedent și una către nodul următor. Legătura către nodul
următor este păstrată de pointerul next iar cea către nodul anterior – de pointerul
back. Deci, un nod al listei liniare dublu înlănțuite va fi declarat în modul următor:
struct nod {
char data;
nod *next, *back;
};
nod *prim, *ultim;
Am declarat și doi pointeri prim și ultim, care vor reține adresele primului
nod și respectiv, al ultimului element al listei. In figura 6.1 este prezentată o listă
liniară dublu înlănțuită.
prim
ultim
m
Fig. 6.1
ultim ultim
a b
temp temp
baza baza
prim prim
prim baza
prim = temp
ultim ultim
ultim = temp
c d
temp -> next = prim
temp temp
apri baza
x x
a b
d d
temp = new(nod)
temp temp
baza baza
ultim
x y
x y
ultim
d
d ultim = temp
temp
baza
Fig. 6.3
struct nod {
char data;
nod *prec, *suc;
};
unde prec este pointerul către nodul precedent iar suc este pointerul către nodul
următor.
Simetria listei poate fi completată prin legarea primei și ultimei
componente, obținându-se astfel o listă circulară dublu înlănțuită (figura 7.1a).
baza
a
baza
Fig. 7.1
tom
dick
dick -> suc = tom -> suc
tom
om
dick
tom
omt
c
Fig. 7.2
8. Stive
9. Cozi
O coadă („Queue"), numită și listă FIFO ("First In First Out") este o listă la
care adăugarea se face pe la un capăt (de obicei la sfârșitul cozii), iar extragerea
se face de la celălalt capăt (de la începutul cozii). Ordinea de extragere din
coadă este aceeași cu ordinea de introducere în coadă, ceea ce face utilă o
coadă în aplicațiile unde ordinea de servire este aceeași cu ordinea de sosire:
procese de tip "vânzător - client" sau "producător - consumator". In astfel de
situații coada de așteptare este necesară pentru a acoperi o diferență temporară
între ritmul de servire și ritmul de sosire, deci pentru a memora temporar cereri
de servire (mesaje) care nu pot fi încă prelucrate.
Operațiile care pot fi efectuate pe o „coadă" sunt:
- inițializare coadă (initQ);
- test coadă goală (emptyQ) ;
- adăugare un obiect la coadă (addQ, insQ, enqueue);
- scoatere un obiect din coadă (delQ, dequeue);
- citire a unor noduri din coada.