Do you mind switching to another blogger ~~ Http://blog.csdn.net/thestoryofsnow/article/details/6822576 ~
Question: How can we check whether a linked list has a ring? If so, how can we determine the starting point of the ring.
The basic idea of the solution can be explained by running examples. If two people start at the same time, if the track has a ring, the fast side will always catch up with the slow side. Further, the fast side must be several more laps than the slow side, that is, the length of the Multi-run route is a multiple of the lap length.
Based on the above idea, Floyd uses two pointers, one slow pointer (Turtle), and one fast pointer (rabbit) the pointer moves two steps forward each time (two or more steps are equivalent, as long as one is faster than the other, we can see this from the discussion below ). If the two encounter a point other than the linked list header (that is, equal), the linked list has a ring. Otherwise, if the (fast pointer) reaches the end of the linked list, there is no ring.
From the above explanation, the ring detection should be correct. Next, let's take a look at how to determine the starting point of the ring, which is also the second part of the Floyd solution. The method is to move the slow pointer (or fast pointer) to the start point of the linked list. When the two move one step at the same time, the starting point of the ring is the place where the two encounter.
I use (http://cegerede.etu.edu.tr/cycle_detection.jpg) to explain this. Assume that the distance from the start point to the start point of the ring is M. It has been determined that there is a ring. The circumference of the ring is N, and the distance from the first encounter point to the start point of the ring is K. When the two encounter, the total distance between the slow pointer movement is I, I = m + A * n + k, because the fast pointer movement speed is twice that of the slow pointer, so the moving distance of the fast pointer is 2I, 2I = m + B * n + K. Here, A and B are respectively the slow pointers and the number of circles the fast pointer turns when the first encounter. We subtract the two (fast slowing down), so there is I = (B-a) * n. That is, I is a multiple of the cycle length. Using this conclusion, we can understand why the Floyd solution can determine the starting point of the ring. Move one pointer to the start point of the linked list, and the other pointer remains unchanged, that is, the distance from the start point of the linked list is I. The two move at the same time, one step at a time. When the first pointer advances M, that is, when it reaches the starting point of the ring, the other pointer is from the starting point of the linked list to I + M. Considering that I is a multiple of the ring length, it can be understood that the pointer starts from the starting point of the linked list, goes to the starting point of the ring, and then turns around a few circles, so the second pointer must also be at the starting point of the ring. That is, the encounter points of the two are the starting points of the ring.
The instance program is as follows:
1 int * head = List. gethead (); 2 if (Head! = NULL) {3 int * fastptr = head; 4 int * slowptr = head; 5 6 bool iscircular = true; 7 8 do 9 {10 if (fastptr-> next = NULL | fastptr-> next = NULL) // list end found11 {12 iscircular = false; 13 break; 14} 15 16 fastptr = fastptr-> next; 17 slowptr = slowptr-> next; 18} while (fastptr! = Slowptr); 19 // determine the start point of the Ring 20 slowptr = head; 21 While (slowptr! = Fastptr) 22 {23 slowptr = slowptr-> next; 24 fastptr = fastptr-> next; 25} 26 cout <"the starting point of the cycle is" <slowptr <Endl; 27}
Later, I asked how to determine the length of the ring. Of course, if you run another lap after determining the starting point of the ring, but this makes a huge fuss. After confirming that there is a ring, let the fast and slow pointer run again. After Catching up again, the fast and slow pointer just runs one more lap, and the length of the ring is determined.
Floyd ring Determination Algorithm (to determine whether a ring exists)