1. 给定单链表,检测是否有环。如果有环,则求出进入环的第一个节点。
判断单向链表是否有环,可以采用快指针与慢指针的方式来解决。即定义一个快指针fast和一个慢指针slow,使得fast每次跳跃两个节点,slow每次跳跃一个节点。如果链表没有环的话,则slow与fast永远不会相遇(这里链表至少有两个节点);如果有环,则fast与slow将会在环中相遇。判断出链表有环以后,则需要算出进入环的第一个节点。在fast与slow第一次相遇后,设置一个节点pNode从链表的头部开始遍历,每次只遍历一个节点。这样,当fast与slow再次相遇时,pNode所处的位置便是环的首部。
其实很简单,想象一下在跑道上跑步:两个速度不同的人在操场跑道上一圈一圈地跑,他们总会有相遇的时候。因此我们只需要准备两个指针,同时从链表头出发,一个每次往前走一步,另一个每次往前走两步。如果链表没有环,那么经过一段时间,第二个(速度较快的)指针就会到达终点;但如果链表中有环,两个指针就会在环里转圈,并会在某个时刻相遇。
- LNode* GetLoopNode(LNode* head)
- {
- //前置条件的判断
- if (!head)
- {
- return NULL;
- }
- //定义一个快指针和一个慢指针
- LNode* fast = head;
- LNode* slow = head;
- while (fast && (fast->next))
- {
- fast = fast->next->next;
- slow = slow->next;
- if (fast == slow)
- {
- //如果有环,则返回环的第一个节点
- slow = head;
- while (1)
- {
- fast = fast->next;
- slow = slow->next;
- if (fast == slow)
- {
- break;
- }
- }
- return slow;
- }
- }
- return NULL;
- }