我目前正在开发一个项目,我必须编写的最后一项功能是使用rand函数对链接列表进行洗牌。
我对它的运作方式感到非常困惑。
有人可以澄清我究竟能够实现这个目标吗?
我已经查看过去的代码示例以及我对数组进行洗牌的方法,但数组和链接列表却截然不同。
编辑: 为了进一步澄清,我的教授正在使用链表进行洗牌,因为他很棒。像那样。
答案 0 :(得分:2)
您可以随时添加另一级别的间接...;)
(参见维基百科中的Fundamental theorem of software engineering)
只需创建一个指针数组,根据列表的长度调整大小,从列表中取消链接项并将其指针放到数组中,然后将数组洗牌并重新构建列表。
修改强>
如果必须使用列表,则可以使用类似于merge-sort的方法:
答案 1 :(得分:0)
我不知道它是否给出了合理的随机分布:D
bool randcomp(int, int)
{
return (rand()%2) != 0;
}
mylist.sort(randcomp);
答案 2 :(得分:0)
您可以尝试多次遍历列表并使用某些概率交换相邻节点。像这样:
const float swapchance = 0.25;
const int itercount = 100;
struct node
{
int val;
node *next;
};
node *fisrt;
{ // Creating example list
node *ptr = 0;
for (int i = 0; i < 20; i++)
{
node *tmp = new node;
tmp.val = i;
tmp.next = ptr;
ptr = tmp;
}
}
// Shuffling
for (int i = 0; i < itercount; i++)
{
node *ptr = first;
node *prev = 0;
while (ptr && ptr->next)
{
if (std::rand() % 1000 / 1000.0 < swapchance)
{
prev->next = ptr->next;
node *t = ptr->next->next;
ptr->next->next = ptr;
ptr->next = t;
}
prev = ptr;
ptr = ptr->next;
}
}
答案 3 :(得分:0)
数组和链表之间的最大区别在于,当您使用数组时,您可以使用指针算法直接访问给定元素,这就是operator[]
的工作方式。
然而,这并不妨碍您编写自己的operator[]
或类似的位置,并列出列表中的第n个元素。到目前为止,删除元素并将其放入新列表非常简单。
最大的区别在于,对于数组,复杂度为O(n),对于链表,它变为O(n ^ 2)。