Java 洗牌链表
我很难为洗牌算法使用伪代码,并将其转换为可工作的java代码。我正在尝试洗牌一个链接列表。总的来说,该方法获取链表头的指针,并随机返回指向同一列表头的指针。我想使用我创建的getLength和getItem方法Java 洗牌链表,java,random,linked-list,shuffle,Java,Random,Linked List,Shuffle,我很难为洗牌算法使用伪代码,并将其转换为可工作的java代码。我正在尝试洗牌一个链接列表。总的来说,该方法获取链表头的指针,并随机返回指向同一列表头的指针。我想使用我创建的getLength和getItem方法 public static ListElement shuffle(ListElement head){ head = head.getLength(); ListElement head2= null; while( head == null) { int rand
public static ListElement shuffle(ListElement head){
head = head.getLength();
ListElement head2= null;
while( head == null) {
int random = (int) Math.random() * n;
for(int i=0;i<random;i++){
head= head.getNext();
}
}
return head;
}
公共静态ListElement洗牌(ListElement头){
head=head.getLength();
ListElement头2=null;
while(head==null){
int random=(int)Math.random()*n;
对于(int i=0;i
看起来应该是int n=head.getLength();
看起来它应该是while(head!=null){
您需要返回新列表。我只是稍微重写了代码,使其遵循伪代码
return head;
ListElement head2 = null;
int length = head.getLength();
while (head != null) {
int k = (int) Math.random() * length;
// Assume there is function deleteAt(index) that removes
// the element at specified index and returns the deleted
// element
ListElement e = head.deleteAt(k);
// Although I can just give the implementation - I'll leave this
// as exercise.
// You can have a function that add element to front
// head2.addFront(e);
e.setNext(head2);
head2 = e;
// Instead of querying the length again
// decrement the length
length--;
}
return head;
伪代码的问题是,在最坏的情况下,每次要删除元素以将其添加到新列表时,都必须迭代到原始列表的末尾
return head;
原始列表o=[a,b,c,d,e,f,g]
新列表:n=[]
o=[a,b,c,d,e,f]
n=[g]
o=[a,b,c,d,e]
n=[g,f]
o=[a,b,c,d]
n=[g,f,e]
我现在能想到的最佳答案是创建一个列表大小的数组,并遍历原始链表,在随机位置向数组插入元素:
原始列表o=[a,b,c,d,e,f,g]
新数组a=[,,,,,,]
o=[b,c,d,e,f,g]
a=[,a,,,,]
o=[c,d,e,f,g]
a=[,a,,b,,]
o=[d,e,f,g]
a=[c,a,b,,]
o=[e,f,g]
a=[c,a,b,d,]
将它们放入数组后,在数组中循环并修复链接
在原始版本中,您必须调用getNext()
6次,然后5次,然后4次,然后3次
在我的中,您调用getNext()
6次,然后在数组中循环重置“下一个”引用。ListElement是什么?你能发布代码吗?@Sujay:我很确定它是链接列表。是的ListElement是链接列表。你的代码是剪切粘贴的吗?head被视为一个元素和一个长度。“n”被使用,但没有定义。你的伪代码看起来不错-rem余烬当您从L中删除项目时,L的长度会发生变化。我想学习如何使用math.random()这就是为什么我在集合中使用它而不是洗牌。随机数生成器可能会多次返回相同的索引值,特别是对于小列表。这意味着在您的情况下,您可以用迭代的成本来换取生成比严格要求更多的随机数的成本。。。(此外,还需要过滤掉这些值。)如果取了点,只取最近的打开点。发生冲突还有另一个问题——RNG可能多次生成相同的值,因此您需要将其过滤掉。@user268396这不是真正的随机移动。您需要在移动时从列表中删除元素,以便只从其余元素中随机选择。
int random = (int) Math.random() * n;
for(int i=0;i<random;i++){
head= head.getNext();
return head;
ListElement head2 = null;
int length = head.getLength();
while (head != null) {
int k = (int) Math.random() * length;
// Assume there is function deleteAt(index) that removes
// the element at specified index and returns the deleted
// element
ListElement e = head.deleteAt(k);
// Although I can just give the implementation - I'll leave this
// as exercise.
// You can have a function that add element to front
// head2.addFront(e);
e.setNext(head2);
head2 = e;
// Instead of querying the length again
// decrement the length
length--;
}
return head;