Lección 11 · 11 de 20
Un árbol binario de búsqueda · C
Construya en C un árbol binario de búsqueda que cuenta palabras: inserción recursiva, búsqueda, recorrido en orden y liberación del árbol.

En un árbol binario de búsqueda cada nodo tiene dos hijos, left y right, y una regla: las palabras menores van a la izquierda y las mayores, a la derecha. Gracias a esa regla, buscar baja por una sola rama y en cada nivel descarta la mitad del árbol, si está equilibrado.
insert es recursiva. Si llega a un hueco (n == NULL), crea el nodo con calloc, que deja count a 0 e hijos a NULL, y copia la palabra. Después compara con strcmp: si es menor, inserta en el subárbol izquierdo; si es mayor, en el derecho; si es igual, suma uno a count. Un nodo recién creado pasa así de 0 a 1, y una palabra repetida como fig llega a 3.
find hace lo mismo sin recursión: mientras no encuentre la palabra, baja a la izquierda o a la derecha. Devuelve el nodo o NULL, como con lime.
in_order visita primero el subárbol izquierdo, después el nodo y por último el derecho: un recorrido en orden, que escribe las palabras ordenadas alfabéticamente sin haber ordenado nada. La raíz es melon porque fue la primera palabra insertada.
free_tree libera en postorden: primero los dos hijos y después el nodo. Al revés, al liberar el nodo se perderían los punteros a sus hijos.
Código · main.c
#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct Node { char word[16]; int count; struct Node *left, *right; } Node;Node *insert(Node *n, const char *word) { // smaller to the left, bigger to the right if (n == NULL) { // empty spot found: the new node goes here if (!(n = calloc(1, sizeof *n))) exit(EXIT_FAILURE); // count 0, children NULL snprintf(n->word, sizeof n->word, "%s", word); } int cmp = strcmp(word, n->word); if (cmp < 0) n->left = insert(n->left, word); else if (cmp > 0) n->right = insert(n->right, word); else n->count++; // the word is here: new (0 -> 1) or repeated return n;}const Node *find(const Node *n, const char *word) { // one branch per level while (n && strcmp(word, n->word) != 0) n = strcmp(word, n->word) < 0 ? n->left : n->right; return n;}void in_order(const Node *n) { // left, node, right: alphabetical order if (n) { in_order(n->left); printf(" %-6s x%d\n", n->word, n->count); in_order(n->right); }}void free_tree(Node *n) { if (n) { free_tree(n->left); free_tree(n->right); free(n); } }int main(void) { const char *words[] = {"melon", "fig", "pear", "apple", "kiwi", "fig", "plum", "apple", "fig"}; Node *root = NULL; // an empty tree for (int i = 0; i < 9; i++) root = insert(root, words[i]); in_order(root); printf("Root: %s, kiwi: %s, lime: %s\n", root->word, find(root, "kiwi") ? "found" : "missing", find(root, "lime") ? "found" : "missing"); free_tree(root); // children first, then the node itself return 0;}Salida · cc main.c -o main && ./main
apple x2 fig x3 kiwi x1 melon x1 pear x1 plum x1 Root: melon, kiwi: found, lime: missing
Para recordar
- Menores a la izquierda, mayores a la derecha.
- Buscar e insertar recorren una sola rama.
- El recorrido en orden da los datos ordenados.
- Se libera en postorden: hijos primero, nodo después.
Ejercicio
Escriba int height(const Node *n) (0 para NULL, y 1 más la altura del hijo más alto) y compare la altura del árbol con la que sale si inserta las palabras ya ordenadas.