|

Structuri de Date Liniare Implementate Dinamic – Stiva 10


1. Obiectivele lecției:

  • Să înțeleagă conceptul de stivă și utilizările sale.
  • Să învețe cum să implementeze o stivă utilizând alocarea dinamică a memoriei.
  • Să implementeze operații comune pe stive: push, pop, peek și isEmpty.

2. Ce este o stivă?

  1. Definiție:
    O stivă este o structură de date liniară care urmează principiul LIFO (Last In, First Out), ceea ce înseamnă că ultimul element introdus este primul care se scoate.
  2. Operații comune:
    • Push: Adăugarea unui element în stivă.
    • Pop: Eliminarea elementului de la vârful stivei.
    • Peek: Accesarea elementului de la vârful stivei fără a-l elimina.
    • isEmpty: Verificarea dacă stiva este goală.

3. Avantaje și dezavantaje

AvantajeDezavantaje
Structură simplă și ușor de implementat.Accesibilitate limitată (doar vârful stivei).
Eficientă pentru gestionarea problemelor LIFO.Necesită mai multe operații pentru acces aleator.
Utilă în aplicații precum recursivitatea sau backtracking.

4. Implementarea unei stive folosind liste simplu înlănțuite


Structura unui nod

  1. Structura nodului pentru stivă:

struct Nod {

    int valoare;  // Informația stocată

    Nod* urmator; // Pointer către următorul nod

};

  1. Pointerul către vârful stivei:

Nod* top = nullptr;


1. Crearea unui nod

Nod* creeazaNod(int valoare) {

    Nod* nod = new Nod();

    nod->valoare = valoare;

    nod->urmator = nullptr;

    return nod;

}


2. Operații comune pe stivă

  1. Push (Adăugarea unui element):

void push(Nod*& top, int valoare) {

    Nod* nod = creeazaNod(valoare);

    nod->urmator = top;

    top = nod;

}

  1. Pop (Eliminarea elementului de la vârf):

void pop(Nod*& top) {

    if (top == nullptr) {

        cout << „Stiva este goală. Nu se poate elimina elementul.” << endl;

        return;

    }

    Nod* temp = top;

    top = top->urmator;

    delete temp;

}

  1. Peek (Accesarea elementului de la vârf):

int peek(Nod* top) {

    if (top == nullptr) {

        cout << „Stiva este goală.” << endl;

        return -1; // Valoare simbolică pentru eroare

    }

    return top->valoare;

}

  1. isEmpty (Verificarea dacă stiva este goală):

bool isEmpty(Nod* top) {

    return top == nullptr;

}


3. Parcurgerea stivei

void parcurgeStiva(Nod* top) {

    if (top == nullptr) {

        cout << „Stiva este goală.” << endl;

        return;

    }

    Nod* temp = top;

    while (temp != nullptr) {

        cout << temp->valoare << ” „;

        temp = temp->urmator;

    }

    cout << endl;

}


4. Exemplu complet

#include <iostream>

using namespace std;

struct Nod {

    int valoare;

    Nod* urmator;

};

Nod* creeazaNod(int valoare) {

    Nod* nod = new Nod();

    nod->valoare = valoare;

    nod->urmator = nullptr;

    return nod;

}

void push(Nod*& top, int valoare) {

    Nod* nod = creeazaNod(valoare);

    nod->urmator = top;

    top = nod;

}

void pop(Nod*& top) {

    if (top == nullptr) {

        cout << „Stiva este goală. Nu se poate elimina elementul.” << endl;

        return;

    }

    Nod* temp = top;

    top = top->urmator;

    delete temp;

}

int peek(Nod* top) {

    if (top == nullptr) {

        cout << „Stiva este goală.” << endl;

        return -1; // Valoare simbolică pentru eroare

    }

    return top->valoare;

}

bool isEmpty(Nod* top) {

    return top == nullptr;

}

void parcurgeStiva(Nod* top) {

    if (top == nullptr) {

        cout << „Stiva este goală.” << endl;

        return;

    }

    Nod* temp = top;

    while (temp != nullptr) {

        cout << temp->valoare << ” „;

        temp = temp->urmator;

    }

    cout << endl;

}

int main() {

    Nod* top = nullptr;

    push(top, 10);

    push(top, 20);

    push(top, 30);

    cout << „Stiva după adăugări: „;

    parcurgeStiva(top);

    cout << „Elementul de la vârf: ” << peek(top) << endl;

    pop(top);

    cout << „Stiva după eliminarea elementului de la vârf: „;

    parcurgeStiva(top);

    cout << „Stiva este goală? ” << (isEmpty(top) ? „Da” : „Nu”) << endl;

    return 0;

}


5. Utilizări practice ale stivei

  1. Evarea expresiilor aritmetice:
    Utilizată în evarea expresiilor postfixate sau conversia expresiilor infixate.
  2. Controlul recursivității:
    Stiva este utilizată intern pentru a gestiona apelurile recursive.
  3. Operații de backtracking:
    Găsirea soluțiilor prin explorarea căilor posibile și revenirea (ex.: labirinturi).
  4. Parantezare corectă:
    Verificarea dacă o expresie conține paranteze deschise și închise în mod corect.

6. Activități practice pentru elevi

  1. Implementați o funcție care verifică dacă o expresie aritmetică are paranteze corecte utilizând o stivă.
  2. Realizați o funcție care calculează factorialul unui număr utilizând o stivă în loc de recursivitate.
  3. Implementați un algoritm care convertește o expresie infixată într-o expresie postfixată utilizând o stivă.

7. Scheme logice

  1. Push:
    • Creează un nod -> Conectează nodul la vârful stivei -> Actualizează top.
  2. Pop:
    • Verifică dacă stiva este goală -> Elimină nodul de la vârf -> Actualizează top.
  3. Peek:
    • Returnează valoarea din nodul de la vârf fără a-l elimina.

8. Concluzie

  • Stiva este o structură de date esențială în informatică, cu multiple aplicații practice.
  • Implementarea sa folosind alocarea dinamică oferă flexibilitate în gestionarea datelor.
  • Practica ajută la înțelegerea conceptelor și la utilizarea eficientă a acestei structuri.

Similar Posts

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *