用途一:查找链表中间节点
示例:
head->1->2->3->4->5->6->7->None
结果:中间节点为4
方法:
定义两个指针,一个快指针,一个慢指针,当快指针遍历到尾节点的时候,慢指针刚好遍历到中间的节点。
当节点个数为奇数时,中间节点只有一个,当节点个数为偶数时,慢指针指向的节点和它的后继都是中间节点。
这种办法时间只需要遍历一次,且未开辟新空间,因此时间复杂度为O(n),空间复杂度为O(1)。
代码:
“”“”“”
class LNode():
def __init__(self,x=None):
self.data = x
self.next = None
head = Lnode() #默认head的结构为节点
“”“”“”
def FindMiddleNode(head):
if head == None or head.next == None:
return head
fast = head #快指针
slow = None #慢指针
slowPre = head #slowPre 用来标记中间节点的第一个节点
while fast != None or fast.next != None:
slow.pre = slow
slow = slow.next #slow一次前进一个单位
fast = fast.next.next #fast一次前进两个单位
slowPre.next = None #从中间节点的前面断开成两个链表
return slow #返回链表的第一个元素(断开的链表没有头)
用途二:找到链表的倒数第个节点
方法:
与上面一样,不过这里的移动方式要变一下,之前快慢指针同时起步,slow= slow.next ;fast = fast.next.next,这样做,快指针比慢指针整整快了一倍。
想要找倒数第k个节点,可以让快指针先行k步,然后两个指针一起往后走,当快指针到达尾节点的时候,慢指针指向的就是前k个节点。
示例:
head->1->2->3->4->5->6->7->None
k= 2(倒数第2个节点)
结果: 倒数第2个节点为6
代码:
def FindLastK(head , k):
if head == None or head.next == None:
return head #确保链表不为空
slow = LNode() 定义两个指针
fast = LNode()
slow = head.next #两个指针的起始位置都为第一个节点
fast = head.next
i = 0
while(i<k and fast != None): #快指针先向前走K步
fast = fast.next
i+=1
if i<k: #判断k是否超出链表长度
return None
while fast != None: #只要fast不到尾,就一直走
slow = slow.next #两个指针行进速度一样
fast = fast.next
return slow
用途三:检测单链表是否有环,返回环的入口。
方法:
(一)检测单链表是否有环:
定义两个指针,一个快一个慢,两个指针刚开始时都指向链表的头节点,之后快指针每次前进两步,慢指针每次前进一步,如果他们相遇了(fast= low),说明快指针已经转了一圈回来了,也就说明链表有环。
(二)返回环的入口:
同样定义两个指针,一个指向头节点,另一个指向相遇点,两个指针同时向后走,他们的第一次相遇点就是环的入口。
分析:
就类似于在操场的跑道上跑步,两个人,快的人的速度是慢的人的两倍,跑的快的人,在第二圈会再次与跑的慢的人相遇。
代码:
class LNode(): #定义链表节点
def __init__(self,x=None):
self.data = x
self.next = None
(一)检测单链表是否有环:
def isLoop(head):
if head == None or head.next == None:
return None
fast = head
slow = head #刚开始都指向头 或者都指向head.next都可以
while fast !=None and fast.next !=None:
slow = slow.next #快慢指针前进速度
fast = fast.next.next
if slow == fast:
return slow
else:
return None
(二)返回环的入口:
def findLoopNode(head,meetNode):
first = head
second = meetNode
while first != second:
first = first.next
second = second.next
return first