Skip to content

Commit f962cc0

Browse files
authored
Merge pull request #37 from marcode24/2024-21
✨ Add challenge-21 solution
2 parents e13ba28 + b7b225f commit f962cc0

File tree

4 files changed

+428
-0
lines changed

4 files changed

+428
-0
lines changed
+331
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
# Reto 21: Calcula-la-altura-del-arbol-de-navidad
2+
3+
Santa Claus 🎅 está decorando un árbol de Navidad mágico 🪄, que este año tiene una estructura especial en forma de **árbol binario.** Cada nodo del árbol representa un regalo, y Santa quiere saber la **altura del árbol** para colocar la estrella mágica en la punta.
4+
5+
Tu tarea es escribir una función que calcule la altura de un árbol binario. La altura de un árbol binario se define como el número máximo de niveles desde la raíz hasta una hoja. Un árbol vacío tiene una altura de 0.
6+
7+
```js
8+
// Definición del árbol
9+
const tree = {
10+
value: '🎁',
11+
left: {
12+
value: '🎄',
13+
left: {
14+
value: '',
15+
left: null,
16+
right: null
17+
},
18+
right: {
19+
value: '🎅',
20+
left: null,
21+
right: null
22+
}
23+
},
24+
right: {
25+
value: '❄️',
26+
left: null,
27+
right: {
28+
value: '🦌',
29+
left: null,
30+
right: null
31+
}
32+
}
33+
}
34+
35+
// Representación gráfica del árbol:
36+
// 🎁
37+
// / \
38+
// 🎄 ❄️
39+
// / \ \
40+
// ⭐ 🎅 🦌
41+
42+
// Llamada a la función
43+
treeHeight(tree)
44+
// Devuelve: 3
45+
```
46+
47+
## Mi solución explicada
48+
49+
```js
50+
function treeHeight(tree) {
51+
if (!tree) return 0;
52+
53+
const leftHeight = treeHeight(tree.left);
54+
const rightHeight = treeHeight(tree.right);
55+
56+
return Math.max(leftHeight, rightHeight) + 1;
57+
}
58+
```
59+
60+
Para resolver este reto, existen diferentes formas de recorrer un árbol binario. En este caso, he optado por utilizar una función recursiva que recorra el árbol en **preorden**. La función `treeHeight` recibe un nodo del árbol y devuelve la altura del árbol.
61+
62+
Como vamos a trabajar con recursividad, la primera condición que debemos comprobar es si el nodo es `null`. En este caso, devolvemos 0, ya que un árbol vacío tiene una altura de 0.
63+
64+
Si el nodo no es `null`, calculamos la altura de los subárboles izquierdo y derecho. La altura de un árbol es el máximo entre la altura del subárbol izquierdo y la altura del subárbol derecho, más 1 (por el nodo actual). Para esto utilizamos la función `Math.max` para obtener el máximo entre `leftHeight` y `rightHeight`, y sumamos 1.
65+
66+
Implicitamente, la función `treeHeight` se va llamando a sí misma con los nodos izquierdo y derecho, hasta llegar a un nodo `null`. En ese momento, se empiezan a devolver los valores de la altura de los subárboles, y se van sumando hasta llegar a la raíz del árbol.
67+
68+
**Veamos cómo se resuelve con un ejemplo:**
69+
70+
Supongamos que tenemos el siguiente árbol:
71+
72+
```js
73+
const tree = {
74+
value: '🎁',
75+
left: {
76+
value: '🎄',
77+
left: {
78+
value: '',
79+
left: {
80+
value: '🎅',
81+
left: null,
82+
right: null,
83+
},
84+
right: null,
85+
},
86+
right: null,
87+
},
88+
right: null,
89+
}
90+
```
91+
92+
Visualmente, el árbol se vería así:
93+
94+
```txt
95+
🎁
96+
/
97+
🎄
98+
/
99+
100+
/
101+
🎅
102+
```
103+
104+
Para la primera llamada, el nodo actual es la raíz del árbol `🎁`
105+
106+
```js
107+
tree = {
108+
value: '🎁',
109+
left: {
110+
value: '🎄',
111+
left: {
112+
value: '',
113+
left: {
114+
value: '🎅',
115+
left: null,
116+
right: null,
117+
},
118+
right: null,
119+
},
120+
right: null,
121+
},
122+
right: null,
123+
}
124+
```
125+
126+
Como `tree` no es `null`, calculamos la altura de los subárboles izquierdo y derecho:
127+
128+
```js
129+
if (!tree) return 0;
130+
(false) --> No se cumple la condición
131+
132+
const leftHeight = treeHeight(tree.left);
133+
const rightHeight = treeHeight(tree.right);
134+
```
135+
136+
**Primero nos enfocaremos en el `rightHeight`** ya que es el más sencillo. En este caso, el subárbol derecho es `null`, por lo que la altura del subárbol derecho es `0`.
137+
138+
La entrada para el subárbol derecho es:
139+
140+
```js
141+
tree.right = null
142+
143+
//treeHeight(tree.right)
144+
treeHeight(null)
145+
```
146+
147+
Como `tree` es `null`, se cumple la condición y devolvemos `0`.
148+
149+
```js
150+
// tree = null
151+
152+
// if (!tree) return 0;
153+
// if (!null) return 0;
154+
if (true) return 0 -> Se cumple la condición
155+
156+
return 0;
157+
```
158+
159+
**Ahora nos enfocaremos en el `leftHeight`.** En este caso, el subárbol izquierdo `🎁` tiene un nodo `🎄` un subárbol izquierdo y un subárbol derecho. La entrada para el subárbol izquierdo es:
160+
161+
```js
162+
tree = {
163+
value: '🎄',
164+
left: {
165+
value: '',
166+
left: {
167+
value: '🎅',
168+
left: null,
169+
right: null,
170+
},
171+
right: null,
172+
},
173+
right: null,
174+
}
175+
```
176+
177+
Como `tree` no es `null`, calculamos la altura de los subárboles izquierdo y derecho:
178+
179+
```js
180+
if (!tree) return 0;
181+
(false) --> No se cumple la condición
182+
183+
const leftHeight = treeHeight(tree.left);
184+
const rightHeight = treeHeight(tree.right);
185+
```
186+
187+
**Primero nos enfocaremos en el `rightHeight`** ya que es el más sencillo. Como ya hemos visto, el subárbol derecho es `null`, por lo que la altura del subárbol derecho es 0.
188+
189+
```js
190+
tree.right = null
191+
192+
//treeHeight(tree.right)
193+
treeHeight(null) -> 0
194+
```
195+
196+
**Ahora nos enfocaremos en el `leftHeight`.** En este caso, el subárbol izquierdo `🎄` tiene un nodo `` y un subárbol izquierdo. La entrada para el subárbol izquierdo es:
197+
198+
```js
199+
tree = {
200+
value: '',
201+
left: {
202+
value: '🎅',
203+
left = null,
204+
right = null,
205+
},
206+
right: null,
207+
}
208+
```
209+
210+
Como `tree` no es `null`, calculamos la altura de los subárboles izquierdo y derecho:
211+
212+
```js
213+
if (!tree) return 0;
214+
(false) --> No se cumple la condición
215+
216+
const leftHeight = treeHeight(tree.left);
217+
const rightHeight = treeHeight(tree.right);
218+
```
219+
220+
**Primero nos enfocaremos en el `rightHeight`** ya que es el más sencillo. En este caso, el subárbol derecho es `null`, por lo que la altura del subárbol derecho es `0`.
221+
222+
```js
223+
tree.right = null
224+
225+
//treeHeight(tree.right)
226+
treeHeight(null) -> 0
227+
```
228+
229+
**Ahora nos enfocaremos en el `leftHeight`.** En este caso, el subárbol izquierdo `` tiene un nodo `🎅` que es una hoja. La entrada para el subárbol izquierdo es:
230+
231+
```js
232+
tree = {
233+
value: '🎅',
234+
left: null,
235+
right: null,
236+
}
237+
```
238+
239+
Como `tree` no es `null`, calculamos la altura de los subárboles izquierdo y derecho:
240+
241+
```js
242+
if (!tree) return 0;
243+
(false) --> No se cumple la condición
244+
245+
const leftHeight = treeHeight(tree.left);
246+
const rightHeight = treeHeight(tree.right);
247+
```
248+
249+
**Primero nos enfocaremos en el `rightHeight`** ya que es el más sencillo. En este caso, el subárbol derecho es `null`, por lo que la altura del subárbol derecho es `0`.
250+
251+
```js
252+
tree.right = null
253+
254+
//treeHeight(tree.right)
255+
treeHeight(null) -> 0
256+
```
257+
258+
**Ahora nos enfocaremos en el `leftHeight`.** En este caso, el subárbol izquierdo `🎅` es una hoja, por lo que la altura del subárbol izquierdo es `0`.
259+
260+
```js
261+
tree.left = null
262+
263+
//treeHeight(tree.left)
264+
treeHeight(null) -> 0
265+
```
266+
267+
Como ya hemos llegado a una hoja, empezamos a devolver los valores de la altura de los subárboles, y se van sumando hasta llegar a la raíz del árbol.
268+
269+
Entonces tenemos que para el nodo `🎅`:
270+
271+
```js
272+
//const leftHeight = treeHeight(tree.left);
273+
const leftHeight = 0;
274+
275+
//const rightHeight = treeHeight(tree.right);
276+
const rightHeight = 0;
277+
278+
//return Math.max(leftHeight, rightHeight) + 1;
279+
// return Math.max(0, 0) + 1;
280+
// return 0 + 1;
281+
return 1;
282+
```
283+
284+
Para el nodo ``:
285+
286+
```js
287+
//const leftHeight = treeHeight(tree.left);
288+
const leftHeight = 1;
289+
290+
//const rightHeight = treeHeight(tree.right);
291+
const rightHeight = 0;
292+
293+
//return Math.max(leftHeight, rightHeight) + 1;
294+
// return Math.max(1, 0) + 1;
295+
// return 1 + 1;
296+
return 2;
297+
```
298+
299+
Para el nodo `🎄`:
300+
301+
```js
302+
//const leftHeight = treeHeight(tree.left);
303+
const leftHeight = 2;
304+
305+
//const rightHeight = treeHeight(tree.right);
306+
const rightHeight = 0;
307+
308+
//return Math.max(leftHeight, rightHeight) + 1;
309+
// return Math.max(2, 0) + 1;
310+
// return 2 + 1;
311+
return 3;
312+
```
313+
314+
Finalmente, para el nodo `🎁`:
315+
316+
```js
317+
//const leftHeight = treeHeight(tree.left);
318+
const leftHeight = 3;
319+
320+
//const rightHeight = treeHeight(tree.right);
321+
const rightHeight = 0;
322+
323+
//return Math.max(leftHeight, rightHeight) + 1;
324+
// return Math.max(3, 0) + 1;
325+
// return 3 + 1;
326+
return 4;
327+
```
328+
329+
Por lo tanto, la altura del árbol es `4`.
330+
331+
Y así es como resolvemos este reto utilizando una función recursiva que recorre el árbol en preorden. 🎄
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function treeHeight(tree) {
2+
if (!tree) return 0;
3+
4+
const leftHeight = treeHeight(tree.left);
5+
const rightHeight = treeHeight(tree.right);
6+
7+
return Math.max(leftHeight, rightHeight) + 1;
8+
}
9+
10+
module.exports = treeHeight;

0 commit comments

Comments
 (0)