fbpx

Ce este stiva in C++ ? Cum functioneaza?

de Mihai-Alexandru

Ce este stiva ?

Stiva (sau „stack” in limba engleza) este o structură de date liniara ce lucreaza cu o colectie de date avand doua operatii principale:

  • push(int numar) – adauga numar in stiva
  • pop() – sterge ultimul element adaugat in lista (peek() – returneaza valoarea acestui element – deseori functia pop() contine si functia peek() integrata).

Modul in care acesta prelucreaza elementele i-a dat denumirea de LIFO ( Last In First Out=  ultimul venit-primul servit ).

Cum functioneaza stiva?

Avand in vedere ca este o structura de date secventiala, operatiile push si pop se intampla numai la capatul structurii (acest „capat” este numit top). Acest detaliu permite stivei sa fie implementata ca o lista simpla inlantuita. De mentionat este faptul ca stiva este o structura de date cu un numar total de elemente flexibil.

Stiva functioneaza pe principiul LIFO, imginati-va de exemplu mai multe farfurii expuse pe raft intr-un IKEA.

Stiva - farfurii

In mod normal cand faceti cumparaturile puneti in cos prima farfurie. Pe baza acestui principiu functioneaza si stiva – orice element adaugat în ea va fi pus in varful (capatul / top-ul) stivei, iar atunci când dorim sa accesam o anumita farfurie, incepem sa o parcurgem de la varf către baza (nu invers – le-ai sparge pe toate daca ai face invers).

La ce este folosita stiva?

  • Backtracking – in momentul cand vrei sa parcurgi un labirint si te blochezi, pentru a retine pasii ce i-ai facut, ii memorezi intr-o stiva. Daca doresti sa te intorci inapoi un anumit numar de pasi, scoti pe rand coordonatele geografice din stiva.
  • Inversarea unui string – Daca doresti sa construiesti imaginea in oglinda a unui string (de exemplu din „mere” sa faci „erem” – vei folosii o stiva). Pe masura ce citesti cuvantul, pui fiecare litera in stiva, iar in momentul cand construiesti cuvantul nou, scoti cate o litera pe rand din stiva.
  • Multe alte exemple (evaluarea unei expresii, etc)

Cum implementam stiva?

Inainte de a implementa stiva vom traduce denumirile functiilor in engleza (pentru a te familiariza cu libraria STL).

  • push(int numar) – adauga un element in stiva
  • pop() – sterge ultimul element din stiva
  • peek() – afiseaza ultimul element din stiva
  • isEmpty() – verifica daca stiva este goala

Nota: Uneori functia pop() vine „la pachet cu functia peek()”

Există două feluri prin care o putem implementa: fie printr-un array, fie printr-o lista simpla inlantuita. La clasa veti aborda prima metoda, pentru ca listele nu mai intra in programa de Bacalaureat (din cate stiu, poate s-a schimbat intre-timp).

Probabil va intrebati: „de ce trebuie sa implementam noi ceva ce este gata scris in STL?„. Raspunsul este foarte simplu: inveti mult mai bine principiile cu care functioneaza si te forteaza sa intelegi programarea mai bine.

Varianta 1 – Utilizarea unui array (multimi)

#include    <iostream>

using namespace std;

const int LIM = 100;

bool isEmpty(int k) {
    if(k == 0)
        return true;
    return false;
}

void push(int stiva[], int &k, int numar) {
    k = k + 1;
    stiva[k] = numar;
}

int peek(int stiva[], int k) {
    return stiva[k];
}

int pop(int stiva[], int &k) {
    int rezultat = peek(stiva, k);
    k = k - 1;
    return rezultat;
}

int size(int k) {
    return k;
}

int main() {

    int stiva[LIM], k = 0;
    push(stiva, k, 2);
    push(stiva, k, 4);
    push(stiva, k, 6);
    push(stiva, k, 7);
    push(stiva, k, 8);
    cout << pop(stiva, k);
    cout << pop(stiva, k);
    cout << pop(stiva, k);
    return 0;
}

Aceasta varianta incalca una din principiile fundamentale ale stivei. Este restrictionata de un numar maxim de elemente. Stiva este o structura de date flexibila.

Varianta 2 – Utilizarea listelor simpu inlantuite

#include    <iostream>

using namespace std;

struct Nod {
    int data;
    Nod* next;
};

Nod* newNode(int data) {
    Nod* nodNou = new Nod();
    nodNou -> data = data;
    nodNou -> next = NULL;
    return nodNou;
}

bool isEmpty(Nod* top) {
    return top == NULL;
}

void push(Nod* &top, int data) {
    Nod* nodNou = newNode(data);
    nodNou -> next = top;
    top = nodNou;
}

int pop(Nod* &top) {
    if(isEmpty(top))
        return 0;

    Nod* tmp = top;
    top = top -> next;
    int rezultat = tmp -> data;
    delete tmp;
    return rezultat;
}

int peek(Nod* top) {
    if(isEmpty(top))
        return 0;
    return top -> data;
}

int main() {
    Nod* top = NULL;
    push(top, 2);
    push(top, 4);
    push(top, 6);
    push(top, 7);
    push(top, 8);
    cout << pop(top);
    cout << pop(top);
    cout << pop(top);
    return 0;
}

Probleme ce utilizeaza stivele

Pentru a va familiariza cu stivele, puteti sa rezolvati problemele

Comentarii

S-ar putea sa iti placa