环形链表的实现其实将尾指针指向头指针就可以了。
在这里我想说的题目是:判断一个链表中是否有环。
判断一个链表中是否有环,实际上需要设立两个指针。
一个慢指针,一个快指针。顾名思义,慢指针跑的慢,快指针跑的快。如果两个指针可以相遇,那么链表中存在一个环;如果不能相遇,那么无环。
慢指针一次只能移动一步,快指针一次可以移动两步,如果链表中存在环,那么快指针一定可以追上慢指针。
下面是代码:
(注意:下面的代码仅仅提供一种思路,复制代码无法直接运行)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *fast = head;
ListNode *slow = head;
while(fast!= NULL&&fast->next!=NULL)
{
slow = slow->next;
fast = fast->next->next;
if(fast==slow)
return true;
}
return false;
}
};
关于环形链表的另一题目:
就是如果已经判断该链表中有环,那么入环点处于链表中的什么位置?
此时可以设立另一个指针p3。
当慢指针和快指针相遇的时候,p3指针开始从头跑。当p3指针与慢指针相遇(此时慢指针还在跑),那么相遇的地点就是该环在链表中的入环点。
下面是代码:
p1为慢指针,p2为快指针。
(也只是提供一种思路,代码无法直接运行)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head==NULL)
return NULL;
ListNode *p1=head;
ListNode *p2=head;
do
{
if(p2->next==NULL||p2->next->next==NULL)
return NULL;
p1=p1->next;
p2=p2->next->next;
}while(p1!=p2);
ListNode *p3=head;
while(p1!=p3)
{
p1=p1->next;
p3=p3->next;
}
return p3;
}
};