定义一个集合用来存放结点的引用,并将其初始化为空,从链表的头结点开始向后遍历,每遍历到一个结点就判断集合中是否有这个结点的引用,若是没有,说明这个结点是第一次访问,尚未造成环,那么将这个结点的引用添加到集合中去。若是在集合中找到了一样的结点,那么说明这个结点已经被访问过了,因而就造成了环。这种方法的时间复杂度为O(n),空间复杂度也为O(n)。node
定义两个指针fast(快)与slow(慢),两者的初始值都指向链表头,指针slow每次前进一步,指针fast每次前进两步,两个指针同时向前移动,快指针每移动一次都要跟慢指针比较,若是快指针等于慢指针,就证实这个链表是带环的链表。app
若是单链表有环,那么按照上述方法二的思路,当走得快的指针fast与走得慢的指针slow相遇时,slow 指针确定没有遍历完链表,而fast指针己经在环内循环了n圈 (n>=1)。若是slow 指针走了s步,则fast指针走了2s步,fast步数还等于s加上在环上多转的n圈,假设环长为r,则知足以下关系表达式:
2s = s +or
由此能够获得 : s=nr
设整个链表长为L,入口环与相遇点距离为x,起点到环入口点的距离为a。则知足以下关系表达式:
a+x=nr
a+x=(n-1)r+r=(n-l)r+L-a
a=(n-l)r+(L-ax)
(L-a-x)为相遇点到环入口点的距离,从链表头到环入口点的距离=(n-l)*环长+相遇点到环入口 点的长度,因而从链表头与相遇点分别设一个指针,每次各走一步,两个指针一定相遇,且相遇第一点为环入口点。将相遇点指针的前一个节点的next域设成None便可解环。oop
# -*-coding:utf-8-*- """ @Author : 图南 @Software: PyCharm @Time : 2019/9/6 15:28 """ class Node: def __init__(self, data=None, next=None): self.data = data self.next = next # 构造单链表 def con_link(s, k): head = Node() cur = head nums = list(map(int, s.split(' '))) k = int(k) for num in nums: node = Node(num) cur.next = node cur = node tmp = head if k != 0: for i in range(k): tmp = tmp.next cur.next = tmp return head # 打印单链表(用到方法一中的思想) def print_link(head): if head is None or head.next is None: return None flag = [] cur = head.next while cur: if cur not in flag: flag.append(cur) print(cur.data, end=' ') cur = cur.next else: print(cur.data, end=' ') break print() # 判断链表中是否有环 def isLoop(head): if head is None or head.next is None: return None fast = head.next slow = head.next while True: try: fast = fast.next.next slow = slow.next except Exception: print("该链表中没有环!") print_link(head) return False, head if fast == slow: print("该链表中有环!") print_link(head) return True, fast # 查找环的入点口,并解环 def findLoopNode(head, fast): cur = head.next pre = None while cur != fast: pre = fast cur = cur.next fast = fast.next print(cur.data) # 解环并打印链表 pre.next = None print_link(head) if __name__ == '__main__': nums = input('链表:') # 输入环的入口点,若为0则链表中无环 k = input('环的入点口:') head = con_link(nums, k) f, fast = isLoop(head) if f: findLoopNode(head, fast)
带环单链表
无环单链表
3d