4 - Nodo base en C

Elementos fundamentales

El diseño del nodo y los punteros de control determinan la flexibilidad y seguridad de cualquier lista enlazada. Entender cómo declararlos en C, cómo exponerlos en una cabecera y cómo separarlos en archivos es un paso obligado antes de implementar operaciones complejas.

4.1 Definición del struct base

Partimos de un struct que represente el valor almacenado y los enlaces disponibles. Adaptamos los campos según el tipo de lista; aquí mostramos la forma más común.

typedef struct Nodo {
  int valor;
  struct Nodo *sig;
} Nodo;

El typedef evita repetir struct Nodo y permite escribir simplemente Nodo. El tipo de valor puede ser un entero, una estructura compleja o un puntero genérico.

4.2 Puntero a cabeza (head)

El puntero cabeza es la entrada oficial a la lista. Se almacena fuera del nodo para mantener control sobre el conjunto completo.

typedef struct {
  Nodo *cabeza;
} ListaSimple;

void lista_insertar_inicio(ListaSimple *lista, int valor) {
  Nodo *n = malloc(sizeof(Nodo));
  if (!n) return;
  n->valor = valor;
  n->sig = lista->cabeza;
  lista->cabeza = n;
}

El puntero a cabeza permite insertar y eliminar al inicio sin recorrer todo. Siempre debe inicializarse en NULL y actualizarse cada vez que la lista queda vacía.

4.3 Puntero a cola (tail)

Agregar un puntero cola (tail) acelera las inserciones al final. Se utiliza junto con cabeza cuando la estructura necesita operar en ambos extremos.

typedef struct {
  Nodo *cabeza;
  Nodo *cola;
} ListaConCola;

void lista_insertar_final(ListaConCola *lista, int valor) {
  Nodo *n = malloc(sizeof(Nodo));
  if (!n) return;
  n->valor = valor;
  n->sig = NULL;
  if (!lista->cabeza) {
    lista->cabeza = lista->cola = n;
    return;
  }
  lista->cola->sig = n;
  lista->cola = n;
}

El puntero a cola evita recorrer la lista para insertar al final. La condición especial es cuando la lista está vacía: ambos punteros deben apuntar al nuevo nodo.

4.4 Diferencias entre tipos de listas

El struct base se adapta según la variante elegida. A continuación se muestra una comparativa rápida:

Tipo Campos adicionales Ventaja Coste
Simple sig Menor uso de memoria No se puede retroceder
Doble sig, ant Recorridos bidireccionales Duplicación de punteros
Circular sig conectando al inicio Recorridos continuos sin comprobaciones de NULL Mayor atención para terminar ciclos

4.5 Organización en CLion

Separar el nodo base y las operaciones en archivos .h y .c permite mantener un proyecto ordenado. En CLion lo habitual es tener:

  • lista.h: declara el struct y las funciones disponibles.
  • lista.c: implementa la lógica, incluidos head y tail.
  • main.c: actúa como banco de pruebas.
/* lista.h */
#ifndef LISTA_H
#define LISTA_H

typedef struct Nodo {
  int valor;
  struct Nodo *sig;
} Nodo;

typedef struct {
  Nodo *cabeza;
  Nodo *cola;
} Lista;

void lista_insertar_inicio(Lista *lista, int valor);
void lista_insertar_final(Lista *lista, int valor);
void lista_limpiar(Lista *lista);

#endif

Esta organización ayuda a reutilizar el nodo base en diferentes ejercicios y facilita la navegación dentro del IDE.