链表有环与链表相交判断的 Python 实现
目录
判断链表是否有环可以参考链接,
有环链表主要包括以下几个问题(C语言描述):
- 判断环是否存在: 可以使用追赶方法,定义两个指针slow和fast,分别以1步和2步前进,若存在环则两者会相遇,否则fast遇到NULL时则退出;
- 获取环的长度:若存在环,则以相遇点为起点,fast和slow再次开始前进,第二次碰相遇slow走过的步数(1圈)即为环长度;
- 找出入环点:相遇点到连接点的距离 = 头指针到连接点的距离,因此,让头指针和slow同时开始前进,相遇的点即为连接点;
- 带环链表长度:问题3的连接点与头指针长度 + 问题2的环长度即为总长。
下面为关于有环链表几个问题的具体实现代码,
完整代码
1 from linked_list import LinkedList 2 3 4 def check_loop(chain): 5 has_loop, entry_node, loop_length, chain_length = False, None, 0, 0 6 7 # Get header for fast and slow 8 step = 0 9 fast = slow = head = chain.header 10 while fast and fast.next: 11 fast = fast.next.next 12 slow = slow.next 13 step += 1 14 # Note: 15 # Do remember to use ,is' rather than '==' here (assure the id is same). 16 if fast is slow: 17 break 18 has_loop = not(fast is None or fast.next is None) 19 pass_length = (step * 2) if fast is None else (step * 2 + 1) 20 21 if has_loop: 22 step = 0 23 while True: 24 if head is slow: 25 entry_node = slow 26 pass_length = step 27 if not entry_node: 28 head = head.next 29 fast = fast.next.next 30 slow = slow.next 31 step += 1 32 if fast is slow: 33 break 34 loop_length = step 35 36 chain_length = pass_length + loop_length 37 return has_loop, entry_node, loop_length, chain_length 38 39 40 if __name__ == '__main__': 41 print('------------ Loop check ------------------') 42 print(''' 43 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 44 ''') 45 loop_chain = LinkedList(range(10)) 46 print('Linked list has loop: %s, entry node: %s, loop length: %s, chain length: %s' % check_loop(loop_chain)) 47 48 # Create a loop for linked list. 49 print(''' 50 _____________________________ 51 | | 52 V | 53 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 54 ''') 55 node_9 = loop_chain.find(9) 56 node_3 = loop_chain.find(3) 57 node_9.next = node_3 58 print('Linked list has loop: %s, entry node: %s, loop length: %s, chain length: %s' % check_loop(loop_chain))