我很难将伪代码用于混洗算法并将其转换为可用的java代码。我试图改组一个链表。总的来说,该方法采用链表头部的指针,并随机返回指向同一列表头部的指针。我想使用我创建的getLength和getItem方法。
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;
}
伪代码:
A list L of length n
A new list R, empty
while L is not empty
pick a random k
such that 0<=k<= (length L)
remove the kth element of L
call it e
prepend e to R
答案 0 :(得分:0)
head = head.getLength();
看起来应该是int n = head.getLength();
while( head == null) {
看起来应该是while (head != null) {
int random = (int) Math.random() * n;
for(int i=0;i<random;i++){
head= head.getNext();
您正在覆盖head变量。您需要使用新变量来查找列表的第k个元素,并将头部指向旧列表。
一旦找到该元素,您就不会对该元素做任何事情,您需要从旧列表中提取它(硬)并将其添加到新列表中。
return head;
您需要返回新列表。
答案 1 :(得分:0)
我只是稍微重写一下代码,以便它遵循伪代码。
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;
答案 2 :(得分:0)
您的伪代码的问题在于最糟糕的情况,每次您想要删除元素以将其添加到新列表时,您将不得不迭代到原始列表的末尾。
原始列表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次,然后循环重置你的'下一个'参考数据。