题目描述
单链表有环是指单链表中某个节点的next域指向的是链表中在它之前的某一个节点,这样在链表尾部形成一个环形结构,如何半段一个链表是否有环
思路
使用两个指针,初始时两个指针均指向链表头位置,然后一个指针每次走两步,一个指针每次走一步,如果在循环过程中遇到两个指针相等,则说明有循环返回true。如果出现一个指针无法继续往下走,则退出循环返回false。因为fast先进入环,在slow进入之后,如果把slow看作在前面,fast在后面每次循环都向slow靠近1,所以一定会相遇,而不会出现fast直接跳过slow的情况。
代码实现
def isLoop(head):
if head is None or head.next is None:
return None
#初始slow和fast都指向链表的第一个节点
slow = head.next
fast = head.next
while fast is not None and fast.next is not None:
slow = slow.next
fast = fast.next.next
if slow == fast:
return slow
return None
既然判断出有环,那么如何找到环的入口点呢??
def findLoopNode(head, meetNode):
first = head.next
second = meetNode
while first != second:
first = first.next
second = second.next
return first
计算环的长度
def LoopLength(slow):
count = 1
fast = slow.next
while slow != fast:
fast = fast.next
count += 1
return count
整体代码如下:
class LNode:
def __init__(self, item):
self.data = item
self.next = None
#创建一个链表
def CreateLinkList():
i= 1
head = LNode(None)
head.next = None
tmp = None
cur = head
while i < 7:
tmp = LNode(i)
tmp.next = None
cur.next = tmp
cur = tmp
i += 1
cur.next = head.next.next.next
return head
#判断单链表是否有环
def isLoop(head):
if head is None or head.next is None:
return None
#初始slow和fast都指向链表的第一个节点
slow = head.next
fast = head.next
while fast is not None and fast.next is not None:
slow = slow.next
fast = fast.next.next
if slow == fast:
return slow
return None
#找到环的入口点
def findLoopNode(head, meetNode):
first = head.next
second = meetNode
while first != second:
first = first.next
second = second.next
return first
#计算环的长度
def LoopLength(slow):
count = 1
fast = slow.next
while slow != fast:
fast = fast.next
count += 1
return count
#打印链表
def PrintLinkList(head):
cur = head.next
while cur != None:
print(cur.data, end=' ')
cur = cur.next
if __name__ == "__main__":
head = CreateLinkList()
meetNode = isLoop(head)
if meetNode is None:
print("无环")
else:
print("有环,相遇点为:" + str(meetNode.data))
# PrintLinkList(head)
loopNode = findLoopNode(head, meetNode)
print("环的入口点为:" + str(loopNode.data))
print("环的长度为:" + str(LoopLength(meetNode)))
运行结果如下:
有环,相遇点为:5
环的入口点为:3
环的长度为:4