// 递归函数计算嵌套数组总和
function sumNestedArray(arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
sum += sumNestedArray(arr[i]);
} else {
sum += arr[i];
}
}
return sum;
}
// 优化方案1:使用尾递归优化(原理:在函数的最后一步调用自身,避免栈增长。适用场景:支持尾递归优化的环境,如现代的某些JavaScript引擎)
function sumNestedArrayTailRecursion(arr, sum = 0) {
if (arr.length === 0) {
return sum;
}
let current = arr.shift();
if (Array.isArray(current)) {
return sumNestedArrayTailRecursion([...current, ...arr], sum);
} else {
return sumNestedArrayTailRecursion(arr, sum + current);
}
}
// 优化方案2:使用栈模拟递归(原理:手动维护一个栈结构来代替函数调用栈。适用场景:各种环境,尤其是不支持尾递归优化的环境)
function sumNestedArrayWithStack(arr) {
let sum = 0;
let stack = arr.slice();
while (stack.length > 0) {
let current = stack.pop();
if (Array.isArray(current)) {
stack.push(...current);
} else {
sum += current;
}
}
return sum;
}
- 优化方案1:尾递归优化
- 原理:尾递归是指在函数的最后一步调用自身,这样函数调用栈可以复用,不会随着递归深度增加而无限增长。在尾递归中,当前函数的调用帧可以被新的调用帧直接替换,因为不需要保留当前函数的上下文信息来计算返回值。
- 适用场景:适用于支持尾递归优化的JavaScript引擎环境,例如现代的某些浏览器和Node.js版本。但并非所有环境都支持,需要注意兼容性。
- 优化方案2:使用栈模拟递归
- 原理:手动维护一个栈数据结构,通过将数组元素压入栈中,然后依次弹出并处理,模拟递归调用的过程。这种方式避免了函数调用栈的无限增长,因为所有的递归状态都由手动维护的栈来管理。
- 适用场景:适用于各种JavaScript环境,尤其是那些不支持尾递归优化的环境。它可以有效地处理深度嵌套的数组,因为栈的大小可以根据需要动态调整,而不会受到系统栈大小的限制。