void SListHaveCircle(SList* plist){
assert(plist);
SListNode* fast = plist->_head;
SListNode* slow = plist->_head;
while (slow && fast && fast->_next){
slow = slow->_next; //都从起点出发,一个一次走一步
fast = fast->_next->_next; //一个一次走两步
if (slow == fast){ //相遇(即两个指针相遇),表示链表成环
return 1;
}
}
return 0;
}
可以这样去思考,如果是一条直线,A和B同时从起点出发,B的速度是A的2倍,一直跑下去,A和B肯定不会相遇,这其实可以对应到无头单向链表中无环的情况。
现在改掉之前的条件,让A和B先跑一段直线然后入圈,可以看下面这个图帮助理解
这样如果让A和B同时从起点出发,并且B的速度是A的速度的两倍,这样跑下去A和B必然能够相遇,其实这也就能对应说明链表成环。
具体来说就是,我们创建两个指针,一个步长为1,一个步长为2,分别对应上面代码中的SListNode* fast和SListNode* slow,让他们同时从起点出发,在保证fast,slow和fast->_next部位NULL的情况下进行循环直到fast == slow,说明他们相遇即成环。