Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!bb3.andrew.cmu.edu!newsfeed.pitt.edu!gatech!newsfeed.internetmci.com!miwok!linex1!linex.com!donham
From: donham@linex.com (Jake Donham)
Subject: Re: Cycle-detection algorithm?
In-Reply-To: cdjeris@midway.uchicago.edu's message of Mon, 19 Feb 1996 03:37:09 GMT
X-Nntp-Posting-Host: linex.com
Message-ID: <DONHAM.96Feb20185320@linex.linex.com>
Sender: news@linex1.linex.com
Organization: LineX Communications (415) 455-1650
References: <Dn07Dx.C6q@midway.uchicago.edu>
Date: Wed, 21 Feb 1996 02:53:19 GMT
Lines: 29

"Christopher" == Christopher Jeris <cdjeris@midway.uchicago.edu> murmurs:

    Christopher> 3.19 Write a procedure that determines,
    Christopher> _in_constant_space_, whether a given list structure
    Christopher> contains a cycle.

One cute trick is the "tortoise and hare" method: Start two pointers
at the head of the list. Now loop, advancing one pointer (the
tortoise) by one pair, and the other (the hare) by two pairs. If the
tortoise and the hare ever point to the same pair (except at the
beginning of the algorithm) then you have a loop. If the hare gets to
the end of the list then you have no loop.

This algorithm takes O(N) time (once the tortoise has entered the
loop, the hare is at most N jumps behind it, and each iteration brings
the hare one jump closer to the tortoise).

I think the pointer-reversal method that someone mentioned goes like
this: traverse the list; for each new pair you see, follow the cdrs
for M steps (where M is the number of pairs you've seen so far) to see
if you get back to the first pair in the list. If so, you've got a
loop. If not, change the cdr of the current pair to point to the
previous pair, and continue on to the next pair. If you reach the end
of the list then you have no loop.

It might help to draw a picture to see how this works. It takes O(N^2)
time.

Jake
