为什么我的排列算法对所有排列给出相同的结果?

Why is my permutation algorithm giving me the same result for all permutations?

我受困于某些堆的置换算法。我写了一些 JavaScript 代码来递归地查找值的所有可能排列:数组或字符串。当我 console.log() 排列值时,我的代码似乎可以完美运行,但是当我将它们推送到另一个数组时,我得到的所有值都相同。我很困惑。

我的代码包含两个独立的函数:一个执行元素交换,另一个递归地查找可能的排列:

arr = ["a", "b", "c"];
newArr = [];

// swap mechanism here
function swap(arr, pos1, pos2) {
    var temp = arr[pos1];
    arr[pos1] = arr[pos2];
    arr[pos2] = temp;
};

function perm(arr, nArr, n) {
    n = n || arr.length; 
    if (n === 1) {
        console.log(arr); // console.log() works great
        newArr.push(arr); // pushing the permuted values does not
    }
    else {
        for(var i = 1; i <= n; i += 1) {
            perm(arr, nArr, n - 1);
            if (n % 2) {
                var j = 1;
            }
            else {
                var j = i;
            }
            swap(arr, j - 1, n - 1);
        }
    }
};

这是一个简单的(堆)引用与(堆栈)值问题。原因很简单:arr 在所有递归调用中引用内存中的同一个数组。因此,当您调用 newArr.push(arr) 时,对同一对象的另一个引用将添加到结果列表中。当您执行 swap 时,您将元素交换为 newArr 的所有元素,因为它们指向同一个数组。另请参阅 Copying array by value in JavaScript for a possible workaround. (Basically use Array.slice 创建独立副本的方法)。