所以,我正在学习递归,我正在处理一个需要数组中元素的所有变体的编码挑战。
我被指给了Heap 的算法,这就是我到目前为止在 JavaScript 中制定的内容。
function generate(n, array) {
if (n == 1) {
return array;
}
else {
for (var i = 0; i < n - 1; i++) {
generate(n - 1, array);
if (n % 2 == 0) {
swap(array[i], array[n - 1]);
}
else {
swap(array[0], array[n - 1]);
}
}
generate(n - 1, array);
}
}
请忽略我没有将“交换”实例翻译成 JavaScript 的事实。
我有点不确定如何准确地遍历这个算法的递归部分。
假设我有数组:[A,B,C,D,E]。我相信我将传递给外部函数的参数是:
generate(5, [A,B,C,D,E]);
在这种情况下,n 不等于 1,所以我将继续讨论“else”部分。我遇到了 for 循环,因为 n 是 5,所以它执行。
Next: 函数调用自身,但这次的参数是:
generate(4, [A,B,C,D,E]);
这就是我的困惑开始的地方:
当我经历这个时,我是继续“if”/“else”条件还是(在递归调用之后)回到外部函数的最开始?
更新
下面是 Heap 算法的完全翻译的 JavaScript 版本。
function generate(n, array) {
//console.log("ENTER", n, array)
if (n == 1) {
console.log(array);
}
else {
for (var i = 0; i < n - 1; i++) {
//console.log("RECUR", n-1, array)
generate(n - 1, array);
if (n % 2 == 0) {
//console.log("SWAP ", n, array)
var one = array[i];
var two = array[n - 1];
array[i] = two;
array[n - 1] = one;
//swap(array[i], array[n - 1]);
}
else {
//console.log("SWAP ", 0, n-1)
var first = array[0];
var second = array[n - 1];
array[0] = second;
array[n - 1] = first;
//swap(array[0], array[n - 1]);
}
//console.log("array", array)
}
//console.log("RECUR 2", n-1, array)
generate(n - 1, array);
}
//console.log("LEAVE", n, array)
}
我在纸上遍历它,直到我再次重复[A,B,C,D]。
以为我搞砸了,我决定实施 Prune 的控制台输出建议,看看控制台中发生了什么,这很有帮助。
修复一个小错误后,它现在工作得很好。
感谢所有帮助过的人!