一、定义
单向链表中可以通过当前节点找到下一个节点,每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
# 定义节点
class Node(object): def __init__(self,num): self.num = num self.next = None def __str__(self): return self.num
class Link(): def __init__(self): #永远指向链表中第一个节点 self._head = None def isEmpty(self): return self._head is None def add(self,item): node = Node(item) node.next = self._head self._head = node def length(self): count = 0 if self.isEmpty(): return count else: cur = self._head while cur is not None: count += 1 cur = cur.next return count def travel(self): cur = self._head while cur is not None: print(cur) cur = cur.next def append(self,item): node = Node(item) cur = self._head if self.isEmpty(): self._head = node else: while cur is not None: #因为循环遍历结束后cur会指向空并非最后一个节点 pre_cur = cur cur = cur.next pre_cur.next = node def search(self,item): ex = False cur = self._head while cur is not None: if cur.item == item: ex = True break cur = cur.next return ex def insertTo(self,item,index): cur = self._head ex = 0 node = Node(item) #插入到第一个节点位置 if index <= 0: self.add(item) #插入到最后一个节点位置 elif index >= self.length(): self.append(item) else: while cur is not None: pre = cur cur = cur.next #此处插入的一定不是第一个节点和最后一个节点位置,因此index要减1 if ex == index-1: node.next = cur pre.next = node break ex += 1 def remove(self,item): pre = None cur = self._head #删除的是第一个节点 if cur.item == item: self._head = cur.next else: while cur is not None: pre = cur cur = cur.next if cur.item == item: pre.next = cur.next cur.next = None cur = cur.next
二、链表中环的问题
1、判断是否有环
有两种方法,第一种是循环判断是否相同,这里就不再说了,时间复杂度很高,O(n^2)
第二种方法就是同时开始从头部出发,一个快,一个慢,若是最后相遇,那么就是有环的
def islinkloop(self): if self._head is None: return False first = self._head second = self._head while first.next is not None and second.next is not None: first = first.next.next second = second.next if first == second: return True return False
就像下图中一样,最后总会相遇
2、找环的起点位置
之前我们让先走的点两步一次的前进,第二个一步一次的前进,那么我们设从头部到起点位置的距离是m,从起点位置到相遇位置的距离是k,环长度为n。
那么 first 一共走了 m+An+k (A为圈数,有可能好几圈才相遇),second 一共走了 m+Bn+k,由于first走的长度是second的二倍(first两步,second一步)。
这样我们就发现first一共比second多走了S = (A-B)*n 的距离,一共走了2S,是环的长度的倍数
我们让second 回到头部,first 从交汇点开始,都按照一步一次前进,当second走了m长到达起点位置,而first一共走了2S+m,这样我们可以理解为first多走了几圈之后又到达了起点位置。所以两个点相遇就代表是起点位置
def getlinkloopstart(self): if self._head is None: return None first = self._head second = self._head while first.next is not None and second.next is not None: first = first.next.next second = second.next if first == second: break if first == second: second = self._head while first != second: first = first.next second = second.next return second else: return None