找到单链表中间位置的结点,如果单链表的长度是偶数,则取中间两个的前一个,单链表是没有序号的,所以要么通过计数,要么通过移动解决该问题。
有两种方法,计数法和快慢指针法。
代码及解析如下:
#找到单链表中间位置的结点,如果单链表的长度是偶数,则取中间两个的前一个
#单链表是没有序号的,所以要么通过计数,要么通过移动解决该问题
def Middle1(L):#计数法
#计数的意思就是用一个新的变量来标记单链表的序号,然后通过序号与单链表的长度之间的数字关系来求得中间结点
j=1
n=L.getsize()#获得单链表长度
p=L.head.next#指针p指向首结点
while j<=(n-1)//2:#当j>(n-1)//2且j为整数时说明找到了中间结点,j<=(n-1)//2代表没找到,说明序号要+1,指针要后移一位
#n-1然后向下取证的方法解决了奇偶长度的问题
j+=1
p=p.next
return p.data
#算法的时间复杂度O(n)
def Middle2(L):#快慢指针法
#原理:两个指针分别从原点出发,fast速度始终是slow速度的2倍,则0与fast的中间点一定是slow
slow=L.head.next#先将slow和fast指针都放在首结点
fast=L.head.next#先将slow和fast指针都放在首结点
#注:L.head.next是首结点
#思考:这代码如何解决链表奇偶长度的问题?
while fast!=None and fast.next!=None and fast.next.next!=None:
#第一个判断是为了判断fast是否到达了单链表尾端
#若单链表的长度为奇数,到达尾端正好触发了fast.next=None的条件
#若单链表的长度为偶数,到达尾端-1位置正好触发了fast.next.next=None的条件,这样正好slow仍然是中间两个数前面的位置
slow=slow.next#slow一次移动1个单位
fast=fast.next.next#slow一次移动2个单位
return slow.data
#算法的时间复杂度O(n)
#两个算法比起来,第一个算法遍历了整个长度1.5遍,所以第二个效率更高