Arrays 是什么与Java列表相关的微妙之处导致了我的堆';s算法实现失败?

Arrays 是什么与Java列表相关的微妙之处导致了我的堆';s算法实现失败?,arrays,algorithm,list,arraylist,permutation,Arrays,Algorithm,List,Arraylist,Permutation,我试图在Java中实现“Heap算法”(Heap's Algorithm),它构造给定集合的所有置换。(我知道这在技术上不是Heap的算法,因为它指出了一些微妙之处,但目前这对我来说并不太重要) 我拥有的:我从一段代码开始,这段代码可以正常工作并实现我想要的: 公共静态列表置换(ta[]{ LinkedList=新建LinkedList(); heapermutation(a,a.length,a.length,list); 退货清单; } //用堆算法生成置换 公共静态void堆(ta[],i

我试图在Java中实现“Heap算法”(Heap's Algorithm),它构造给定集合的所有置换。(我知道这在技术上不是Heap的算法,因为它指出了一些微妙之处,但目前这对我来说并不太重要)

我拥有的:我从一段代码开始,这段代码可以正常工作并实现我想要的:

公共静态列表置换(ta[]{
LinkedList=新建LinkedList();
heapermutation(a,a.length,a.length,list);
退货清单;
}
//用堆算法生成置换
公共静态void堆(ta[],int size,int n,List)
{ 
//如果大小变为1,则添加获得的
//列表的排列
如果(大小==1)
list.add(a.clone());
对于(int i=0;i首先,输入错误
如前所述,第一件需要快速修复的事情是您的输入错误:偶数情况应为
T temp=aTemp.get(i);

第二,克隆 问题的关键在于,您没有掌握列表/数组是如何/何时被修改的,而不是何时被复制以进行累积

即使不看你的方法在做什么,我们也可以看到数组版本在原地操纵数组,除非它的大小是1,在这种情况下,它被复制到结果列表中

换句话说,在数组版本中,无论递归的深度有多深,交换项的总是同一个数组。 只有当我们想记住项目的某个排列时,我们才会复制该排列,以确保该排列被冻结(
a.clone()
),这意味着在此之后,我们仍然可以交换项目,而不会对已经累积的排列进行任何修改

另一方面,列表版本在每次启动时复制其输入。换句话说,在每个递归阶段,使用原始列表的本地副本交换项目。当递归展开时,此副本的当前项目排列将丢失

因此,如果删除列表所在位置的克隆,只将其保留在
if size==1)
案例中,就应该可以了

最后,与ararys相比,列表案例并没有什么微妙之处,只是你在没有分析影响的情况下移动了一些“克隆”逻辑

在该位置,输出变为:

[[a, b, c, d], 
[b, a, c, d],
[c, a, b, d],
[a, c, b, d],
[b, c, a, d],
[c, b, a, d],
[d, b, c, a],
[b, d, c, a],
[c, d, b, a],
[d, c, b, a],
[b, c, d, a],
[c, b, d, a],
[d, a, c, b],
[a, d, c, b],
[c, d, a, b],
[d, c, a, b],
[a, c, d, b],
[c, a, d, b],
[d, a, b, c],
[a, d, b, c],
[b, d, a, c],
[d, b, a, c], 
[a, b, d, c],
[b, a, d, c]]
首先是打字错误 如前所述,第一件需要快速修复的事情是您的输入错误:偶数情况应为
T temp=aTemp.get(i);

第二,克隆 问题的关键在于,您没有掌握列表/数组是如何/何时被修改的,而不是何时被复制以进行累积

即使不看你的方法在做什么,我们也可以看到数组版本在原地操纵数组,除非它的大小是1,在这种情况下,它被复制到结果列表中

换句话说,在数组版本中,无论递归的深度有多深,交换项的总是同一个数组。 只有当我们想记住项目的某个排列时,我们才会复制该排列,以确保该排列被冻结(
a.clone()
),这意味着在此之后,我们仍然可以交换项目,而不会对已经累积的排列进行任何修改

另一方面,列表版本在每次启动时复制其输入。换句话说,在每个递归阶段,使用原始列表的本地副本交换项目。当递归展开时,此副本的当前项目排列将丢失

因此,如果删除列表所在位置的克隆,只将其保留在
if size==1)
案例中,就应该可以了

最后,与ararys相比,列表案例并没有什么微妙之处,只是你在没有分析影响的情况下移动了一些“克隆”逻辑

在该位置,输出变为:

[[a, b, c, d], 
[b, a, c, d],
[c, a, b, d],
[a, c, b, d],
[b, c, a, d],
[c, b, a, d],
[d, b, c, a],
[b, d, c, a],
[c, d, b, a],
[d, c, b, a],
[b, c, d, a],
[c, b, d, a],
[d, a, c, b],
[a, d, c, b],
[c, d, a, b],
[d, c, a, b],
[a, c, d, b],
[c, a, d, b],
[d, a, b, c],
[a, d, b, c],
[b, d, a, c],
[d, b, a, c], 
[a, b, d, c],
[b, a, d, c]]

在偶数情况下,
T temp=aTemp.get(0);
应该是
T temp=aTemp.get(i);
@GPI-谢谢您的反馈!在实施该更改后(非常尴尬),我仍然没有得到正确的答案。我将更新以表明。我不知道其中的微妙之处,但不应该以某种方式使用
n
吗?数组变量在
size==1
时添加了一个数组克隆,列表变量主要在
列表a
的深层副本上运行。@greybeard-这是我遇到的可能的困惑之一我的行动计划是首先得到一个我满意的工作实现,然后尝试做一些事情来修复那些看似无关的部分。考虑到我甚至无法实现功能正确性,我现在不打算去处理
n
。至于你的第二个评论:问题出在哪里我建议我(a)在
size!=1
的情况下不实现数组克隆,或者(b)需要完全做其他事情?在偶数情况下,
t temp=aTemp.get(0);
应该是
t temp=aTemp.get(I);
@GPI-谢谢你的反馈!在实现了那个更改之后(这非常尴尬),我仍然没有得到正确的答案。我将更新以表明。我不知道其中的微妙之处,但不应该以某种方式使用
n
吗?数组变量在
size==1
时添加了一个数组克隆,列表变量主要在
列表a
的深层副本上运行。@greybeard-这是我遇到的可能的困惑之一我的行动计划是首先得到一个我满意的工作实现,然后尝试做一些事情来修复那些看似无关的部分。考虑到我甚至无法实现功能正确性,我现在不打算去处理
n
。至于你的第二个评论:问题出在哪里m我(a)不在
大小!=1
情况下实现阵列克隆,或