Laboratorio de árboles y montículos en C
ABB
Acerca de esta estructura
Árbol Binario de Búsqueda sin duplicados.
1 Preparar
Ejemplos guiados
Los ejemplos construyen el estado mediante operaciones públicas reales.
2 Predecir
Prepara una traza para predecir una condición aún no ejecutada.
Practica anticipando una condición C antes de revelar su resultado: elige Insertar y un valor, activa Paso a paso y pulsa Ejecutar operación. Responde Verdadero o Falso; NULL indica ausencia de un nodo referenciado.
Comprobar u omitir avanza varias instrucciones hasta esa decisión; Siguiente paso avanza solo una instrucción. El estado visible es el anterior a la decisión.
Durante un lote, la predicción y los controles individuales quedan bloqueados para no mezclar operaciones. Finaliza el lote o pulsa Detener lote y prepara una operación individual. Detener conserva la operación ya aceptada y descarta las pendientes.
Progreso conceptual de esta sesión: 0 aciertos de 0 intentos.
3 Ejecutar y visualizar
Código C: Insertar
/**
* @brief Inserta un valor en el árbol binario de búsqueda.
* @param nodo Puntero a la raíz del árbol.
* @param valor Valor entero.
* @return Raíz actualizada; NULL si el árbol estaba vacío y malloc falla.
* @note Si falla la reserva en un subárbol, se conserva la raíz existente sin insertar el valor.
* @note El arbol debe ser un ABB valido y aciclico. Un duplicado conserva la misma raiz sin reservar otro nodo. Asigne el retorno a la raiz del llamador; los enlaces internos se modifican. El nuevo nodo se inicializa antes de enlazarlo.
*/
ABBNodo* abb_insertar(ABBNodo* nodo, int valor) {
if (nodo == NULL) {
ABBNodo* nuevo = malloc(sizeof *nuevo);
if (nuevo == NULL) {
return NULL;
}
nuevo->valor = valor;
nuevo->izquierdo = nuevo->derecho = NULL;
return nuevo;
}
if (valor < nodo->valor)
nodo->izquierdo = abb_insertar(nodo->izquierdo, valor);
else if (valor > nodo->valor)
nodo->derecho = abb_insertar(nodo->derecho, valor);
return nodo;
}3 Controlar la ejecución
Actual: +0.00x (1.00x real)
Función: — · Profundidad: — · Fase: — · Concepto: —
Paso: 0/0
4 Comprender
Referencia completa de la estructura
Árbol binario de búsqueda sin duplicados: todo valor menor va al subárbol izquierdo y todo valor mayor al derecho. En la simulación revisa la ruta de comparaciones y confirma que la propiedad de orden se preserve después de cada inserción o eliminación. Buscar retorna un puntero prestado o NULL en C; la interfaz expone encontrado o no encontrado como booleano, sin error por ausencia. El llamador equivalente mostrado contextualiza esa conversión y no agrega otro método al C/H descargado. Mínimo y máximo recorren enlaces con while, sin recursión ni mutación; retornan un alias prestado. En C, árbol vacío retorna NULL; el wrapper consulta el TAD y convierte ese retorno en un error de interfaz. En ABB, altura cuenta niveles: vacío 0 y hoja 1. altIzq y altDer son locales int de cada invocación; durante su inicializador recursivo están en ámbito, sin inicializar. El padre conserva sus locales mientras espera al hijo. La altura visita todo el árbol en O(n), con O(h) marcos recursivos, sin cambiar enlaces ni imprimir. La interfaz rechaza duplicados y eliminaciones ausentes; el TAD C conserva el árbol en esos casos. Asigna a la raíz el retorno de insertar/eliminar. liberarArbol recibe la raíz por valor: después de liberar, el llamador debe ponerla a NULL. Durante Limpiar, free termina primero las vidas de hijos y después del padre; sus alias se muestran como identidades históricas con valor indeterminado, nunca como direcciones utilizables. El SVG representa reservas vivas y no afirma que el C haya puesto sus enlaces a NULL. El retorno es void y la asignación NULL del main es una instrucción posterior. Durante Eliminar, la llamada recursiva no publica enlaces futuros: el retorno se asigna después. Con dos hijos se conserva la reserva encontrada y se copia el valor del sucesor; ambas reservas existen temporalmente con ese valor. El helper minimo tiene su propio ámbito; temp se inicializa al retornar. free termina solo la reserva retirada; sus alias son históricos inutilizables. Los recorridos C imprimen cada entero seguido de un espacio, sin salto final. Contar hojas y Validar usan auxiliares mostrados en la aplicación que no están declarados en el C/H descargado. Contar hojas retorna 0 para NULL y 1 para un nodo sin hijos; en otro caso suma los conteos de ambos subárboles sin mutación ni printf. C no fija cuál llamada de esa suma se evalúa primero: un orden mostrado u observado es una opción permitida, no una garantía del lenguaje. Los resultados parciales son operandos de la expresión, no variables locales declaradas. El main mostrado con Contar hojas incluye stdio.h, tad_abb.h y el auxiliar canónico una sola vez; compílalo junto a tad_abb.c. Imprime el conteo calculado, conserva consultas repetidas y las recupera al recargar sin volver a ejecutarlas para reconstruir el árbol. Validar ABB usa límites estrictos opcionales con indicadores enteros: la llamada inicial omite ambos límites y admite INT_MIN/INT_MAX. No usa centinelas ni +/-1. Cada hijo hereda los límites de sus ancestros; igualdad o duplicado devuelve 0. NULL devuelve 1. El cortocircuito omite límites ausentes y no visita el subárbol derecho si el izquierdo falla. Es consulta sin mutación ni printf; cada marco conserva sus parámetros. El main incluye el auxiliar una sola vez y calcula cada validación, sin imprimir una respuesta almacenada de la interfaz. Consultas repetidas sobreviven a recarga sin volver a ejecutar esas operaciones del historial al reconstruir.
Condición, ruta y caso
Pila recursiva y retornos
Invariante y evidencia
Variables C
Memoria y enlaces
Relaciones estructurales
6 Comparar
Elige una pareja o una estructura contra todas. Cada una recibe una copia independiente de la misma entrada inmutable; los pasos corresponden a inserciones completas.
Prepara una comparación para estudiar forma, altura, orden e invariante después de cada inserción.
7 Reflexionar
Consola C (printf)
Programa principal del historial
Estructura del TAD
typedef struct ABBNodo {
int valor; /**< Dato entero almacenado. */
struct ABBNodo *izquierdo; /**< Hijo izquierdo. */
struct ABBNodo *derecho; /**< Hijo derecho. */
} ABBNodo;