【问题标题】:randomize linked list in C在C中随机化链表
【发布时间】:2012-11-20 21:02:50
【问题描述】:

假设我在 C 程序的内存中有一个保留空间,用于包含 1000 个项目的链表。每个项目只包含列表中下一个项目的引用(最后一个指向第一个)。但是现在它们都设置为null,它只是保留空间。

接下来我有一个 rand() 函数,它给了我一个从 1 到 1000 的随机数。我的问题是,有没有简单的方法可以通过以下方式使用这个函数随机化这个列表:当我从第一个元素开始时,我会遍历整个列表,即列表中不会有比整个列表小的圆圈。

【问题讨论】:

  • 你这里的随机数有什么用?
  • 听起来很简单——你试过什么?
  • 我应该用它来随机化列表。但我不知道如何......天真的方法会按顺序遍历项目并将此数字用作“下一个”元素的索引。但很有可能两个项目会指向同一个项目。

标签: c random linked-list


【解决方案1】:

根据您的描述,您有一个包含 1000 个节点的数组,全部归零。为了便于论证,该数组名为node_array,链接字段名为next。您还有一个名为 head 的指针,它可以指向其中一个节点。

你可以分配一个包含 1000 个整数的数组:

enum { NUM_ITEMS = 1000 };
int mapper[NUM_ITEMS];

您可以初始化列表,使每个数字出现一次:

for (int i = 0; i < NUM_ITEMS; i++)
    mapper[i] = i;

您可以随机播放列表。 (我真的应该检查 Knuth(计算机编程艺术)或 Bentley(编程珍珠或更多编程珍珠),但我认为正确的随机洗牌算法需要一个不同的随机数生成器——生成一个范围内的随机数[n..m) — 而不是只生成 0..999 范围内的数字)。

for (int i = 0; i < NUM_ITEMS; i++)
{
    int j = rand();
    int t = mapper[j];
    mapper[j] = mapper[i];
    mapper[i] = t;
}

您现在可以遍历节点数组,将它们按mapper 数组中的顺序链接。因为数组中没有重复项,所以列表中没有循环。

head = &node_array[mapper[0]];

for (i = 1; i < NUM_ITEMS; i++)
{
    head->next = head;
    head = &node_array[mapper[i]];
}

等等……

【讨论】:

  • 这似乎是我想做的。谢谢:-)
  • 仔细检查 0..999 与 1..1000 并注意逐个错误。未经测试的代码!您刚刚收到警告。
  • 是的,我只是想知道如何做到这一点。我去测试一下,谢谢。
【解决方案2】:

不需要额外空间的解决方案。虽然注意rand()被称为每个节点分配的随机次数:

struct Node
{
    Node* next;
};

int main()
{   
    Node nodes[1000];
    Node* pNext = NULL; 
    Node* pHead = NULL; 
    Node* pTail = NULL;
    int i = 0;
    // reset .next to NULL
    memset(nodes, 0, sizeof(nodes));
    srand ( time(NULL) );
    pHead = &nodes[ rand() % (1000)];           
    pTail = pHead;
    // need only 999 runs as one node is already assigned
    for (i = 0; i < 999; ++i)
    {   
        pTail->next = pTail;
        while ((pNext = &nodes[ rand() % (1000)]) && pNext->next);
        pTail->next = pNext;
        pTail = pNext;
    }
    // pTail->next = pHead; // uncomment if you need circular list
}

【讨论】:

    猜你喜欢
    • 2012-07-03
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多