此帖为 SICP 章节 3.3 的参考答案。为保持可读性,请勿直接在本帖讨论。讨论请另开新帖。
解释:
- 从列表 X 的第一个节点起编号,记为 X(0), X(1), X(2) .... 如果 X 中含有一个环,则 X(n) 的下标 n 可无限增大。
- 可以用 eq? 来判断 X(i), X(j) 是否同一个节点。
- 具体做法为:选取 {X(i)} 的一个子列 {X(2i)},不断地用 eq? 比较 X(i) 与 X(2i)。如果子列 X(2i) 在前移中碰到表尾(NIL),则表明没有环。如果 X(2i) 没碰到表尾,发现某个 i 使 X(i) 与 X(2i) 是同一个点,则表明有环。在有环的情形下,X(2i) 永远不会碰到表尾。
- 这个算法一定能发现环。
设有环且环的大小为 b, 则 X(i) 与 X(2i) 重合等价与 i=2i (mod b) => i=0 (mod b)。环中只有一个节点下标是 b 的倍数,当 X(i) 达到这个节点时,就能发现环。
- 这个算法的时间复杂度是 O(n),空间复杂度为 O(1)
关于这个题目,在 CU 上有更深入一些的讨论,请参考
欢迎光临 Chinaunix (http://bbs.chinaunix.net/) | Powered by Discuz! X3.2 |