python链表 —— 检测一个较大的单链表是否有环

题目描述

单链表有环是指单链表中某个节点的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

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值