Lista Enlazada
Descripcion del TAD
Secuencia lineal de nodos enlazados por referencias al siguiente. En el simulador debes seguir el avance de punteros auxiliares para inserciones/eliminaciones por posicion, verificando que el HEAD siempre conserve la conectividad de la lista. La Lista Enlazada representa una secuencia dinamica de nodos conectados por punteros. Es clave entender desplazamiento por posicion, manejo de cabecera y casos borde en insercion/eliminacion.
Objetivo
Mantener la conectividad al buscar, insertar y eliminar.
Estrategia
Seguir HEAD, anterior y actual.
Invariante
Cada nodo es alcanzable una vez desde HEAD y el último apunta a NULL.
Memoria dinámica
Guardar el enlace siguiente antes de liberar.
Errores frecuentes
- Perder HEAD
- Sobrescribir un enlace antes de conservar el resto
Glosario contextual
- Nodo
- Objeto dinámico con datos y uno o más enlaces.
- Enlace
- Campo puntero que conecta objetos.
- Alias
- Dos punteros que designan el mismo objeto.
- LIFO
- El último en entrar es el primero en salir.
- FIFO
- El primero en entrar es el primero en salir.
- Prioridad
- Criterio de selección independiente del orden físico.
- Circularidad
- El último enlace vuelve al inicio.
- malloc
- Reserva memoria; puede devolver NULL.
- free
- Libera una reserva que deja de ser válida.
Controles de ejecucion paso a paso
- Checkbox Interpretar codigo paso a paso: activado muestra toda la traza; desactivado aplica solo el resultado final.
- Botones de ejecucion: Reproducir y Reiniciar.
- Navegacion por traza: Anterior paso y Siguiente paso.
- Velocidad de simulacion: slider de -2x a +2x (0.00x = 1.00x real).
- En modo rapido (checkbox desactivado), el resultado visual final debe coincidir con el ultimo estado de la traza interpretada.
- Al llegar al ultimo paso, Siguiente paso se bloquea hasta cambiar entradas/operacion; Anterior paso se habilita solo cuando ya avanzaste.
Operaciones soportadas
- lista_insertar_inicio
- lista_insertar_final
- lista_insertar_elemento
- lista_buscar_elemento
- lista_mostrar
- lista_eliminar_elemento
- lista_eliminar_repetidos
- lista_eliminar_elemento
Operaciones pendientes / restricciones
- lista_insertar_elemento usa modo relativo: -1 (antes) o 0 (despues).
Estructura del TAD en C
typedef struct NodoLista {
int nro;
struct NodoLista *sgte;
} *Tlista;
Metodos del TAD en C
Codigo C: insertar_inicio
Inserta nodo al inicio: enlaza el nuevo nodo antes del actual primero y actualiza la cabecera.
/**
* @brief Inserta un nuevo nodo al inicio de la lista.
* @param lista Puntero a la lista.
* @param valor Valor entero a insertar.
*/
void lista_insertar_inicio(Tlista *lista, int valor) {
if (lista == NULL) {
return;
}
Tlista q = CrearNodoLista(valor);
if (q == NULL) {
return;
}
q->sgte = *lista;
*lista = q;
}
Codigo C: insertar_final
Recorre hasta el ultimo nodo y conecta el nuevo elemento al final de la secuencia.
/**
* @brief Inserta un nuevo nodo al final de la lista.
* @param lista Puntero a la lista.
* @param valor Valor entero a insertar.
*/
void lista_insertar_final(Tlista *lista, int valor) {
if (lista == NULL) {
return;
}
Tlista q = CrearNodoLista(valor);
if (q == NULL) {
return;
}
if (*lista == NULL) {
*lista = q;
} else {
Tlista t = *lista;
while (t->sgte != NULL) {
t = t->sgte;
}
t->sgte = q;
}
}
Codigo C: lista_insertar_elemento
Inserta por posicion base segun contrato del TAD, ajustando enlaces previo/siguiente en el punto objetivo.
/**
* @brief Inserta un nodo en una posición dada.
* @param lista Puntero a la lista.
* @param valor Valor a insertar.
* @param pos Posición base para la inserción.
*/
void lista_insertar_elemento(Tlista *lista, int valor, int pos) {
if (lista == NULL || pos <= 0) {
return;
}
Tlista q = CrearNodoLista(valor);
if (q == NULL) {
return;
}
/*
* Contrato actual:
* - pos == 1: inserta al inicio.
* - pos > 1 : inserta despues del nodo en posicion base `pos`.
*/
if (pos == 1) {
q->sgte = *lista;
*lista = q;
return;
}
Tlista t = *lista;
int i = 1;
while (t != NULL) {
if (i == pos) {
q->sgte = t->sgte;
t->sgte = q;
return;
}
t = t->sgte;
i++;
}
printf(" Error...Posicion no encontrada..!\n");
free(q);
}
Codigo C: buscar_elemento
Recorre secuencialmente comparando valores hasta encontrar coincidencia o agotar la lista.
/**
* @brief Busca un elemento en la lista e imprime su posición.
* @param lista Lista en la que se busca.
* @param valor Valor a buscar.
*/
void lista_buscar_elemento(Tlista lista, int valor) {
int i = 1, encontrado = 0;
Tlista q = lista;
while (q != NULL) {
if (q->nro == valor) {
printf("\n Encontrado en la posicion %d\n", i);
encontrado = 1;
}
q = q->sgte;
i++;
}
if (!encontrado) {
printf("\n Numero no encontrado..\n");
}
}
Codigo C: mostrar
Recorre la estructura para construir una salida ordenada sin alterar enlaces internos.
/**
* @brief Muestra los elementos de la lista con su posición.
* @param lista Lista a mostrar.
*/
void lista_mostrar(Tlista lista) {
int i = 1;
Tlista aux = lista;
while (aux != NULL) {
printf(" %d) %d\n", i, aux->nro);
aux = aux->sgte;
i++;
}
}
Codigo C: eliminar_elemento
Busca la primera ocurrencia, reconecta vecinos para excluir el nodo y libera su memoria.
/**
* @brief Elimina la primera ocurrencia de un valor en la lista.
* @param lista Puntero a la lista.
* @param valor Valor a eliminar.
*/
void lista_eliminar_elemento(Tlista *lista, int valor) {
if (lista == NULL || *lista == NULL) {
printf(" Valor no encontrado o lista vacia.\n");
return;
}
Tlista p = *lista, ant = NULL;
while (p != NULL) {
if (p->nro == valor) {
if (p == *lista) {
*lista = p->sgte;
} else {
ant->sgte = p->sgte;
}
free(p);
return;
}
ant = p;
p = p->sgte;
}
printf(" Valor no encontrado o lista vacia.\n");
}
Codigo C: eliminar_repetidos
Detecta duplicados durante el recorrido, elimina ocurrencias adicionales y conserva solo una por valor.
/**
* @brief Elimina todas las ocurrencias de un valor en la lista.
* @param lista Puntero a la lista.
* @param valor Valor a eliminar.
*/
void lista_eliminar_repetidos(Tlista *lista, int valor) {
if (lista == NULL || *lista == NULL) {
printf("\n\n Valores eliminados..\n");
return;
}
Tlista q = *lista, ant = NULL;
while (q != NULL) {
if (q->nro == valor) {
Tlista temp = q;
if (q == *lista) {
*lista = q->sgte;
q = *lista;
} else {
ant->sgte = q->sgte;
q = ant->sgte;
}
free(temp);
} else {
ant = q;
q = q->sgte;
}
}
printf("\n\n Valores eliminados..\n");
}
Codigo C: limpiar
Recorre la estructura liberando todos los nodos y deja el puntero raiz en estado nulo para reinicio seguro.
/* Liberacion completa para dejar lista vacia. */
while (*lista != NULL) {
int head = (*lista)->nro;
lista_eliminar_elemento(lista, head);
}
Codigo C: insertar_elemento
Este metodo del TAD Lista Enlazada debe interpretarse respetando condicionales, ciclos, returns y actualizacion del estado visual segun el flujo real del codigo C.
/**
* @brief Inserta un nodo en una posición dada.
* @param lista Puntero a la lista.
* @param valor Valor a insertar.
* @param pos Posición base para la inserción.
*/
void lista_insertar_elemento(Tlista *lista, int valor, int pos) {
if (lista == NULL || pos <= 0) {
return;
}
Tlista q = CrearNodoLista(valor);
if (q == NULL) {
return;
}
/*
* Contrato actual:
* - pos == 1: inserta al inicio.
* - pos > 1 : inserta despues del nodo en posicion base `pos`.
*/
if (pos == 1) {
q->sgte = *lista;
*lista = q;
return;
}
Tlista t = *lista;
int i = 1;
while (t != NULL) {
if (i == pos) {
q->sgte = t->sgte;
t->sgte = q;
return;
}
t = t->sgte;
i++;
}
printf(" Error...Posicion no encontrada..!\n");
free(q);
}
Codigo C: insertar_posicion
Este metodo del TAD Lista Enlazada debe interpretarse respetando condicionales, ciclos, returns y actualizacion del estado visual segun el flujo real del codigo C.
/**
* @brief Inserta un nodo en una posición dada.
* @param lista Puntero a la lista.
* @param valor Valor a insertar.
* @param pos Posición base para la inserción.
*/
void lista_insertar_elemento(Tlista *lista, int valor, int pos) {
if (lista == NULL || pos <= 0) {
return;
}
Tlista q = CrearNodoLista(valor);
if (q == NULL) {
return;
}
/*
* Contrato actual:
* - pos == 1: inserta al inicio.
* - pos > 1 : inserta despues del nodo en posicion base `pos`.
*/
if (pos == 1) {
q->sgte = *lista;
*lista = q;
return;
}
Tlista t = *lista;
int i = 1;
while (t != NULL) {
if (i == pos) {
q->sgte = t->sgte;
t->sgte = q;
return;
}
t = t->sgte;
i++;
}
printf(" Error...Posicion no encontrada..!\n");
free(q);
}
Codigo C: eliminar_primero
Elimina la primera coincidencia de un valor y recompone enlaces para mantener continuidad.
/**
* @brief Elimina la primera ocurrencia de un valor en la lista.
* @param lista Puntero a la lista.
* @param valor Valor a eliminar.
*/
void lista_eliminar_elemento(Tlista *lista, int valor) {
if (lista == NULL || *lista == NULL) {
printf(" Valor no encontrado o lista vacia.\n");
return;
}
Tlista p = *lista, ant = NULL;
while (p != NULL) {
if (p->nro == valor) {
if (p == *lista) {
*lista = p->sgte;
} else {
ant->sgte = p->sgte;
}
free(p);
return;
}
ant = p;
p = p->sgte;
}
printf(" Valor no encontrado o lista vacia.\n");
}
Codigo C: buscar_posiciones
Recorre toda la lista y registra todas las posiciones donde aparece el valor buscado.
/**
* @brief Busca un elemento en la lista e imprime su posición.
* @param lista Lista en la que se busca.
* @param valor Valor a buscar.
*/
void lista_buscar_elemento(Tlista lista, int valor) {
int i = 1, encontrado = 0;
Tlista q = lista;
while (q != NULL) {
if (q->nro == valor) {
printf("\n Encontrado en la posicion %d\n", i);
encontrado = 1;
}
q = q->sgte;
i++;
}
if (!encontrado) {
printf("\n Numero no encontrado..\n");
}
}
Codigo C: eliminar_inicio
Remueve la cabecera, mueve el inicio al siguiente nodo y libera el nodo anterior.
int lista_eliminar_inicio(Tlista *lista, int *valor) {
Tlista eliminado;
if (lista == NULL || *lista == NULL || valor == NULL) return 0;
eliminado = *lista;
*valor = eliminado->nro;
*lista = eliminado->sgte;
free(eliminado);
return 1;
}
Codigo C: eliminar_final
Este metodo del TAD Lista Enlazada debe interpretarse respetando condicionales, ciclos, returns y actualizacion del estado visual segun el flujo real del codigo C.
int lista_eliminar_final(Tlista *lista, int *valor) {
Tlista actual, anterior = NULL;
if (lista == NULL || *lista == NULL || valor == NULL) return 0;
actual = *lista;
while (actual->sgte != NULL) { anterior = actual; actual = actual->sgte; }
*valor = actual->nro;
if (anterior == NULL) *lista = NULL; else anterior->sgte = NULL;
free(actual);
return 1;
}
Codigo C: eliminar_posicion
Este metodo del TAD Lista Enlazada debe interpretarse respetando condicionales, ciclos, returns y actualizacion del estado visual segun el flujo real del codigo C.
int lista_eliminar_posicion(Tlista *lista, int posicion, int *valor) {
Tlista actual, anterior = NULL;
int indice = 0;
if (lista == NULL || posicion < 0 || valor == NULL) return 0;
actual = *lista;
while (actual != NULL && indice < posicion) { anterior = actual; actual = actual->sgte; indice++; }
if (actual == NULL) return 0;
*valor = actual->nro;
if (anterior == NULL) *lista = actual->sgte; else anterior->sgte = actual->sgte;
free(actual);
return 1;
}
Codigo C: invertir
Reasigna enlaces nodo a nodo para invertir la direccion completa de la lista.
void lista_invertir(Tlista *lista) {
Tlista anterior = NULL, actual, siguiente;
if (lista == NULL) return;
actual = *lista;
while (actual != NULL) {
siguiente = actual->sgte;
actual->sgte = anterior;
anterior = actual;
actual = siguiente;
}
*lista = anterior;
}
Codigo C: primero
Este metodo del TAD Lista Enlazada debe interpretarse respetando condicionales, ciclos, returns y actualizacion del estado visual segun el flujo real del codigo C.
int lista_primero(Tlista lista, int *valor) {
if (lista == NULL || valor == NULL) return 0;
*valor = lista->nro;
return 1;
}
Codigo C: ultimo
Este metodo del TAD Lista Enlazada debe interpretarse respetando condicionales, ciclos, returns y actualizacion del estado visual segun el flujo real del codigo C.
int lista_ultimo(Tlista lista, int *valor) {
if (lista == NULL || valor == NULL) return 0;
while (lista->sgte != NULL) lista = lista->sgte;
*valor = lista->nro;
return 1;
}