单链表中存在环,表明是单链表中最后一个结点的指针指向单链表中其他结点。
如图:
4结点指向表中1结点。
上图单链表中只存在一个结点,但是它的指针域指向自己。
算法思路:
可以初始化两个指针p1、p2分别指向链表的表头节点。p1指针每次更新:p1=p1->next->next;p2指针更新:p2=p2->next;
当链表中没有环的时候,p1指针达到链表末尾,p2指针还没有达到链表末尾,就是p2追不上p1指针。
当链表存在环的时候,p2指针走的快,p1指针走的慢,一定会出现p2指针超越p1指针,此时p2==p1。
链表定义:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
创建链表结点与连接链表结点
ListNode* CreateListNode(int value)
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->m_pNext = NULL;
return pNode;
}
void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
if(pCurrent == NULL)
{
printf("Error to connect two nodes.\n");
exit(1);
}
pCurrent->m_pNext = pNext;
}
检测链表中是否有环
int find_circle(ListNode * sll)
{
ListNode * fast = sll;
ListNode * slow = sll;
if (NULL == fast)//当头指针为空时,认为链表中无环
{
return 0;
}
while (fast&& fast->m_pNext)
{
fast = fast->m_pNext->m_pNext;
slow = slow->m_pNext;
if (fast == slow)//当快指针追上慢指针
{
return 1;//有环
}
}
return 0;//无环
}
测试用例
void test1()
{
ListNode * node1=CreateListNode(1);
ConnectListNodes(node1,node1);
printf("test1:\n");
if(find_circle(node1))
printf("loop!\n");
else
printf("no loop!\n");
}
<img src="https://img-blog.youkuaiyun.com/20150818201925513?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
void test2()
{
ListNode * node1=CreateListNode(1);
ListNode * node2=CreateListNode(1);
ListNode * node3=CreateListNode(1);
ListNode * node4=CreateListNode(1);
ConnectListNodes(node1,node2);
ConnectListNodes(node2,node3);
ConnectListNodes(node3,node4);
ConnectListNodes(node4,node2);
printf("test2\n");
if(find_circle(node1))
printf("loop!\n");
else
printf("no loop!\n");
}
<img src="https://img-blog.youkuaiyun.com/20150818203804164?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
void test3()//无环
{
ListNode * node1=CreateListNode(1);
ListNode * node2=CreateListNode(1);
ListNode * node3=CreateListNode(1);
ListNode * node4=CreateListNode(1);
ConnectListNodes(node1,node2);
ConnectListNodes(node2,node3);
ConnectListNodes(node3,node4);
printf("test3\n");
if(find_circle(node1))
printf("loop!\n");
else
printf("no loop!\n");
}
void test4()//空指针
{
printf("test4:\n");
if(find_circle(NULL))
printf("loop!\n");
else
printf("no loop!\n");
}
int main()
{
test1();
test2();
test3();
test4();
}
测试结果