All about flooble | fun stuff | Get a free chatterbox | Free JavaScript | Avatars
 perplexus dot info

 Lost my pointer 2 (Posted on 2003-12-18)
You are given a pointer to the head of a SINGLY linked list. Write a function that takes as an argument one pointer, and determines whether or not the list is "looped".

A "looped" list means that the linked list has a node that points to a PREVIOUS member (thereby creating a cycle).

Clearly, if a list is looped, and you attempt to simply go from node to each next node until you reach the end, you will never get to an end (just going around and around the loop forever).

Conditions: The list (and the loop, if it exists) may be of any given size (up to available memory), and your function has only 64 bytes (16 4-byte pointers) of available heap/stack space).

***Extra Credit: What is the speed (big-O notation) of your solution?
__________________________________

For those of you non-computer types: a singly linked list is simply a list of records where each record (node) points to the NEXT record. (The only way to get to a node is to first be at the previous node.) The first node is special in that we keep track of where it is.

So, we can always get to the first node, but to get to the second we must first get to the first node. To get to the third, we must first get to the second, and so on.

Therefore, it is an easy matter of traversing all the nodes in order. But it is impossible to go backwards (unless one keeps track of all previously visited nodes) or to access the nodes in any other order (like random access or alphabetically).

Normally, the last node points to NULL, and we generally know to stop at that point.

This problem arises when one of the nodes MIGHT point to a node that occurred in the list previously. (For instance, the 651st node points to the 83rd node.) Then we will end up going from the 651st -> 83rd -> 84th... and continue looping.

The question is... how do we know that we've looped? (And how quickly can we determine whether or not we looped.)

 See The Solution Submitted by SilverKnight Rating: 4.0000 (2 votes)

Comments: ( Back to comment list | You must be logged in to post comments.)
 Solution | Comment 6 of 22 |
Description of algorithm:
save a pointer to the current item on the list
go down the list COUNT times, checking to see if you get back to the item you saved (or hit the end -- start COUNT at 1).
double COUNT, save the current location instead, and continue

If the list has length N, with a loop of M items on the end, then the number
of items checked will be on the order of N+M (actually, it will be bounded
by 2*max(N,M)), so the runtime is O(N+M).

Here is a C subroutine (sans indentation, as usual -- how do I fix that?):

count=1;
while(1) {
for(i=0; i<count; i++) {
if(item==save) goto is_looped;
if(item==NULL) goto is_not_looped;
item=item->next;
}
count=2*count;
save=item;
}
is_looped:
printf("Is looped\n");
return(1)
is_not_looped:
printf("Is NOT looped\n");
return(0)
}

 Posted by Brian Wainscott on 2003-12-18 16:03:52

 Search: Search body:
Forums (0)