Una lista secuencial es una estructura de datos lineal que almacena elementos en posiciones de memoria contiguas. Esta estructura permite un acceso rápido a cualquier elemento mediante su índice, pero tiene desventajas en operaciones de inserción y eliminación que requieren movimiento de elementos. A continuación, exploraremos su implementación en C.
Estructuras de Datos Fundamentales
Lista Estática
Utiliza un arreglo de tamaño fijo definido en tiempo de compilación. Su principal limitación es que no permite redimensionamiento dinámico.
#define MAX_ELEMENTOS 50
typedef int TipoDato;
typedef struct {
TipoDato datos[MAX_ELEMENTOS];
int contador;
} ListaEstatica;
Lista Dinámica
Emplea memoria asignaad dinámicamente, lo que permite ajustar el tamaño según las necesidades durante la ejecución.
typedef int TipoDato;
typedef struct {
TipoDato* elementos;
int longitud;
int capacidad;
} ListaDinamica;
Operaciones Fundamentales
Inicialización
Prepara la estructura para su uso estableciendo punteros a NULL y contadores a cero.
#include <stdio.h>
#include <stdlib.h>
void inicializarLista(ListaDinamica* lista) {
lista->elementos = NULL;
lista->longitud = 0;
lista->capacidad = 0;
}
Gestión de Memoria
Controla la expansión automática cuando se requiere más espacio de almacenamiento.
void verificarCapacidad(ListaDinamica* lista) {
if (lista->longitud == lista->capacidad) {
int nuevaCapacidad = lista->capacidad == 0 ? 4 : lista->capacidad * 2;
TipoDato* nuevoArreglo = realloc(lista->elementos, nuevaCapacidad * sizeof(TipoDato));
if (nuevoArreglo == NULL) {
fprintf(stderr, "Error en la asignación de memoria\n");
exit(EXIT_FAILURE);
}
lista->elementos = nuevoArreglo;
lista->capacidad = nuevaCapacidad;
}
}
Inserción en Posición Específica
Desplaza los elementos existentes para crear espacio en la posición deseada.
void insertarEnPosicion(ListaDinamica* lista, int posicion, TipoDato valor) {
if (posicion < 0 || posicion > lista->longitud) {
fprintf(stderr, "Posición fuera de rango\n");
return;
}
verificarCapacidad(lista);
for (int i = lista->longitud; i > posicion; i--) {
lista->elementos[i] = lista->elementos[i-1];
}
lista->elementos[posicion] = valor;
lista->longitud++;
}
Eliminación de Elementos
Remueve un elemento y reorganiza la estructura manteniendo la continuidad.
void eliminarDePosicion(ListaDinamica* lista, int posicion) {
if (posicion < 0 || posicion >= lista->longitud) {
fprintf(stderr, "Índice no válido\n");
return;
}
for (int i = posicion; i < lista->longitud - 1; i++) {
lista->elementos[i] = lista->elementos[i+1];
}
lista->longitud--;
}
Búsqueda de Elementos
Recorre secuencialmente la estructura hasta encontrar el elemento buscado.
int buscarElemento(ListaDinamica* lista, TipoDato objetivo) {
for (int idx = 0; idx < lista->longitud; idx++) {
if (lista->elementos[idx] == objetivo) {
return idx;
}
}
return -1;
}
Operaciones de Extremos
Inserción al Final
Añade un nuevo elemento incrementando el contador de elementos.
void agregarAlFinal(ListaDinamica* lista, TipoDato nuevoValor) {
verificarCapacidad(lista);
lista->elementos[lista->longitud] = nuevoValor;
lista->longitud++;
}
Eliminación del Final
Reduce el contador de elementos sin necesidad de desplazar datos.
void removerUltimo(ListaDinamica* lista) {
if (lista->longitud > 0) {
lista->longitud--;
}
}
Visualización del Contenido
Muestra todos los elementos almacenados en formato legible.
void mostrarLista(ListaDinamica* lista) {
printf("Contenido: ");
for (int pos = 0; pos < lista->longitud; pos++) {
printf("%d ", lista->elementos[pos]);
}
printf("\n");
}
Código Completo Integrado
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int TipoDato;
typedef struct {
TipoDato* elementos;
int longitud;
int capacidad;
} ListaDinamica;
void inicializarLista(ListaDinamica* lista);
void verificarCapacidad(ListaDinamica* lista);
void insertarEnPosicion(ListaDinamica* lista, int posicion, TipoDato valor);
void eliminarDePosicion(ListaDinamica* lista, int posicion);
int buscarElemento(ListaDinamica* lista, TipoDato objetivo);
void agregarAlFinal(ListaDinamica* lista, TipoDato nuevoValor);
void removerUltimo(ListaDinamica* lista);
void mostrarLista(ListaDinamica* lista);
void liberarLista(ListaDinamica* lista);
void inicializarLista(ListaDinamica* lista) {
lista->elementos = NULL;
lista->longitud = 0;
lista->capacidad = 0;
}
void verificarCapacidad(ListaDinamica* lista) {
if (lista->longitud == lista->capacidad) {
int nuevaCapacidad = lista->capacidad == 0 ? 4 : lista->capacidad * 2;
TipoDato* nuevoArreglo = realloc(lista->elementos, nuevaCapacidad * sizeof(TipoDato));
if (nuevoArreglo == NULL) {
fprintf(stderr, "Error en asignación de memoria\n");
exit(EXIT_FAILURE);
}
lista->elementos = nuevoArreglo;
lista->capacidad = nuevaCapacidad;
}
}
void insertarEnPosicion(ListaDinamica* lista, int posicion, TipoDato valor) {
assert(posicion >= 0 && posicion <= lista->longitud);
verificarCapacidad(lista);
for (int i = lista->longitud; i > posicion; i--) {
lista->elementos[i] = lista->elementos[i-1];
}
lista->elementos[posicion] = valor;
lista->longitud++;
}
void eliminarDePosicion(ListaDinamica* lista, int posicion) {
assert(posicion >= 0 && posicion < lista->longitud);
for (int i = posicion; i < lista->longitud - 1; i++) {
lista->elementos[i] = lista->elementos[i+1];
}
lista->longitud--;
}
int buscarElemento(ListaDinamica* lista, TipoDato objetivo) {
for (int idx = 0; idx < lista->longitud; idx++) {
if (lista->elementos[idx] == objetivo) {
return idx;
}
}
return -1;
}
void agregarAlFinal(ListaDinamica* lista, TipoDato nuevoValor) {
verificarCapacidad(lista);
lista->elementos[lista->longitud] = nuevoValor;
lista->longitud++;
}
void removerUltimo(ListaDinamica* lista) {
assert(lista->longitud > 0);
lista->longitud--;
}
void mostrarLista(ListaDinamica* lista) {
printf("Contenido: ");
for (int pos = 0; pos < lista->longitud; pos++) {
printf("%d ", lista->elementos[pos]);
}
printf("\n");
}
void liberarLista(ListaDinamica* lista) {
free(lista->elementos);
lista->elementos = NULL;
lista->longitud = 0;
lista->capacidad = 0;
}
Ejemplo de Prueba
int main() {
ListaDinamica miLista;
inicializarLista(&miLista);
agregarAlFinal(&miLista, 10);
agregarAlFinal(&miLista, 20);
agregarAlFinal(&miLista, 30);
mostrarLista(&miLista);
insertarEnPosicion(&miLista, 1, 15);
mostrarLista(&miLista);
eliminarDePosicion(&miLista, 0);
mostrarLista(&miLista);
int indice = buscarElemento(&miLista, 20);
printf("Encontrado en posición: %d\n", indice);
liberarLista(&miLista);
return 0;
}