Javascript 堆';s算法遍历

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

所以,我正在学习递归,我正在研究一个编码挑战,它需要数组中所有元素的变化

有人指着我说,这就是我迄今为止用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);
    }
}
在本例中,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. }