判断一个链表是否存在环:例如n1->n2->n3->n4->n5->n6->n2就是一个有环的链表,环的开始结点是n
6。
有的博客说的一种方法:遍历链表,将遍历过的结点放在一个字典中,如果一个结点已经存在字典中,说明有环。
个人认为这种方法不可行,因为如果链表中如果有重复的元素,但是重复的元素的地址是不一样的,此时并没有形成环。所以这种判断环的方法不可行。
下面是正确的解法:用快慢指针的方法。时间复杂度O(n),空间复杂度O(1)。
设置p1为慢指针,p2为快指针,两者初始时都指向链表的头结点 ,慢指针p1每次前进1步,快指针p2每次前进2步。如果链表存在环,则快指针p2肯定先进入环,慢指针p1后进入环,两个指针必定会相遇。如果不存在环,则快指针会先行到达链表的尾部变为None。
以下是程序:
class LNode:
def __init__(self, elem):
self.elem = elem
self.pnext = None
def exitLoop(LList):
p1 = p2 = LList
while p2 and p2.pnext: #当链表为空或者只有一个结点时,就不执行循环体里的程序,返回False
p1 = p1.pnext
p2 = p2.pnext.pnext
if p1 == p2:
return True
return False
if __name__=="__main__":
LList = LNode(1)
p1 = LNode(2)
p2 = LNode(3)
p3 = LNode(4)
p4 = LNode(5)
p5 = LNode(6)
LList.pnext = p1
p1.pnext = p2
p2.pnext = p3
p3.pnext = p4
p4.pnext = p5
p5.pnext = p2
print(exitLoop(LList))