随机改组链表

时间:2014-04-15 20:38:23

标签: c++

我目前正在开发一个项目,我必须编写的最后一项功能是使用rand函数对链接列表进行洗牌。

我对它的运作方式感到非常困惑。

有人可以澄清我究竟能够实现这个目标吗?

我已经查看过去的代码示例以及我对数组进行洗牌的方法,但数组和链接列表却截然不同。

编辑: 为了进一步澄清,我的教授正在使用链表进行洗牌,因为他很棒。像那样。

4 个答案:

答案 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)。