【问题标题】:Heap's Algorithm implementation in list of lists列表列表中的堆算法实现
【发布时间】:2018-02-25 00:09:21
【问题描述】:

我正在使用 Heap 的算法来创建一个列表列表,其中包含所述列表的每个排列。每个排列将是它自己的列表。当我在算法中打印它时它可以正常工作,但是当我尝试将它添加到我的列表时它不能正常工作并且它们都是相同的数组(4、1、2、3)。我注释掉了我测试的打印以确保它正常工作。

我当前的代码:

public static ArrayList<int[]> lists = new ArrayList<>();

public static void main(String[] args) {
    int[] list = {1,2,3,4};
    heapsAlgorithm(4,list);
    for(int i = 1; i <= lists.size(); i++) {
        System.out.println("List " + i + ": " + Arrays.toString(lists.get(i-1)));
    }
}

public static void heapsAlgorithm(int n, int[] list) {
    if (n == 1) {
        lists.add(list);
        //System.out.println(Arrays.toString(list));
    }
    else {
        for(int i = 0; i < n; i++) {
            heapsAlgorithm(n - 1, list);
            if ( n % 2 == 0) {
                int swap = list[i];
                list[i] = list[n-1];
                list[n-1] = swap;
            }
            else {
                int swap = list[0];
                list[0] = list[n-1];
                list[n-1] = swap;
            }
        }
    }
}

工作:

[1, 2, 3, 4]
[2, 1, 3, 4]
[3, 1, 2, 4]
[1, 3, 2, 4]
[2, 3, 1, 4]
[3, 2, 1, 4]
[4, 2, 3, 1]
[2, 4, 3, 1]
[3, 4, 2, 1]
[4, 3, 2, 1]
[2, 3, 4, 1]
[3, 2, 4, 1]
[4, 1, 3, 2]
[1, 4, 3, 2]
[3, 4, 1, 2]
[4, 3, 1, 2]
[1, 3, 4, 2]
[3, 1, 4, 2]
[4, 1, 2, 3]
[1, 4, 2, 3]
[2, 4, 1, 3]
[4, 2, 1, 3]
[1, 2, 4, 3]
[2, 1, 4, 3]

输出不正确:

List 1: [4, 1, 2, 3]
List 2: [4, 1, 2, 3]
List 3: [4, 1, 2, 3]
List 4: [4, 1, 2, 3]
List 5: [4, 1, 2, 3]
List 6: [4, 1, 2, 3]
List 7: [4, 1, 2, 3]
List 8: [4, 1, 2, 3]
List 9: [4, 1, 2, 3]
List 10: [4, 1, 2, 3]
List 11: [4, 1, 2, 3]
List 12: [4, 1, 2, 3]
List 13: [4, 1, 2, 3]
List 14: [4, 1, 2, 3]
List 15: [4, 1, 2, 3]
List 16: [4, 1, 2, 3]
List 17: [4, 1, 2, 3]
List 18: [4, 1, 2, 3]
List 19: [4, 1, 2, 3]
List 20: [4, 1, 2, 3]
List 21: [4, 1, 2, 3]
List 22: [4, 1, 2, 3]
List 23: [4, 1, 2, 3]
List 24: [4, 1, 2, 3]

我认为我的 ArrayList 使用错误,但我不确定在哪里。有什么建议吗?

【问题讨论】:

  • 您需要将数组的副本添加到列表中:lists.add(Arrays.copyOf(list, list.length))。
  • 谢谢!那行得通。为什么添加数组的副本而不是直接添加数组的任何原因?
  • 因为将数组(或通常的任何东西)添加到列表中不会复制它:您只是在存储一个引用。因此,对列表“外部”数组的任何更新也会更新到列表“内部”的同一数组。
  • 这不是堆算法的正确实现。您可能被 geeksforgeeks 网站误导了,这是错误的,或者当维基百科页面被认为自己更了解的人污损时,通常是因为他们查看了另一个错误的网站。堆的算法在每次迭代中恰好交换两个元素。错误的实现不符合这个限制;看第七步,它从 3,2,1,4 过渡到 4,2,3,1,这显然不是一次交换,因为三个元素已被移动。

标签: java algorithm arraylist data-structures heaps-algorithm


【解决方案1】:

你需要复制你的 int 数组。

您有一个可变的数组实例和数组列表,假设您保留排列。基本上,发生了什么:

  1. 你做排列。
  2. 您将排列添加到 ArrayList。
  3. 您对 THE SAME 对象进行了另一次排列。
  4. 您将已在此列表中的对象添加到 ArrayList。

最后你有 ArrayList 20 次添加相同的 int 数组。

【讨论】:

    猜你喜欢
    • 2015-11-19
    • 2011-04-30
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    • 2017-08-24
    相关资源
    最近更新 更多