我有一个列表,我想从中随机选择一个节点。由于它不是一个阵列,我事先并不知道它的长度。有没有办法随机选择一个节点(均匀分布)而不必扫描整个列表(在最坏的情况下)两次(即得到它的长度和在随机选择其位置后到达所选节点)?
这是我用于列表的代码:
struct mynode {
in_addr_t paddr;
struct mynode *prev, *next;
};
struct mylist {
struct mynode *first, *last;
char *name;
};
答案 0 :(得分:1)
根据joop和Ilja Everilä的评论中的建议,我在C中实施了 reservoir sampling 。
struct mynode *select_mynode(struct mylist *list) {
struct mynode *list_iter = list->first; // An iterator to scan the list
struct mynode *sel_node = list_iter; // The node that will be selected
int count = 2; // Temporary size of the list
srand((unsigned int) time(NULL)); // Seed
// Select a random element in O(n)
while (list_iter->next != NULL) {
if (rand() % count == (count - 1))
sel_node = list_iter->next;
list_iter = list_iter->next;
count++;
}
return sel_node;
}
注意:有关随机选择的更多信息,请参阅here。