Sunteți pe pagina 1din 37

Algoritmi, Structuri de date şi

Complexitate

Tema: Stive. Stive reprezentate prin buffer de


lungime fixă. Stive prin liste simplu înlănţuite.
Cozi. Cozi reprezentate prin buffer ciclic.
Cozi reprezentate prin liste simplu înlănţuite.

Ludmila NOVAC
Dr., conf. univ.
Dep. Informatică
Unităţi de conţinut
Structuri dinamice de date
1. Structuri dinamice de date (arbori binari, liste, stive, cozi).
Arbori binari. Crearea arborilor. Accesul la elementele unui arbore.
Parcurgerea arborilor binari. Arbori binari plini. Arbori binari de căutare.
Exemplu de clasă generică de reprezentare a arborilor binari de căutare.
2. Liste simplu înlănţuite. Liste înlănţuite ciclic. Liste dublu înlănţuite.
Liste dublu înlănţuite ciclic. Exemple de clase generice de reprezentare
a listelor.
3. Stive. Stive reprezentate prin buffer de lungime fixă. Stive
reprezentate prin liste simplu înlănţuite. Exemple de clase generice de
reprezentare a stivelor. Realizarea algoritmului de sortare rapidă prin
utilizarea stivei.
4. Cozi. Cozi reprezentate prin buffer ciclic. Cozi reprezentate prin liste
simplu înlănţuite. Exemple de clase generice de reprezentare a cozilor.
Planul Lecţiei
• Stive. Stivele reprezentate prin buffer de lungime fixă.
Stive reprezentate prin liste simplu înlănţuite. Realizarea
algoritmului de sortare rapidă prin utilizarea stivei.

• Cozi. Cozi reprezentate prin buffer ciclic. Cozi


reprezentate prin liste simplu înlănţuite.

• Exemple de Liste, stive, cozi. Aplicaţii.


Stivele şi Cozile
• Cozile şi stivele sunt structuri de date logice (implementarea este
făcută utilizând alte structuri de date) şi omogene (toate elementele
sunt de acelaşi tip). Ambele structuri au două operaţii de bază:
adăugarea şi extragerea unui element. În afara acestor operaţii se
pot implementa şi alte operaţii utile: test de structură vidă, obţinerea
primului element fără extragerea acestuia etc. Diferenţa
fundamentală între cele două structuri este disciplina de acces.
Stiva foloseşte o disciplină de acces de tip LIFO (Last In First Out),
iar coada o disciplină de tip FIFO (First In First Out).
Stive si cozi. Exemple

Stivă

Coadă
Stivele. Implementarea stivelor
Stivele
• Pentru implementarea unei stive folosind masive (tablouri) avem nevoie de
un tablou (masiv) V de dimensiune n pentru memorarea elementelor.
Ultimul element al tabloului va fi utilizat pentru memorarea numărului de
elemente ale stivei.

În cazul în care stiva este vidă, atunci elementul Vn-1 va avea valoarea 0. Folosind
această reprezentare, operaţiile de bază se pot implementa în timp constant (O(1)).
Stive. Noţiuni generale
• Stivă (engl. stack, LIFO list, pushdown stack, pushdown list)
este o structură dinamică de date compusă dintr-un set
ordonat şi finit de elemente de una şi aceiaşi structură, astfel
ca adăugarea elementelor noi şi accesarea (mai ales
extragerea) elementelor existente se efectuează dintr-un
capăt (numit vârful stivei) după principiul “ultimul a întrat –
primul a ieşit” (engl. LIFO – Last In, First Out ).
Moduri de implementare
Stivele şi cozile pot fi implementate în mai multe moduri. Cele mai
utilizate implementări sunt cele folosind masive şi liste. Ambele
abordări au avantaje şi dezavantaje:
La stive se aplică operaţiile următoare:
• La stive se aplică următoare operaţii :

• inserarea unui element nou în vârful stivei, vârful precedent devine ca


următorul element (push);
• extragerea unui element din vârful stivei, următorul element devine noul vârf
(pop);
• verificarea dacă stiva este vidă, adică nu se poate aplica operaţia pop
(isempty);
• verificarea dacă stiva este plină, adică nu se poate aplica operaţia push
(isfull).

Sunt două metode de realizare a stivelor în memorie operativă:


– prin buffer de dimensiune fixă;
– prin listă simplă înlănţuită cu adăugarea şi înlăturarea
elementelor la începutul listei.
Inserarea şi extragerea
elementelor în/din stivă
Realizarea stivelor prin buffer de
dimensiune fixă
• Bufferul reprezintă un vector de lungime fixă (mărimea, sau
adâncimea stivei). Tipul elementelor vectorului depinde de tipul
elementelor stivei sau este pointer cu tipul de bază – tipul
elementelor stivei, cum este arătat schematic în figura următoare.

• Câmpul size conţine dimensiunea stivei. El se iniţializează în


momentul când se creează stiva şi nu se schimbă pe parcurs.
Realizarea stivelor prin buffer

Vectorul buffer reprezintă spaţiul pentru înscriere în stivă.


Memoria pentru el se alocă în momentul când se creează stiva.
Câmpul top indică vârful stivei (prima celulă disponibilă pentru înscriere).
El se iniţializează în momentul când se creează stiva şi mai departe se
actualizează la fiecare înscriere (push) şi fiecare extragere (pop).
De exemplu, după trei înscrieri consecutive (push(A), push(B), push(C))
stiva va arăta astfel:
Realizarea stivelor prin buffer

Dacă în continuare va urma o extragere (pop), ea va avea rezultatul C, iar


stiva va arăta astfel:
Operaţiile de bază (în pseudocod)
Algoritmii pentru implementarea operaţiilor de bază adăugarea şi ştergerea
unui element (în pseudocod) sunt:
Reprezentarea dinamică a stivelor
• Cea de-a doua modalitate de implementare a stivelor este cea folosind liste
alocate dinamic.
• În cazul stivei, vom folosi o listă simplu înlănţuită organizată ca în figura de
mai jos.
• Fiecare nod este format din informaţiile utile şi o legătură către elementul
următor. Tipul informaţiilor stocate în stivă este indicat de utilizator prin
definirea tipului TipStiva. Stiva vidă este reprezentată printr-un pointer nul.
Elementele sunt adăugate înaintea primului element (cu deplasarea vârfului
stivei). Extragerea se face tot din vârful stivei.
Realizarea stivelor prin listă

• Operaţiile de adăugare şi extragere se efectuează la începutul listei


care se foloseşte pentru reprezentarea stivei în memorie operativă.
• Stiva goală în formă de listă va arăta astfel:
Realizarea stivelor prin listă

După trei înscrieri consecutive (push(A), push(B), push(C)) stiva va arăta astfel:

Dacă mai departe va urma o extragere (pop), ea va avea rezultatul C, iar stiva va
arăta astfel:
Utilizarea stivelor la parcurgerea
arborilor binari
• În continuare vom demonstra utilizarea stivelor pentru parcurgerea arborilor
binari. În capitolul consacrat arborilor binari au fost prezentate parcurgerile
(preordine, inordine, postordine) şi realizarea prin funcţii recursive.
Acum vom folosi stivele.
Parcurgerea arborilor binari. Exemplu
a) Traversarea în preordine (RSD)
- se vizitează rădăcina
- traversează subarborele stâng
- traversează subarborele drept
b) Traversarea în inordine (SRD)
- se traversează subarborele stâng
- se vizitează rădăcina
- se traversează subarborele drept
c) Traversarea în postordine (SDR)
- se traversează subarborele stâng
- se traversează subarborele drept
- se vizitează rădăcina

Exemplu:
Vom exemplifica metodele de parcurgere
pe următorul arbore.
Pentru arborele binar din figură avem
următoarele succesiuni ale
parcurgerilor:
• metoda RSD: 1, 2, 4, 5, 6, 7, 8, 9, 3
• metoda SRD: 4, 2, 6, 5, 8, 7, 9, 1, 3
• metoda SDR: 4, 6, 8, 9, 7, 5, 2, 3, 1
Parcurgerea arborilor binari
Un arbore binar este un arbore în care fiecare nod are gradul cel mult 2 adică
fiecare nod are cel mult 2 fii.

Parcurgeri în adâncime Pentru arborele din figură şirul parcurgerii pe niveluri este:

• preordine (RSD): 2, 8, 10, 1, 5, 3, 4, 11, 6, 7, 9, 12


• inordine (SRD): 1, 10, 5, 8, 4, 3, 11, 2, 9, 7, 6, 12
• postordine (SRD): 1, 5, 10, 4, 11, 3, 8, 9, 7, 12, 6, 2
Cozile. Cozi prin buffer ciclic.
Cozi prin liste simplu înlănţuite
Cozile. Implementarea Cozilor
Cozile. Noţiuni generale
Coada se poate implementa folosind un vector circular de dimensiune
n (după elementul n-4 urmează elementul 0). Ultimele două elemente
conţin indicii de start şi sfârşit ai cozii, iar antepenultimul element este
un marcaj folosit pentru a putea diferenţia cazurile de coadă vidă şi
coadă plină.
Cozi. Noţiuni generale
Coadă (engl. queue, FIFO list, pushup stack, pushup list) este o structură
dinamică de date compusă dintr-un set ordonat şi finit de elemente de una
şi aceiaşi structură, astfel ca adăugarea elementelor noi se efectuează
numai la sfârşitul setului, iar accesarea (mai ales extragerea) elementelor
existente se efectuează numai de la începutul setului după principiul “primul
a întrat – primul a ieşit” (engl. FIFO – First In, First Out ).
Operaţiile asupra elementelor cozii :
• inserarea unui element nou în coadă, ultimul precedent devine ca
penultimul (put);
• extragerea unui element din coadă, următorul element devine noul prim
(get);
• verificarea dacă coada este vidă (isempty), adică nu se poate aplica
operaţia get;
• verificarea dacă coada este plină (isfull), adică nu se poate aplica
operaţia put.
• În dispozitive coada poate fi realizată ca o formă specială de memorie fără adrese
pentru crearea zonei de tampon de viteză mare pentru schimbul de date între fluxul
de intrare sau ieşire care se formează în timpul real şi unitatea de disc.
Sunt mai multe metode de realizare a cozilor în memorie operativă:
– prin bufferul ciclic de dimensiune fixă;
– prin listă simplă înlănţuită dotată cu un pointer cu adresa ultimului
element adăugat;
– prin listă simplu înlănţuită cu proprietatea că adăugarea se face la
sfârşitul listei iar extragerea - de la începutul listei.
Realizarea cozilor prin buffer ciclic de
dimensiune fixă
Bufferul reprezintă un vector de lungime fixă (mărimea, sau adâncimea
cozii). Tipul elementelor vectorului depinde de tipul elementelor cozii sau
este pointer cu tipul de bază – tipul elementelor cozii, cum este arătat
schematic în figura următoare.
Realizarea cozilor prin buffer ciclic
Câmpul size conţine dimensiunea cozii. El se iniţializează în momentul când se
creează coada şi mai mult nu se schimbă.
Vectorul buffer reprezintă spaţiul pentru înscriere în coadă. Memoria pentru el se
alocă în momentul când se creează coada.
Câmpul nextin indică prima celulă disponibilă pentru înscriere. El se iniţializează
în momentul când se creează coada şi mai departe se actualizează la fiecare
înscriere (put).
Câmpul nextout indică primul element disponibil pentru extragere. El se
iniţializează în momentul când se creează coada şi mai departe se actualizează la
fiecare extragere (pop).
De exemplu, după trei înscrieri consecutive (put(A), put(B), put(C)) coada va arăta
astfel:
Realizarea cozilor prin buffer ciclic

• Dacă mai departe va urma o extragere (get), ea va avea


rezultatul A, iar coada va arăta astfel:
Operaţiile de bază (în pseudocod)

Algoritmii (în pseudocod) care implementează operaţiile de bază


adăugarea şi ştergere a unui element în/din coadă memorată sunt:
Reprezentarea dinamică a cozilor
• Cea de-a doua modalitate de implementare a cozilor este cea folosind liste
alocate dinamic.
• Coada poate fi implementată folosind o listă circulară dublu
înlănţuită de forma prezentată mai jos.
• Ca şi în cazul stivei, tipul informaţiilor stocate este indicat de către
utilizator prin definirea tipului de date TipCoada. Coada goală este
reprezentată printr-un pointer nul. Adăugarea elementelor se face la
sfârşitul listei, iar extragerea se face de la începutul acesteia.
Realizarea cozilor prin listă
Operaţiile de adăugare se efectuează la începutul listei, iar Operaţiile
de extragere la sfârşitul listei, care se foloseşte pentru reprezentarea
cozii în memorie operativă. Coada goală în formă de listă va arăta
astfel:

După trei înscrieri consecutive (put(A), put(B), put(C))


coada va arăta astfel:
Dacă mai departe va urma o
extragere (get), ea va avea
rezultatul A, iar coada va arăta
astfel:
Exemplu de coadă
Exemple:
zona de tampon (bufferul) tastaturii;
coadă de taskuri de deservire de către sistemul de
operare.
Exemplu de coadă
Condiţiile pentru lucrarea de laborator №3 la ASDC
„Structuri dinamice de date”

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