AprenderC
← Todas las lecciones

Recorrer sin ciclos

Cuando hay dos caminos, la función se llama a sí misma.

1Por qué

Recorrer una lista es fácil porque solo hay un camino: avanzas hasta el NULL. Un árbol no tiene «el siguiente»: tiene dos, y en cada uno vuelve a haber dos.

Con un ciclo esto se pone feo enseguida, porque habría que ir anotando a mano los caminos pendientes. Pero hay una forma que cabe en tres líneas, y funciona porque un árbol está hecho de árboles: el hijo izquierdo de la raíz es, él solo, un árbol completo.

Si ya tienes una función que recorre un árbol, para recorrer el de la izquierda basta con llamarla otra vez. Eso es la recursión: una función que se llama a sí misma sobre un trozo más pequeño del problema.

Dos partes, siempre. Dónde parar —aquí, cuando el nodo es NULL— y la llamada sobre algo más chico. Si falta la primera, la función sigue bajando más allá del último nodo y termina preguntándole algo a un puntero que vale NULL. El taller te lo va a señalar, con su línea.

El orden de las tres líneas decide en qué orden salen los datos. Poniendo el izquierdo primero, después el valor y al final el derecho, salen ordenados de menor a mayor. Eso no es casualidad: es la regla de colocar menores a la izquierda, leída al derecho.

2Míralo andar

Este programa funciona. Léelo, y después ejecútalo sin cambiar nada.

#include <stdio.h>
#include <stdlib.h>
typedef struct Nodo {
int valor;
struct Nodo *izq;
struct Nodo *der;
} Nodo;
Nodo *crear(int v)
{
Nodo *n = malloc(sizeof(Nodo));
n->valor = v;
n->izq = NULL;
n->der = NULL;
return n;
}
void enOrden(Nodo *n)
{
if (n == NULL) return;
enOrden(n->izq);
printf("%d ", n->valor);
enOrden(n->der);
}
int main(void)
{
Nodo *raiz = crear(5);
raiz->izq = crear(3);
raiz->der = crear(8);
enOrden(raiz);
printf("\n");
free(raiz->izq);
free(raiz->der);
free(raiz);
return 0;
}

3Ahora tú

A esta función le falta dónde parar, así que no termina. Escribe esa línea

#include <stdio.h>
#include <stdlib.h>
typedef struct Nodo {
int valor;
struct Nodo *izq;
struct Nodo *der;
} Nodo;
Nodo *crear(int v)
{
Nodo *n = malloc(sizeof(Nodo));
n->valor = v;
n->izq = NULL;
n->der = NULL;
return n;
}
void enOrden(Nodo *n)
{
enOrden(n->izq);
printf("%d ", n->valor);
enOrden(n->der);
}
int main(void)
{
Nodo *raiz = crear(6);
raiz->izq = crear(2);
raiz->der = crear(9);
enOrden(raiz);
printf("\n");
free(raiz->izq);
free(raiz->der);
free(raiz);
return 0;
}

↖︎ Tu línea va aquí, antes de las llamadas: es la pregunta que corta el descenso.

Ejecutar

Lo que dice tu programa

↖︎ Escribe tu parte y dale a Ejecutar

Qué pasó

Aquí te aviso si tu programa hace algo raro.

    4Qué guarda tu programa

    Memoria

    ↖︎ Ejecuta el programa para ver qué pasa por dentro