判断一个单链表中是否存在环

单链表中存在环,表明是单链表中最后一个结点的指针指向单链表中其他结点。

如图:

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();
}
测试结果




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值