Javascript 堆';s算法遍历
所以,我正在学习递归,我正在研究一个编码挑战,它需要数组中所有元素的变化 有人指着我说,这就是我迄今为止用JavaScript编写的内容Javascript 堆';s算法遍历,javascript,algorithm,recursion,Javascript,Algorithm,Recursion,所以,我正在学习递归,我正在研究一个编码挑战,它需要数组中所有元素的变化 有人指着我说,这就是我迄今为止用JavaScript编写的内容 function generate(n, array) { if (n == 1) { return array; } else { for (var i = 0; i < n - 1; i++) { generate(n - 1, array); i
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);
}
}
在本例中,n不等于1,因此我将转到“else”部分。
我遇到for循环,因为n是5,所以它执行
下一步:函数调用自身,但这次参数是:
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)
函数生成(n,数组){
//console.log(“输入”,n,数组)
如果(n==1){
console.log(数组);
}
否则{
对于(变量i=0;i
}
我一直在纸上浏览,直到我到达一个点,我又重复了一遍[a,B,C,D]
考虑到我搞砸了,我决定实现Prune关于控制台输出的建议,看看控制台中发生了什么,这很有帮助
在修复了一个小错误后,它现在工作得很好
感谢所有帮助过你的人在这一点上,我的标准答案是,如果你在纸上浏览算法时遇到困难,不要!让电脑为你做这件事。插入一组console.log命令来跟踪执行情况。跟踪每个例程和调用的入口和出口,包括有用的值
function generate(n, array) {
console.log("ENTER", n, array)
if (n == 1) {
return 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)
swap(array[i], array[n - 1]);
}
else {
console.log("SWAP ", 0, n-1)
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)
}
函数生成(n,数组){
console.log(“输入”,n,数组)
如果(n==1){
返回数组;
}
否则{
对于(变量i=0;i
这将给你一个可爱的执行跟踪。为了更大的可读性,请将输出的每行缩进2*(5-n)个空格。让我列举一下您的行,这样我们可以更容易地引用它们(见下文) 你从
generate(5[A,B,C,D,E])走出来代码>最多生成(4[A、B、C、D、E])代码>(在第7行),然后您第二次输入了generate
,没有完成第一次呼叫,因此您在第一次呼叫时暂停,并开始使用第二次呼叫
现在(第二次调用)n=4
因此您再次到达第7行,但这次第三次调用生成(3[a,B,C,D,E])
开始(没有完成之前的调用)
第四次调用generate(2,…)
也是如此,而第五次调用generate(1,…)
则是事情开始改变的时候
在第5次调用中,n=1
,因此第2行的条件求值为真,并返回array
,然后我们返回到我们来自的位置,即第7行的第4次调用,返回的数组不进行任何操作(未分配或任何操作),然后在第4次调用中,我们到达第8行(第一次),n=2
因此第二次swap
发生并且i
增加,回到第7行,我们再次调用generate(1,…)
以获得相同的结果。。。等等
01. function generate(n, array) {
02. if (n == 1) {
03. return array;
04. }
05. else {
06. for (var i = 0; i < n - 1; i++) {
07. generate(n - 1, array);
08. if (n % 2 !== 0) {
09. swap(array[i], array[n - 1]);
10. }
11. else {
12. swap(array[0], array[n - 1]);
13. }
14. }
15. generate(n - 1, array);
16. }
17. }
01。函数生成(n,数组){
02.如果(n==1){
03.返回数组;
04. }
05.其他{
对于(变量i=0;i
当您调用的函数返回值时,您可以继续,而不是从头开始。@vic3685-我猜在生成(n-1,array)为:生成(2-1,array)的点之前,我无法继续执行for循环中的“if”语句,因为此时它将返回某个内容(1)..您需要正确实施交换
,以实现此目的useful@Prune-我在我的帖子中添加了一个更新,非常感谢您的想法,谢谢!想什么?这是一个非常开放的评论。谢谢,这证实了我的怀疑。我要去试着走过去。虽然我会用A,B,C,D,因为它的排列较少。很高兴听到。顺便说一句,如果你在学习递归,我不建议把排列作为第一课。最好试试阶乘、斐波那契或迷宫。谷歌的“阶乘递归javascript”、“斐波那契递归javascript”和/或“2d迷宫递归javascript”谢谢。事实上,我已经浏览了阶乘和斐波那契的例子,并很快转到了这个,因为我正在做的编码挑战/任务需要它。不过谢谢,我会看看2d迷宫。
01. function generate(n, array) {
02. if (n == 1) {
03. return array;
04. }
05. else {
06. for (var i = 0; i < n - 1; i++) {
07. generate(n - 1, array);
08. if (n % 2 !== 0) {
09. swap(array[i], array[n - 1]);
10. }
11. else {
12. swap(array[0], array[n - 1]);
13. }
14. }
15. generate(n - 1, array);
16. }
17. }