Forward Star Encadenado: Implementación Optimizada de Listas de Adyacencia

Necesidad de estructuras eficientes para grafos

El almacenamiento de grafos es fudnamental en algoritmos. Las matrices de adyacencia consumen O(n²) espacio, resultando ineficientes para grafos dispersos. Las listas de adyacencia tradicionales optimizan espacio pero introducen complejidad con punteros. El Forward Star Encadenado resuelve esto usando arreglos para simular enlaces, manteniendo eficiencia espacial O(∣V∣+∣E∣) sin manipulación directa de puntreos.

Diseño de la estructura

struct Arista {
    int destino;   // Nodo destino
    int peso;      // Peso de la arista
    int siguiente; // Índice de la próxima arista
} aristas[10005];  // Almacenamiento de aristas

int cabeza[105];   // cabeza[i]: primera arista del nodo i
int contador = 0;  // Contador de aristas

Inicialización

memset(cabeza, -1, sizeof(cabeza));
contador = 0;

Inserción de aristas

Nuevas aristas se añaden mediante inserción frontal:

void agregar_arista(int origen, int destino, int peso) {
    aristas[contador].destino = destino;
    aristas[contador].peso = peso;
    aristas[contador].siguiente = cabeza[origen];
    cabeza[origen] = contador;
    contador++;
}

Manejo de grafos no dirigidos

agregar_arista(x, y, peso);
agregar_arista(y, x, peso);

Recorrido de la estructura

void recorrer_grafo() {
    for (int nodo = 1; nodo <= n; nodo++) {
        for (int idx = cabeza[nodo]; idx != -1; idx = aristas[idx].siguiente) {
            int vecino = aristas[idx].destino;
            int peso_arista = aristas[idx].peso;
            cout << nodo << " → " << vecino << " (" << peso_arista << ")\t";
        }
        cout << endl;
    }
}

Caso demostrativo

Entrada:

4 5
1 2 5
1 4 3
2 3 8
2 4 12
3 4 9

Salida:

1 → 4 (3)    1 → 2 (5)
2 → 4 (12)   2 → 3 (8)    2 → 1 (5)
3 → 4 (9)    3 → 2 (8)
4 → 3 (9)    4 → 2 (12)   4 → 1 (3)

Implementación completa

#include <iostream>
#include <cstring>
using namespace std;

struct Arista { /* Definición previa */ };
Arista aristas[10005];
int cabeza[105];
int contador, n, m;

void agregar_arista(int x, int y, int w) { /* Definición previa */ }

void recorrer_grafo() { /* Definición previa */ }

int main() {
    cin >> n >> m;
    memset(cabeza, -1, sizeof(cabeza));
    contador = 0;
    
    while (m--) {
        int x, y, w;
        cin >> x >> y >> w;
        agregar_arista(x, y, w);
        agregar_arista(y, x, w);
    }
    recorrer_grafo();
    return 0;
}

Ventajas y limitaciones

Ventajas

  • Espacio óptimo: O(∣V∣+∣E∣)
  • Elimina riesgos de manejo manual de memoria
  • Inserción en tiempo constante O(1)

Limitaciones

  • Orden inverso en recorridos
  • Asignación estática de memoria

Etiquetas: forward-star lista-adyacencia grafos estructuras-datos C++

Publicado el 7-30 02:03