¿Puede alguien explicarme por qué se le da este código para atravesar un árbol binario?
var sumOfLeftLeaves = function(root) { let sum = 0; traverse(root, sum); return sum; }; function traverse(root, sum) { const left = root.left; const right = root.right; if (left) { sum += left.val; traverse(left, sum); } if (right) { traverse(right, sum); } }la suma que se calculó correctamente durante el recorrido del árbol, se restablece a 0 después de salir de la última etapa recursiva?
No está devolviendo sum de traverse , y tampoco lo está reasignando en sumOfLeftLeaves . Probablemente quieras algo más como esto:
var sumOfLeftLeaves = function(root) { return traverse(root, 0); }; function traverse(root, sum) { const left = root.left; const right = root.right; if (left) { sum += left.val; return traverse(left, sum); } if (right) { return traverse(right, sum); } return sum; }var sumOfLeftLeaves = function(root) { let sum = 0; return traverse(root, sum); }; function traverse(root, sum) { const left = root.left; const right = root.right; sum += root.val if (left) { sum += traverse(left, sum); } if (right) { sum += traverse(right, sum); } return sum } sum es un valor inmutable. Esto significa que cada vez que lo pasa como argumento a una llamada de función, se realiza una nueva copia. Por lo tanto, las adiciones que realiza más abajo en la pila recursiva no se reflejan en la variable de sum en los marcos de la pila de arriba.
Para elaborar más , sum es un número entero, Number en términos JS. Es un tipo de valor, lo que significa que en cada asignación, se pasa por valor, se copia. En otras palabras, el tiempo de ejecución de JS crea un nuevo lugar en la pila y almacena el valor que se asignó en el nuevo lugar. Cualquier mutación/modificación que realice en el tipo de valor no se refleja en la variable original.
Este enfoque resuelve el problema.
Otro enfoque sería eliminar la sum como parámetro y solo devolver la suma de los valores de los nodos de la siguiente manera:
var sumOfLeftLeaves = function(root) { return traverse(root); }; function traverse(root) { if (root == null) return 0 return root.val + traverse(root.left) + traverse(root.right); } Para completar, un tercer enfoque sería hacer que sum sea una variable mutable, como un tipo de objeto js o una matriz. Si bien la estructura del objeto o de la matriz en sí se pasa por valor, su contenido se puede cambiar y esos cambios se reflejarán en la variable original. Digamos que pasa sum como una matriz de un elemento, const sum = [0] . Cada vez que le agrega algo, sum[0] += node.val , el valor del elemento en el índice cero de sum cambia y también es visible para las funciones más arriba de la pila de llamadas.
Puede tomar una sola función que devuelva el valor más el lado izquierdo y derecho o cero.
const sumOfTree = node => node ? value + sumOfTree(node.left) + sumOfTree(node.right) : 0;Otra solución podría ser utilizar una función transversal que tome un nodo y una función con un cierre sobre un objeto para el valor.
const traverse = (node, fn) => { if (!node) return; fn(node); traverse(node.left, fn); traverse(node.right, fn); }, sumOfTree = result => node => result.sum += node.value; // call const result = { sum: 0 }, getSum = sumOfTree(result); traverse(tree, getSum); console.log(result.sum);