11 - Ejemplo práctico: inventario ordenado

En este ejemplo aplicamos un árbol binario de búsqueda para registrar productos en un depósito. Cada nodo guarda un código y la cantidad disponible. El árbol facilita insertar nuevas referencias, consultar existencias y generar reportes ordenados sin recorrer el inventario de forma lineal.

11.1 Enunciado

Una tienda recibe los siguientes productos (código, cantidad):

  • 1050 → 12 unidades
  • 900 → 6 unidades
  • 1400 → 5 unidades
  • 850 → 20 unidades
  • 1100 → 8 unidades
  • 1600 → 3 unidades

Se desea:

  1. Insertar cada producto manteniendo orden por código.
  2. Consultar el stock de un código dado.
  3. Listar el inventario de menor a mayor código.

11.2 Modelo de nodo

Cada nodo almacena el código, la cantidad y los punteros a sus hijos. Se reutilizan los helpers vistos en temas anteriores.

typedef struct ProductNode {
  int codigo;
  int stock;
  struct ProductNode *izquierdo;
  struct ProductNode *derecho;
} ProductNode;

11.3 Inserción y actualización

Si el producto existe, se suma al stock actual. De lo contrario, se crea un nuevo nodo.

ProductNode *crearProducto(int codigo, int stock) {
  ProductNode *n = malloc(sizeof(ProductNode));
  if (!n) return NULL;
  n->codigo = codigo;
  n->stock = stock;
  n->izquierdo = NULL;
  n->derecho = NULL;
  return n;
}

ProductNode *insertarProducto(ProductNode *raiz, int codigo, int stock) {
  if (!raiz) return crearProducto(codigo, stock);
  if (codigo == raiz->codigo) {
    raiz->stock += stock;
  } else if (codigo < raiz->codigo) {
    raiz->izquierdo = insertarProducto(raiz->izquierdo, codigo, stock);
  } else {
    raiz->derecho = insertarProducto(raiz->derecho, codigo, stock);
  }
  return raiz;
}

11.4 Consulta de stock

La búsqueda se apoya en la propiedad de orden del árbol.

ProductNode *buscarProducto(ProductNode *raiz, int codigo) {
  if (!raiz) return NULL;
  if (codigo == raiz->codigo) return raiz;
  return (codigo < raiz->codigo)
      ? buscarProducto(raiz->izquierdo, codigo)
      : buscarProducto(raiz->derecho, codigo);
}

11.5 Reporte ordenado

Un recorrido inorden lista los productos de menor a mayor código e incluye las existencias.

void imprimirInventario(ProductNode *raiz) {
  if (!raiz) return;
  imprimirInventario(raiz->izquierdo);
  printf("Codigo %d: %d unidades\n", raiz->codigo, raiz->stock);
  imprimirInventario(raiz->derecho);
}

11.6 Verificación

  • Inserta dos veces el mismo código y comprueba que el stock se acumula.
  • Consulta un código inexistente y verifica que se retorne NULL.
  • Imprime el inventario y confirma el orden ascendente.

11.7 Código completo para CLion

Este archivo contiene todo el flujo: inserción, consulta y reporte final.

#include <stdio.h>
#include <stdlib.h>

typedef struct ProductNode {
  int codigo;
  int stock;
  struct ProductNode *izquierdo;
  struct ProductNode *derecho;
} ProductNode;

ProductNode *crearProducto(int codigo, int stock) {
  ProductNode *n = malloc(sizeof(ProductNode));
  if (!n) return NULL;
  n->codigo = codigo;
  n->stock = stock;
  n->izquierdo = NULL;
  n->derecho = NULL;
  return n;
}

ProductNode *insertarProducto(ProductNode *raiz, int codigo, int stock) {
  if (!raiz) return crearProducto(codigo, stock);
  if (codigo == raiz->codigo) {
    raiz->stock += stock;
  } else if (codigo < raiz->codigo) {
    raiz->izquierdo = insertarProducto(raiz->izquierdo, codigo, stock);
  } else {
    raiz->derecho = insertarProducto(raiz->derecho, codigo, stock);
  }
  return raiz;
}

ProductNode *buscarProducto(ProductNode *raiz, int codigo) {
  if (!raiz) return NULL;
  if (codigo == raiz->codigo) return raiz;
  return (codigo < raiz->codigo)
      ? buscarProducto(raiz->izquierdo, codigo)
      : buscarProducto(raiz->derecho);
}

void imprimirInventario(ProductNode *raiz) {
  if (!raiz) return;
  imprimirInventario(raiz->izquierdo);
  printf("Codigo %d: %d unidades\n", raiz->codigo, raiz->stock);
  imprimirInventario(raiz->derecho);
}

void liberar(ProductNode *raiz) {
  if (!raiz) return;
  liberar(raiz->izquierdo);
  liberar(raiz->derecho);
  free(raiz);
}

int main(void) {
  ProductNode *inventario = NULL;
  inventario = insertarProducto(inventario, 1050, 12);
  inventario = insertarProducto(inventario, 900, 6);
  inventario = insertarProducto(inventario, 1400, 5);
  inventario = insertarProducto(inventario, 850, 20);
  inventario = insertarProducto(inventario, 1100, 8);
  inventario = insertarProducto(inventario, 1600, 3);
  inventario = insertarProducto(inventario, 900, 4); /* reingreso */

  puts("Inventario ordenado:");
  imprimirInventario(inventario);

  int codigoConsulta = 1100;
  ProductNode *resultado = buscarProducto(inventario, codigoConsulta);
  if (resultado) {
    printf("\nStock del producto %d: %d unidades\n", codigoConsulta, resultado->stock);
  } else {
    printf("\nEl producto %d no existe\n", codigoConsulta);
  }

  liberar(inventario);
  return 0;
}