(Jani Yusef) writes:
> Based on an interview question I heard of but did not know the answer
> to.......
> How do you find and remove a loop from a singly linked list?
> In a google groups search I found the following code which will detect
> the loop but I am stumped how one would remove this loop.
> Any ideas?
Step 1 - find an element 'b' that is part of the loop.
Step 2 - starting at the beginning of the list, step along
it, setting to zero any pointer that is part of
the loop and that points to the element in question.
The resulting algorithm is N squared in the length of the
list, but uses no marking bits or extra memory.
The code:
typedef struct ListElement_struct {
void *head; /* or car, if you prefer */
struct ListElement_struct *next; /* or cdr, if you prefer */
} *List;
static void
break_loop( List possibly_looped ){
List list = possibly_looped, a = list, b = list;
do {
if( b == 0 || b->next == 0 ) return;
a = a->next, b = b->next->next;
} while( a != b );
while( list ){
a = b;
do {
if( a->next == list ){
a->next = 0;
return;
}
} while( a = a->next, a != b );
list = list->next;
}
ASSERT( FALSE );
}