We discussed two methods of "finding middle element" in a linked list in other page. Here is the third iteration.
middle3 and middle2 are really identical routines. The only difference is the while loop condition. middle2 checks if fast reaches the END. middle3 checks if fast reaches the END or fast reaches the last node. Note that in logic ~(A or B) is equivalent to ~A and ~B. BTW, that's called De Morgan's Law. The while loop keeps going if fast is not at END and fast is not at the last node.
One interesting question is the while condition in middle3. fast could be NULL when it encounters the while condition. Shouldn't fast->next cause a problem just like our earlier discussion on find_middle() // need to check?
As it turns out, the sequence of the instruction takes care of this for us. If we reverse the two conditions, it will have the NULL->next issue again. Go ahead and experiment it. The current coding sequence asks fast be checked first. If fast is NULL, the while condition will fail, the second part will never be checked.
Debug with Local Variables
One simple approach I often used to debug a looping routine is examining variables. I usually set breakpoint at the beginning of each loop and examine all relevant variables to see if they behave the way I expected, one cycle, two cycle, etc. If I see things strange (i.e. not what I expect), I then do the single step through the instructions. I will use Eclipse to illustrate, but the other IDEs I know all have similar facilities.
Examining variables in Eclipse is a straight forward exercise. When a program breaks in a routine, all its local variables show up in the (x)=Variables window. If you do not see this window, go to "Window" and "open view". Still need more detail? Here is the youtube video.