Que el árbol crezca solo
Para colgar un nodo hay que poder cambiar el puntero que lo sostiene.
1Por qué
Hasta ahora colgaste los nodos a mano: raiz->izq = crear(3). Eso sirve para tres, no para tres mil llegando de un archivo. Hace falta una función que reciba un número y lo ponga donde le toque.
Y ahí aparece el problema que ya conoces, un piso más arriba. Para colgar el nodo hay que cambiar el puntero que lo va a sostener — sea raiz, sea algo->izq. Y una función recibe copias: si le pasas el puntero, cambia su copia y el árbol queda igual.
La solución es la misma de la lección 9, aplicada a un puntero: pasar la dirección del puntero. Por eso el parámetro es Nodo **raiz, con dos estrellas. Se lee «la dirección de un puntero a nodo», y *raiz es el puntero de verdad, el que sí se puede cambiar.
Esto es lo que más cuesta del curso, y no porque sea muchas ideas: es una sola, aplicada dos veces. Si *raiz te confunde, vuelve a la lección 9 y cámbiale el nombre: allí *p era la cajita apuntada; aquí *raiz es el puntero apuntado.
Lo bonito es que la regla del orden hace el resto sola. No hay que buscar el sitio: bajas comparando, y cuando llegas a un hueco vacío, ese ES el sitio.
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 insertar(Nodo **raiz, int x){if (*raiz == NULL){*raiz = crear(x);return;}if (x < (*raiz)->valor)insertar(&(*raiz)->izq, x);elseinsertar(&(*raiz)->der, x);}void enOrden(Nodo *n){if (n == NULL) return;enOrden(n->izq);printf("%d ", n->valor);enOrden(n->der);}int main(void){Nodo *raiz = NULL;insertar(&raiz, 5);insertar(&raiz, 2);insertar(&raiz, 9);enOrden(raiz);printf("\n");return 0;}
- línea 21
Llegó a un hueco vacío: ese es el sitio. No hubo que buscarlo, se llegó bajando. - línea 23
*raiz = …cambia el puntero de quien nos llamó. ConNodo *raizsolo cambiaría la copia y el árbol quedaría igual. - línea 29
&(*raiz)->izqes la dirección del puntero izquierdo. Se pasa la dirección, no el puntero, por lo mismo de la línea 23. - línea 44
Un árbol vacío es un puntero que no apunta a nada, y se le pasa su dirección con&.
3Ahora tú
A esta inserción le falta el paso hacia la izquierda. Escríbelo para que el árbol salga ordenado: 2 5 9
#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 insertar(Nodo **raiz, int x){if (*raiz == NULL){*raiz = crear(x);return;}if (x < (*raiz)->valor)elseinsertar(&(*raiz)->der, x);}void enOrden(Nodo *n){if (n == NULL) return;enOrden(n->izq);printf("%d ", n->valor);enOrden(n->der);}int main(void){Nodo *raiz = NULL;insertar(&raiz, 5);insertar(&raiz, 2);insertar(&raiz, 9);enOrden(raiz);printf("\n");return 0;}
↖︎ Tu línea va aquí. Fíjate en la de abajo: la tuya es su espejo hacia el otro lado.
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