Un árbol es un grafo conectado sin ciclos. Un bosque está formado por uno o más árboles separados y conserva la estructura acíclica.
Los árboles aparecen constantemente en programación: sistemas de archivos, jerarquías, árboles de búsqueda, interfaces, expresiones y decisiones.
Desde la teoría de grafos, un árbol no se define por su forma visual, sino por dos propiedades: debe estar conectado y no contener ciclos.
Un árbol es un grafo no dirigido, conectado y acíclico.
La definición no exige una raíz. La raíz se elige cuando queremos interpretar el árbol como una jerarquía.
Un bosque es un grafo no dirigido sin ciclos que puede estar desconectado. Cada una de sus componentes conexas es un árbol.
Todo árbol es también un bosque con una sola componente.
Para un grafo no dirigido con n vértices, las siguientes afirmaciones caracterizan a un árbol:
Selecciona dos vértices para agregar o quitar una arista. La aplicación comprobará conectividad y ciclos para clasificar la estructura.
Agrega A—D: como ya existía un camino entre ambos, aparece un ciclo. Reinicia y corta C—F: el árbol se divide en dos componentes y se convierte en bosque.
Todo árbol con n vértices posee exactamente n − 1 aristas.
Si tiene menos, no puede estar conectado. Si tiene más y sigue conectado, necesariamente contiene algún ciclo.
Un bosque con n vértices y c componentes posee n − c aristas.
Cada componente de tamaño nᵢ es un árbol con nᵢ − 1 aristas. Al sumar todas obtenemos la fórmula.
En un árbol con al menos dos vértices, una hoja tiene grado 1. Los demás nodos se consideran internos.
| Tipo | Grado o función |
|---|---|
| Hoja | Grado 1 |
| Vértice interno | Conecta varias ramas |
| Raíz | Vértice elegido como origen jerárquico |
Todo árbol finito con al menos dos vértices tiene al menos dos hojas.
Al elegir una raíz aparecen relaciones jerárquicas: padre, hijo, ancestro, descendiente, nivel y profundidad.
La estructura no dirigida subyacente sigue siendo el mismo árbol; la raíz agrega una interpretación y una orientación conceptual.
function esArbol(cantidadVertices, aristas, cantidadComponentes) {
return cantidadComponentes === 1 &&
aristas.length === cantidadVertices - 1;
}
console.log(esArbol(5, [
["A", "B"], ["A", "C"], ["C", "D"], ["C", "E"]
], 1));La comprobación presupone un grafo simple no dirigido. La cantidad de componentes debe calcularse mediante una búsqueda.
function tieneCiclo(aristas) {
const padre = {};
const buscar = x => padre[x] === x ? x : padre[x] = buscar(padre[x]);
for (const [a, b] of aristas) {
if (!(a in padre)) padre[a] = a;
if (!(b in padre)) padre[b] = b;
const raizA = buscar(a);
const raizB = buscar(b);
if (raizA === raizB) return true;
padre[raizA] = raizB;
}
return false;
}Árboles y bosques son las estructuras acíclicas fundamentales de la teoría de grafos. Ofrecen conectividad con la mínima cantidad de aristas y permiten representar jerarquías y relaciones sin redundancia.
En el próximo tema estudiaremos árboles generadores, que conservan todos los vértices de un grafo conectado utilizando solo las aristas necesarias.