Aplicamos los árboles binarios para modelar expresiones aritméticas con sumas y restas. Cada nodo interno almacena un operador (+ o -) y cada hoja contiene un operando entero. Al recorrer el árbol evaluamos la expresión completa respetando la precedencia implícita de la estructura.
Representar y evaluar la expresión:
((12 + (8 - 3)) - (5 + 4))
El resultado esperado es 8. Debemos construir manualmente el árbol, imprimir la expresión en notación infija y calcular su valor.
Usamos un struct que diferencia entre operadores y operandos mediante el campo es_operador.
typedef struct TreeNode {
int es_operador;
char operador;
int valor;
struct TreeNode *izquierdo;
struct TreeNode *derecho;
} TreeNode;
Definimos dos helpers: uno para operandos y otro para operadores.
TreeNode *crearOperando(int valor) {
TreeNode *n = malloc(sizeof(TreeNode));
if (!n) return NULL;
n->es_operador = 0;
n->operador = 0;
n->valor = valor;
n->izquierdo = NULL;
n->derecho = NULL;
return n;
}
TreeNode *crearOperador(char operador, TreeNode *izq, TreeNode *der) {
TreeNode *n = malloc(sizeof(TreeNode));
if (!n) return NULL;
n->es_operador = 1;
n->operador = operador;
n->valor = 0;
n->izquierdo = izq;
n->derecho = der;
return n;
}
Para evaluar la expresión recorremos el árbol y combinamos los resultados de cada subárbol según el operador.
int evaluar(TreeNode *nodo) {
if (!nodo) return 0;
if (!nodo->es_operador) {
return nodo->valor;
}
int izq = evaluar(nodo->izquierdo);
int der = evaluar(nodo->derecho);
if (nodo->operador == '+') {
return izq + der;
}
return izq - der;
}
Para visualizar la expresión usamos un recorrido en orden y agregamos paréntesis.
void imprimirInfijo(TreeNode *nodo) {
if (!nodo) return;
if (nodo->es_operador) printf("(");
imprimirInfijo(nodo->izquierdo);
if (nodo->es_operador) {
printf(" %c ", nodo->operador);
} else {
printf("%d", nodo->valor);
}
imprimirInfijo(nodo->derecho);
if (nodo->es_operador) printf(")");
}
Para confirmar el resultado:
((12 + (8 - 3)) - (5 + 4)).evaluar(raiz) debe retornar 8.El siguiente archivo implementa la expresión propuesta y permite reutilizar la estructura para cualquier combinación de sumas y restas.
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode {
int es_operador;
char operador;
int valor;
struct TreeNode *izquierdo;
struct TreeNode *derecho;
} TreeNode;
TreeNode *crearOperando(int valor) {
TreeNode *n = malloc(sizeof(TreeNode));
if (!n) return NULL;
n->es_operador = 0;
n->operador = 0;
n->valor = valor;
n->izquierdo = NULL;
n->derecho = NULL;
return n;
}
TreeNode *crearOperador(char operador, TreeNode *izq, TreeNode *der) {
TreeNode *n = malloc(sizeof(TreeNode));
if (!n) return NULL;
n->es_operador = 1;
n->operador = operador;
n->valor = 0;
n->izquierdo = izq;
n->derecho = der;
return n;
}
int evaluar(TreeNode *nodo) {
if (!nodo) return 0;
if (!nodo->es_operador) return nodo->valor;
int izq = evaluar(nodo->izquierdo);
int der = evaluar(nodo->derecho);
return (nodo->operador == '+') ? (izq + der) : (izq - der);
}
void imprimirInfijo(TreeNode *nodo) {
if (!nodo) return;
if (nodo->es_operador) printf("(");
imprimirInfijo(nodo->izquierdo);
if (nodo->es_operador) printf(" %c ", nodo->operador);
else printf("%d", nodo->valor);
imprimirInfijo(nodo->derecho);
if (nodo->es_operador) printf(")");
}
void liberar(TreeNode *nodo) {
if (!nodo) return;
liberar(nodo->izquierdo);
liberar(nodo->derecho);
free(nodo);
}
int main(void) {
TreeNode *n12 = crearOperando(12);
TreeNode *n8 = crearOperando(8);
TreeNode *n3 = crearOperando(3);
TreeNode *n5 = crearOperando(5);
TreeNode *n4 = crearOperando(4);
TreeNode *sub = crearOperador('-', n8, n3); /* (8 - 3) */
TreeNode *sum12 = crearOperador('+', n12, sub); /* 12 + (8 - 3) */
TreeNode *sum5 = crearOperador('+', n5, n4); /* (5 + 4) */
TreeNode *raiz = crearOperador('-', sum12, sum5); /* (12 + (8 - 3)) - (5 + 4) */
printf("Expresion infija: ");
imprimirInfijo(raiz);
printf("\nResultado: %d\n", evaluar(raiz));
liberar(raiz);
return 0;
}