Pilas en C

En este ejemplo completo te enseñaré cómo construir una estructura de datos pila en C utilizando nodos enlazados entre sí. Es un ejemplo de implementación completo.

Para gestionar un historial de URLs y simular la función atrás de un navegador web, podemos implementar una pila en C utilizando listas enlazadas. La idea es almacenar cada URL visitada en un nodo, y así, al pulsar atrás, simplemente recuperamos la última URL almacenada en la pila.

Primero, definimos un tipo URL como un puntero a char, que representará nuestras cadenas de texto con las direcciones web. Luego, creamos una estructura nodo que contendrá una URL y un puntero al siguiente nodo, formando así la lista enlazada que representará la pila.

typedef char* URL;

typedef struct nodo {
    URL url;
    struct nodo* siguiente;
} nodo;

Para manejar la pila, definimos una estructura que contiene un puntero a la cima de la pila y un campo para la longitud, que nos ayudará a controlar cuántos elementos hay en ella.

typedef struct pila {
    nodo* cima;
    int longitud;
} pila;

La operación para crear un nuevo nodo recibe una URL, reserva memoria dinámica para el nodo, asigna la URL y establece el puntero siguiente a NULL.

#include <stdlib.h>

nodo* crearNodo(URL url) {
    nodo* nuevo = (nodo*) malloc(sizeof(nodo));
    if (nuevo == NULL) return NULL; // Comprobación básica de malloc
    nuevo->url = url;
    nuevo->siguiente = NULL;
    return nuevo;
}

Para evitar fugas de memoria, es fundamental destruir los nodos cuando ya no los necesitemos. La función para destruir un nodo libera la memoria asignada y asegura que el puntero siguiente no cause problemas.

void destruirNodo(nodo* n) {
    if (n == NULL) return;
    n->siguiente = NULL;
    free(n);
}

La operación de apilar consiste en crear un nuevo nodo con la URL dada y colocarlo en la cima de la pila. Para ello, el nuevo nodo apunta al nodo que actualmente está en la cima, y luego actualizamos la cima para que sea el nuevo nodo. Además, incrementamos la longitud de la pila.

void apilar(pila* p, URL url) {
    nodo* nuevo = crearNodo(url);
    if (nuevo == NULL) return; // Manejo básico de error
    nuevo->siguiente = p->cima;
    p->cima = nuevo;
    p->longitud++;
}

Para desapilar, primero verificamos que la pila no esté vacía. Si tiene elementos, guardamos el nodo de la cima, actualizamos la cima para que apunte al siguiente nodo, decrementamos la longitud y destruimos el nodo que hemos desapilado.

void desapilar(pila* p) {
    if (p->cima == NULL) return; // Pila vacía, nada que desapilar
    nodo* aEliminar = p->cima;
    p->cima = p->cima->siguiente;
    p->longitud--;
    destruirNodo(aEliminar);
}

Para consultar la URL en la cima de la pila, simplemente devolvemos la URL almacenada en el nodo de la cima, siempre que la pila no esté vacía.

URL cima(pila* p) {
    if (p->cima == NULL) return NULL; // Pila vacía
    return p->cima->url;
}

Crear una pila nueva implica reservar memoria para la estructura pila, inicializar la cima a NULL y la longitud a cero.

pila* crearPila() {
    pila* p = (pila*) malloc(sizeof(pila));
    if (p == NULL) return NULL; // Manejo básico de error
    p->cima = NULL;
    p->longitud = 0;
    return p;
}

Para destruir una pila, debemos desapilar todos sus elementos para liberar la memoria de cada nodo y luego liberar la memoria de la propia estructura pila.

void destruirPila(pila* p) {
    while (p->cima != NULL) {
        desapilar(p);
    }
    free(p);
}

Con la longitud almacenada en la estructura, obtener el número de elementos es tan sencillo como devolver ese valor.

int longitud(pila* p) {
    return p->longitud;
}

Y para saber si la pila está vacía, comprobamos si la longitud es cero.

int estaVacia(pila* p) {
    return p->longitud == 0;
}

Esta implementación nos permite gestionar un historial de URLs de forma eficiente, con operaciones básicas para apilar, desapilar y consultar la cima, además de controlar la memoria para evitar fugas. Podemos extenderla para añadir funcionalidades como acceder a elementos intermedios o vaciar la pila completamente, pero con estas bases ya tenemos una pila funcional que simula el comportamiento del botón atrás en un navegador web.

Lista de reproducción
  1. 1
    Qué son las estructuras de datos
    3 minutos
  2. 2
    Listas enlazadas: Teoría
    12 minutos
  3. 3
    Listas enlazadas en C
    18 minutos
  4. 4
    Listas enlazadas en Java
    17 minutos
  5. 5
    Colas: teoría
    6 minutos
  6. 6
    Colas en C
    12 minutos
  7. 7
    Colas en Java
    10 minutos
  8. 8
    Pilas: teoría
    7 minutos
  9. 9
    Pilas en C
    11 minutos
  10. 10
    Pilas en Java
    10 minutos
  11. 11
    Introducción a los árboles
    11 minutos
  12. 12
    Árboles binarios
    9 minutos
  13. 13
    Árboles binarios de búsqueda (parte 1)
    10 minutos
  14. 14
    Árboles de búsqueda binaria (parte 2)
    8 minutos
  15. 15
    BSTs en C (parte 1)
    13 minutos
  16. 16
    BSTs en C (parte 2)
    8 minutos
  17. 17
    BSTs en C (y parte 3)
    18 minutos
  18. 18
    BSTs en Java (parte 1)
    9 minutos
  19. 19
    BSTs en Java (parte 2)
    11 minutos
  20. 20
    BSTs en Java (parte 3)
    10 minutos
  21. 21
    Árbol desde preorden e inorden
    8 minutos
  22. 22
    Árbol desde inorden y postorden
    8 minutos
  23. 23
    Árboles k-arios
    6 minutos
  24. 24
    Árboles B (parte 1)
    11 minutos
  25. 25
    Árboles B (parte 2)
    20 minutos
  26. 26
    Árboles B (parte 3)
    39 minutos