Lista Enlazada

¿Qué representa este TAD?

Una lista enlazada es una secuencia de nodos: cada uno guarda un valor y el enlace al siguiente. Puedes recorrerla para buscar, insertar o eliminar sin necesitar posiciones contiguas en memoria.

Prueba este ejemplo

En una Lista enlazada vacía carga 10, 20, 10 con Agregar varios. Buscar elemento con valor 10 debe informar las posiciones 1 y 3.

Qué observar · tres pasos

  1. Sigue los enlaces desde la cabeza, que es el primer nodo de la lista.
  2. Compara Insertar inicio con Insertar final; Agregar varios siempre agrega al final.
  3. Al eliminar, comprueba qué enlace cambia y qué nodo se libera. Eliminar repetidos retira todas las ocurrencias del valor indicado.

Ir a la visualización e ingresar estos datos

De la idea al resultado

  1. Prepara una operación y predice qué cambiará.
  2. Activa Paso a paso antes de ejecutar si quieres ver la traza; sin ese modo obtienes el resultado final.
  3. Relaciona el dibujo con la línea C resaltada: acaba de ejecutarse. Una condición puede no cambiar ningún nodo.
  4. Lee las pistas de Comprender y las pestañas de Resultados.

Paso anterior / Siguiente paso revisan la misma llamada. Pausar no deshace; cerrar Paso a paso muestra su final sin ejecutarla otra vez. Restablecer TAD (o Reiniciar, según el módulo) borra estructura e historial, no sólo el cursor.

Usa −, +, 100%, Encajar vista y Centrar inicio para acomodar el gráfico. El zoom y el desplazamiento se conservan durante los pasos; la memoria auxiliar es opcional.

Agregar varios valores en esta estructura

Disponible en Pila, Cola, Lista enlazada, Lista circular, ABB, AVL, Rojo-Negro y Montículo binario. En las listas agrega al final. No está disponible para Grafos, Hash, Cola de prioridad ni Sublista; Ordenamiento conserva su propia entrada de arreglo.

  1. Abre Agregar varios en Preparar. Escribe hasta 50 enteros separados por comas, por ejemplo 8, -3, 12. Se permiten espacios y signos; no decimales, posiciones vacías ni una coma final. Rango: −2147483648 a 2147483647.
  2. Revisa cantidad y orden. Se valida la lista completa antes de empezar. ABB, AVL y Rojo-Negro no aceptan repetidos, ni dentro del lote ni respecto al árbol actual. Pila, Cola, listas y Montículo sí los admiten.
  3. Elige Cargar valores para añadirlos en orden con resultado final, o Agregar paso a paso para estudiar cada inserción.
  4. En paso a paso, usa los controles del lote. Reproducir traza sólo reproduce el valor actual; Pausar detiene la reproducción. Al final, pulsa Siguiente valor para aceptar la siguiente inserción, o Finalizar lote al terminar la última.

Al terminar o detener un lote, edita la lista antes de iniciar otro. La vista previa conserva el orden solicitado; el resumen describe ese lote, no sustituye el estado actual tras otra operación o Restablecer TAD.

Detener lote conserva las operaciones ya aceptadas, incluida la actual, y descarta los valores pendientes. No es «deshacer todo». Si falla una operación durante el proceso, las anteriores no se revierten. Si la respuesta es incierta, usa Recargar estado e historial y comprueba qué se guardó antes de volver a cargar valores.

Palabras básicas para leer el dibujo
TAD
Tipo abstracto de dato: los datos y las operaciones permitidas sobre ellos.
Nodo
Elemento que guarda un valor y enlaces a otros elementos.
Puntero o enlace
Referencia que permite llegar a otro nodo. NULL indica que no apunta a un nodo.
Raíz, padre e hijo
La raíz inicia el árbol; un padre se conecta con sus hijos.
Tope, frente y atrás
Tope (TOP) en Pila; frente (FRONT) y atrás (BACK) en Cola son referencias a sus extremos.

Primera práctica de 5 minutos · Copiar, ampliar y exportar · Resolver dudas y errores · Atajos y referencia

Profundizar: objetivo, reglas y memoria

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

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.

Alcance de esta pantalla

Usa las operaciones disponibles en el selector. Los auxiliares C pueden no tener un botón propio.

Referencia de operaciones y datos de entrada

Operaciones de la aplicación y datos

Buscar elemento buscar_elemento
Valor (entero)
Eliminar elemento eliminar_elemento
Valor (entero)
Eliminar repetidos eliminar_repetidos
Valor (entero)
Insertar final insertar_final
Valor (entero)
Insertar inicio insertar_inicio
Valor (entero)
Limpiar limpiar
Sin datos adicionales.
Lista insertar elemento lista_insertar_elemento
Valor (entero); Posición (entero)

La API conserva buscar_posiciones, eliminar_final, eliminar_inicio, eliminar_posicion, eliminar_primero, insertar_elemento, insertar_posicion, mostrar, primero, ultimo. Estas operaciones no aparecen en el selector visible.

Los métodos C siguientes pueden incluir helpers, utilidades sin botón propio y llamadores equivalentes. Un bloque con varias funciones no cambia el nombre de la operación de la aplicación. Las vistas de memoria usan identidades simbólicas; tras free, sus registros históricos no son punteros utilizables.

Las posiciones de la API empiezan en 1. Insertar posición coloca el valor antes de esa posición; Insertar elemento permite antes/después según relative. Eliminar posición convierte la posición API a índice interno base 0. Buscar posiciones devuelve posiciones base 1. El alias eliminar_primero retira la primera coincidencia por valor, no la cabeza sin comparar. Los llamadores deben conservar estas conversiones.

Ejecutar operación crea una llamada; Anterior/Siguiente recorren la misma traza. Cerrar y reactivar Paso a paso no vuelven a ejecutar. Las consultas completadas pueden conservarse en el historial o journal aunque no muten la estructura; los rechazos no agregan llamadas exitosas. Restablecer TAD (o Reiniciar, según el módulo) borra la estructura y su historial.

Referencia avanzada por operación

Abre sólo el tema que estás estudiando. Estos detalles distinguen el contrato C, su representación visual y las funciones auxiliares de la aplicación.

Representación, enlaces y consultas
  • Secuencia lineal de nodos enlazados por referencias al siguiente.
  • En el simulador debes seguir el avance de punteros auxiliares para inserciones/eliminaciones por posición, verificando que *lista (HEAD) siempre conserve la conectividad.
  • Para limpiar, lista_limpiar desconecta la cabeza con q y la libera en cada vuelta.

Código fuente completo del TAD

Descarga el archivo C principal de Lista enlazada y su encabezado para estudiarlo o compilarlo en tu equipo.

Referencia: estructura del TAD en C
typedef struct NodoLista {
    int nro; /**< Dato entero almacenado. */
    struct NodoLista *sgte; /**< Enlace al siguiente nodo. */
} *Tlista;

Código C y llamadores equivalentes

Insertar al inicio · código C

Inserta nodo al inicio: enlaza el nuevo nodo antes del actual primero y actualiza la cabecera.

/**
 * @brief Reserva e inserta un nodo al inicio de la cadena.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @param[in] valor Dato entero a insertar; se admiten valores repetidos.
 * @post En éxito, la nueva cabeza contiene valor y enlaza con la cabeza anterior.
 * @note Si lista es NULL no hace nada. Si malloc falla, conserva la cadena y escribe un diagnóstico en stdout.
 */
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;
}
Insertar al final · código C

Recorre hasta el último nodo y conecta el nuevo elemento al final de la secuencia.

/**
 * @brief Reserva e inserta un nodo al final de la cadena.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @param[in] valor Dato entero a insertar; se admiten valores repetidos.
 * @post En éxito, la cadena vacía recibe una cabeza; en otra cadena cambia el enlace del último nodo.
 * @note Si lista es NULL no hace nada. Si malloc falla, conserva la cadena y escribe un diagnóstico en stdout.
 */
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;
    }
}
Insertar por posición · código C

Inserta por posición base según contrato del TAD, ajustando enlaces previo/siguiente en el punto objetivo.

/**
 * @brief Inserta al inicio para pos=1, o después del nodo en la posición base pos.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @param[in] valor Dato entero a insertar; se admiten valores repetidos.
 * @param[in] pos Posición base: 1 incluso en lista vacía, o 2..n si existe el nodo base.
 * @note pos=1 no significa insertar después del primer nodo: inserta al inicio.
 * @note Si lista es NULL o pos<=0, retorna sin reservar ni modificar la cadena.
 * @note Un fallo de malloc conserva la cadena y escribe un diagnóstico en stdout.
 * @note Si no existe la posición base, escribe un diagnóstico, libera el nodo temporal y conserva la cadena.
 */
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);
}
Buscar elemento · código C

Recorre toda la lista e imprime las posiciones de todas las coincidencias; si no encuentra ninguna, informa que el número no fue encontrado.

/**
 * @brief Recorre toda la cadena e imprime las posiciones de todas las coincidencias.
 * @param[in] lista Cabeza de la cadena por valor; NULL representa lista vacía.
 * @param[in] valor Dato buscado.
 * @post No modifica nodos ni enlaces; las posiciones impresas comienzan en 1.
 * @note Es void: comunica las coincidencias mediante stdout, no devuelve una colección C.
 * @note Si no hay coincidencias, incluida la lista vacía, imprime Numero no encontrado.
 */
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");
    }
}
Eliminar elemento · código C

Busca la primera ocurrencia, reconecta vecinos para excluir el nodo y libera su memoria.

/**
 * @brief Desconecta y libera únicamente la primera ocurrencia del valor.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @param[in] valor Dato cuya primera coincidencia se elimina.
 * @post Si hay coincidencia, reconecta la cabeza o el enlace anterior antes de free; las restantes ocurrencias se conservan.
 * @note Si lista es NULL, la cadena está vacía o no existe el valor, escribe un diagnóstico en stdout y no modifica la cadena.
 * @note No devuelve un estado de éxito: su tipo de retorno C es void.
 */
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");
}
Eliminar repetidos · código C

Elimina todas las ocurrencias del valor solicitado, reconecta la lista y libera cada nodo coincidente.

/**
 * @brief Desconecta y libera todas las ocurrencias del valor solicitado.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @param[in] valor Dato cuyas coincidencias se eliminan, incluso si solo hay una.
 * @post Conserva el orden y los nodos de los demás valores; no deja una copia del valor eliminado.
 * @note Si lista es NULL o la cadena está vacía, no modifica nodos. Imprime Valores eliminados también si no encontró coincidencias.
 * @note Es void: no devuelve un contador en C; el contador de la aplicación es información adicional del wrapper.
 */
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");
}
Limpiar · código C

Recorre la estructura liberando todos los nodos y deja el puntero raíz en estado nulo para reinicio seguro.

/**
 * @brief Desconecta y libera todos los nodos; deja la cabeza en NULL.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @post Cada nodo se desconecta de la cabeza antes de free(q); una cabeza inicialmente NULL permanece NULL.
 * @note Si lista es NULL retorna sin hacer nada. No escribe en stdout.
 * @note q es un alias local; después de free(q) su valor es indeterminado hasta la siguiente asignación. No se lee durante ese intervalo.
 */
void lista_limpiar(Tlista *lista) {
    if (lista == NULL) {
        return;
    }

    Tlista q;
    while (*lista != NULL) {
        q = *lista;
        *lista = q->sgte;
        free(q);
    }
}
Insertar elemento · código C

Inserta mediante un llamador que adapta la posición y la relación antes/después al contrato del TAD. Revisa esas conversiones en Referencia de operaciones; no confundas índice de arreglo con posición de la interfaz.

/**
 * @brief Inserta al inicio para pos=1, o después del nodo en la posición base pos.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @param[in] valor Dato entero a insertar; se admiten valores repetidos.
 * @param[in] pos Posición base: 1 incluso en lista vacía, o 2..n si existe el nodo base.
 * @note pos=1 no significa insertar después del primer nodo: inserta al inicio.
 * @note Si lista es NULL o pos<=0, retorna sin reservar ni modificar la cadena.
 * @note Un fallo de malloc conserva la cadena y escribe un diagnóstico en stdout.
 * @note Si no existe la posición base, escribe un diagnóstico, libera el nodo temporal y conserva la cadena.
 */
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);
}
Mostrar · código C

Recorre la estructura para construir una salida ordenada sin alterar enlaces internos.

/**
 * @brief Imprime todos los elementos de la lista.
 * @param[in] lista Lista a mostrar.
 * @pre Lista prestada viva y aciclica; contador de posiciones debe caber en int durante todo recorrido.
 * @note Imprime posicion desde 1 y dato por linea; lista NULL no imprime nada. No reserva/libera ni modifica nodos.
 */
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++;
    }
}
Insertar posición · código C

Adapta la posición de la interfaz, que comienza en 1, al contrato C de inserción. Observa qué nodo sirve de referencia y qué enlace se modifica.

/**
 * @brief Inserta al inicio para pos=1, o después del nodo en la posición base pos.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @param[in] valor Dato entero a insertar; se admiten valores repetidos.
 * @param[in] pos Posición base: 1 incluso en lista vacía, o 2..n si existe el nodo base.
 * @note pos=1 no significa insertar después del primer nodo: inserta al inicio.
 * @note Si lista es NULL o pos<=0, retorna sin reservar ni modificar la cadena.
 * @note Un fallo de malloc conserva la cadena y escribe un diagnóstico en stdout.
 * @note Si no existe la posición base, escribe un diagnóstico, libera el nodo temporal y conserva la cadena.
 */
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);
}
Eliminar primera coincidencia · código C

Elimina la primera coincidencia de un valor y recompone enlaces para mantener continuidad.

/**
 * @brief Desconecta y libera únicamente la primera ocurrencia del valor.
 * @param[in,out] lista Dirección de la variable cabeza del llamador; *lista puede ser NULL.
 * @param[in] valor Dato cuya primera coincidencia se elimina.
 * @post Si hay coincidencia, reconecta la cabeza o el enlace anterior antes de free; las restantes ocurrencias se conservan.
 * @note Si lista es NULL, la cadena está vacía o no existe el valor, escribe un diagnóstico en stdout y no modifica la cadena.
 * @note No devuelve un estado de éxito: su tipo de retorno C es void.
 */
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");
}
Buscar posiciones · código C

Recorre toda la lista y registra todas las posiciones donde aparece el valor buscado.

/**
 * @brief Recorre toda la cadena e imprime las posiciones de todas las coincidencias.
 * @param[in] lista Cabeza de la cadena por valor; NULL representa lista vacía.
 * @param[in] valor Dato buscado.
 * @post No modifica nodos ni enlaces; las posiciones impresas comienzan en 1.
 * @note Es void: comunica las coincidencias mediante stdout, no devuelve una colección C.
 * @note Si no hay coincidencias, incluida la lista vacía, imprime Numero no encontrado.
 */
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");
    }
}
Eliminar inicio · código C

Remueve la cabecera, mueve el inicio al siguiente nodo y libera el nodo anterior.

/**
 * @brief Desenlaza y libera el primer nodo.
 * @param lista Dirección de la cabeza que se actualiza.
 * @param valor Salida del dato eliminado; no debe ser NULL.
 * @return 1 al eliminar; 0 ante lista vacía o punteros NULL.
 * @pre Lista propia viva y aciclica; lista es direccion escribible de cabeza y valor int externo escribible sin solaparse con cabeza/nodos.
 * @note Guardas NULL/vacio/indice inexistente retornan 0 sin escribir valor ni liberar. Exito retorna 1, copia dato, cambia enlaces y libera un nodo; aliases al nodo quedan invalidos. No reserva ni imprime.
 */
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;
}
Eliminar final · código C

Recorre hasta el último nodo, conserva su valor, lo desconecta y libera su memoria. El dato de salida es distinto del indicador de éxito.

/**
 * @brief Desenlaza y libera el último nodo.
 * @param lista Dirección de la cabeza que puede actualizarse.
 * @param valor Salida del dato eliminado; no debe ser NULL.
 * @return 1 al eliminar; 0 ante lista vacía o punteros NULL.
 * @pre Lista propia viva y aciclica; lista es direccion escribible de cabeza y valor int externo escribible sin solaparse con cabeza/nodos.
 * @note Guardas NULL/vacio/indice inexistente retornan 0 sin escribir valor ni liberar. Exito retorna 1, copia dato, cambia enlaces y libera un nodo; aliases al nodo quedan invalidos. No reserva ni imprime.
 */
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;
}
Eliminar posición · código C

Retira el nodo de la posición pedida y escribe su valor en una salida. El C usa posición base 0; el llamador convierte la posición de interfaz base 1. Un índice inválido no elimina nodos.

/**
 * @brief Desenlaza y libera el nodo en un índice basado en cero.
 * @param lista Dirección de la cabeza.
 * @param posicion Índice: cero identifica el primer nodo.
 * @param valor Salida del dato eliminado; no debe ser NULL.
 * @return 1 al eliminar; 0 ante índice fuera de rango o punteros NULL.
 * @pre Lista propia viva y aciclica; lista es direccion escribible de cabeza y valor int externo escribible sin solaparse con cabeza/nodos.
 * @note Guardas NULL/vacio/indice inexistente retornan 0 sin escribir valor ni liberar. Exito retorna 1, copia dato, cambia enlaces y libera un nodo; aliases al nodo quedan invalidos. No reserva ni imprime.
 * @note Posicion basada en cero; negativa retorna 0. No es el contrato posicional de lista_insertar_elemento.
 */
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;
}
Primero · código C

Consulta el primer dato mediante un parámetro de salida, sin cambiar enlaces. El retorno indica éxito, no el valor consultado.

/**
 * @brief Consulta el primer dato sin modificar enlaces.
 * @param lista Cabeza de la lista.
 * @param valor Salida del dato consultado.
 * @return 1 si existe el nodo y valor no es NULL; 0 en otro caso.
 * @pre Lista prestada viva y aciclica; valor es int externo escribible sin solaparse con nodos.
 * @note Lista NULL o valor NULL retorna 0 sin escritura. Exito retorna 1 y escribe dato; no reserva/libera/imprime ni modifica enlaces bajo precondiciones.
 */
int lista_primero(Tlista lista, int *valor) {
    if (lista == NULL || valor == NULL) return 0;
    *valor = lista->nro;
    return 1;
}
Último · código C

Recorre la lista para consultar el último dato mediante un parámetro de salida. No elimina ese nodo; el retorno indica si pudo obtenerlo.

/**
 * @brief Consulta el último dato sin modificar enlaces.
 * @param lista Cabeza de la lista.
 * @param valor Salida del dato consultado.
 * @return 1 si existe el nodo y valor no es NULL; 0 en otro caso.
 * @pre Lista prestada viva y aciclica; valor es int externo escribible sin solaparse con nodos.
 * @note Lista NULL o valor NULL retorna 0 sin escritura. Exito retorna 1 y escribe dato; no reserva/libera/imprime ni modifica enlaces bajo precondiciones.
 */
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;
}

Ir a la visualización