Python链表之单向循环链表
单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。
class Node(object): """单链表的节点""" def __init__(self, item): # elem存放数据元素 self.elem = item # next是下一个节点的标识 self.next = None class SingleCycleList(object): """单向循环链表""" def __init__(self): # 初始化一个空链表 self._head = None def is_empty(self): """判断链表是否为空""" return self._head is None def length(self): """链表长度""" # 如果链表为空,返回长度0 if self.is_empty(): return 0 # 如果不为空,则开始下面的步骤 cur = self._head # count记录数量 count = 1 while cur.next is not self._head: # 因为时单向循环链表,初始_head指向的是头节点,如果只有一个节点,则该节点的next会指向该节点,所以按照while循环的条件,count从1开始 count += 1 cur = cur.next return count def travel(self): """遍历链表""" # 如果链表为空,直接返回 if self.is_empty(): return # cur游标,用来移动遍历节点 cur = self._head while cur.next is not self._head: # _head指向的是头节点,如果最后一个节点的next指向_head,则表示cur指向的是尾节点 print(cur.item, end=" ") cur = cur.next # 退出循环时,cur指向尾节点,但是尾节点的元素未打印 print(cur.item) def add(self, item): """头部添加元素,头插法""" node = Node(item) # 如果链表为空 if self.is_empty(): # _head指向需要插入的节点,该节点的next指向该节点 self._head = node node.next = node # 链表不为空 else: cur = self._head while cur.next is not self._head: cur = cur.next # 退出循环时,cur指向尾节点 node.next = self._head # 需要插入的node节点指向_head指向的节点,即头节点 self._head = node # _head指向需要插入的node节点 cur.next = node # 尾节点的next指向现在的头节点,即node节点 def append(self, item): """尾部添加元素,尾插法""" node = Node(item) # 如果链表为空 if self.is_empty(): self._head = node node.next = node else: # cur游标,用来移动遍历节点 cur = self._head while cur.next is not self._head: cur = cur.next # 退出循环,cur指向尾节点,node的next指向cur的next,即node的next指向头节点;cur的next指向node,即node此时为尾节点了 node.next = cur.next cur.next = node def insert(self, pos, item): """指定位置添加元素 :param pos:从0开始 :param item:需要插入的元素 """ if pos <= 0: self.add(item) elif pos > self.length() - 1: self.append(item) else: pre = self._head count = 0 while count < (pos - 1): count += 1 pre = pre.next # 当循环退出后,pre指向pos-1位置 node = Node(item) node.next = pre.next pre.next = node def remove(self, item): """删除节点""" # 若链表为空,则直接返回 if self.is_empty(): return # 将cur指向头节点 cur = self._head pre = None # 进入while则表示链表不止1个节点 while cur.next is not self._head: if cur.item == item: # 先判断此节点是否是头节点 if cur == self._head: # 头节点的情况,需要先找尾节点 rear = self._head while rear.next is not self._head: rear = rear.next # 退出循环,rear指向尾节点 self._head = cur.next # _head指向cur的下一个,即第二个节点 rear.next = self._head # 尾节点的next指向新的头节点 else: # 中间节点 pre.next = cur.next return else: pre = cur cur = cur.next # 退出while时,cur指向的是尾节点,没有进行处理 if cur.item == item: if cur == self._head: # 链表只有一个节点 self._head = None else: pre.next = self._head # 等同于pre.next = cur.next,让cur的前一个节点指向头节点,完成尾节点的删除 def search(self, item): """链表查找节点是否存在,并返回True或者False""" if self.is_empty(): return False cur = self._head while cur.next is not self._head: if cur.item == item: return True else: cur = cur.next # 退出循环时,cur指向尾节点,还需要判断一下cur是否是item if cur.item == item: return True return False if __name__ == "__main__": ll = SingleCycleList() print(ll.is_empty()) print(ll.length()) ll.add(1) print(ll.is_empty()) print(ll.length()) ll.append(2) ll.append(3) ll.append(4) ll.travel() ll.remove(1) ll.travel() ll.remove(4) ll.travel() ll.insert(-1, 1) ll.travel() ll.insert(6, 4) ll.travel() res = ll.search(1) print(res)