單鏈表中存在環,表明是單鏈表中最後一個結點的指針指向單鏈表中其他結點。
如圖:
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.csdn.net/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.csdn.net/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();
}
測試結果