【发布时间】:2008-12-30 10:28:17
【问题描述】:
我需要一个将链表作为参数的方法,如果它是循环的,则返回真或假。
ex:circular linkedlist 表示存在指向任何先前节点的节点。 我忘了告诉一些限制,我不能使用任何数据结构或动态内存分配。 我只能使用局部变量,并且算法可以按照有人对我说的 n 步完成(我现在正在考虑使用两个指针?)
【问题讨论】:
标签: algorithm
我需要一个将链表作为参数的方法,如果它是循环的,则返回真或假。
ex:circular linkedlist 表示存在指向任何先前节点的节点。 我忘了告诉一些限制,我不能使用任何数据结构或动态内存分配。 我只能使用局部变量,并且算法可以按照有人对我说的 n 步完成(我现在正在考虑使用两个指针?)
【问题讨论】:
标签: algorithm
我相信您正在寻找Floyd's Cycle-Finding Algorithm。有一个比我在here 上给出的更好的解释。
在 C 和 Scheme 中也有几个实现,文档超过 here。
【讨论】:
标准哈希计数适用:
函数有循环(列表): foreach 列表中的节点: 地址 = address_of(node.next); 元素 = hashtable.get(地址); 如果(元素 == NULL): hashtable.put(地址) 别的: 返回真 返回假编辑:根据接受的答案的第二个链接,这可行但效率低下,这意味着有很多更有效的解决方案。
【讨论】:
这是微不足道的。
previousnodes ← set()
previousnodes.add(firstnode)
currentnode ← firstnode.next
while (currentnode in previousnodes) || (currentnode != null):
previousnodes.add(currentnode)
currentnode ← currentnode.next
when (currentnode = 0) return false
return true
【讨论】:
我自己遇到了一个解决这个问题的经典解决方案,忍不住把它贴在这里(虽然我猜原来的发帖人现在很可能已经毕业了)。从起始节点开始,只需开始反转列表。如果列表不是循环的,则该过程将以 Null 结束,如果列表确实是循环的,则该过程将在起始节点处结束。就是这样,一个具有恒定额外空间的线性时间算法。只需再次反转列表即可恢复原始列表。
【讨论】: