1.介绍环形链表
环形链表即链表中形成闭环的一种特殊数据结构,与常规单向链表最后节点指向NULL有着明显差异,形成原因是某处节点next指向了该链表的另一处节点,这就导致链表永远不会“结束”,陷入循环。举例:
2.环形链表的判断:
显然,假设我们通过固定一个指针(p),让指针(q)去遍历链表,如果p==q,则该链表是环形链表,否则不是。这一方法明显错误,因为我们并不知道链表是在哪里进入循环。
介绍双指针:
快慢指针,快指针始终比慢指针多走一步,显而易见的,只要是环形链表,快指针一定会套圈“追上”慢指针。
bool listhasCycle(struct ListNode *head)
{
struct ListNode*slow,*fast;
slow=head;
fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return true;
}
return false;
}
寻找环的入口节点:
仍然采用快慢指针,判断是环形指针后,指针meet指向快慢指针的相遇处,指针cur指向头节点,分别向后移动meet 和cur,相遇处即环形链表环的入口节点。
struct ListNode *detectCycle(struct ListNode *head)
{
struct ListNode *slow,*fast;
slow=fast=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(slow==fast)
{
struct ListNode*meet=slow;
struct ListNode*cur=head;
while(meet!=cur)
{
meet=meet->next;
cur=cur->next;
}
return meet;
}
}
return NULL;
}
那为什么当cur=meet,就一定是入口节点呢?
如图:
总结:学习了环形链表的判断,环入口节点的寻找
❀希望我的内容可以帮到你❀