使用随机顺序的元素将数组插入到链接列表中

时间:2013-12-26 02:38:57

标签: arrays algorithm random linked-list shuffle

我有一个数组,说:books[10]
以及一个链表,例如:bookList

我想将books[10]中的所有元素插入到链接列表中,但是以随机顺序插入。

解决方案1: 对阵列进行随机播放,然后从0插入到长度为1。

解决方案2: 按原样从0插入到长度为1,然后随机播放链接列表。

解决方案3: 生成indexArray= {0, 1, 2, ..., length-1}的Fisher-Yates混洗数组,然后按顺序将元素插入到链表中:

for(i = 0; i < indexArray.length; i ++)
   bookList.add(books[indexArray[i]]);

目前我使用1似乎是最简单的,我认为解决方案3会更好,如果我的数组中的对象很大,因为我不必将原始数组洗牌而是一个int数组对于索引而言。

有更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

另一种解决方案是将方法(1)和(3)结合起来:

(有关参考,请参阅http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle的“现代算法”部分。)

  • i的索引n重置为1(使用基于1的索引)。
  • 在每个步骤中,在m1之间选择一个随机数i
  • 将索引m处的数组元素插入到链接列表的前面。 (我们将从前到后构建列表,但实际上如果您决定在列表后面插入条目则没有任何区别。从后到前构建可以避免跟踪指向后面的指针列表,以避免在每一步扫描到最后导致O(n)插入时间。)
  • 将索引i处的数组元素移动到索引为m的插槽。

这避免了就地shuffle的少量开销,避免了生成索引数组的内存开销,并避免了与方法(2)相关联的链表的复杂的就地混乱。它在O(n)时间运行,使用O(1)额外内存(忽略用于原始数组和链表的内存)。

编辑:我认为上面描述的算法实际上应该是最容易实现的三个选项。除非您的阵列非常大,否则您所拥有的选项的实际运行时和内存使用差异可能会微不足道。

如果数组中条目的大小确实很大,则此算法会遇到与就地shuffle相同的问题,即必须移动大数据集,并且在这种情况下可能生成一个列表指数更好。