单链表的问题在面试考试等等等等中频频上镜,大有赶上凤姐超越芙蓉之势。假若有一个蛋疼的程序猿把单链表的末尾结点的next指针指向了单链表中一个随机的结点上,那么我们经常写的一个循环while(p)或者while(p->next)就可以父传子子传孙子子孙孙无穷尽了。
话说怎么判断单链表是否带环了呢?大部分人都知道了:让快指针追慢指针,追上了就有环,快指针走到头了,就无环。
那么又如何判断那个dt的程序猿把尾结点的next指针指向何处或者说环的入口在哪呢?也许下面的推导只是小学初中级的数学知识,但是大多数人(包括我在内)都没有想到过这么玄而又玄的问题可以用这么简单的数学理论来解答:
假设单链表的总长度为L,头结点到环入口的距离为a,环入口到快慢指针相遇的结点距离为x,环的长度为r,慢指针总共走了s步,则快指针走了2s步。另外,快指针要追上慢指针的话快指针至少要在环里面转了一圈多(假设转了n圈加x的距离),得到以下关系:
s = a + x;
2s = a + nr + x;
=>a + x = nr;
=>a = nr - x;
由上式可知:若在头结点和相遇结点分别设一指针,同步(单步)前进,则最后一定相遇在环入口结点,搞掂!
附图: