判斷一個單鏈表中是否存在環

單鏈表中存在環,表明是單鏈表中最後一個結點的指針指向單鏈表中其他結點。

如圖:

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();
}
測試結果




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章