#节点类
classNode(object):def __init__(self,item):
self._item=item
self._next=None#单向循环链表
classSinCycLinkedList(object):def __init__(self):
self._head=None#判断链表是否为空
@propertydef is_empty(self)->bool:return self._head isNone#求链表的长度
@propertydef length(self)->int:ifself.is_empty:return0
count= 1cur=self._head#注意循环的条件
while cur._next !=self._head:
count+= 1cur=cur._nextreturncount#遍历链表
deftravel(self):ifself.is_empty:return
#第一个节点单独处理
cur =self._headprint(cur._item)#注意循环的条件
while cur._next !=self._head:
cur=cur._nextprint(cur._item)print("SinCycLinkedList has been traveled!")#头部添加节点
defadd(self,item):#实例化一个Node对象
node =Node(item)ifself.is_empty:#循环单向链表尾节点指向头节点
self._head =node
node._next=self._headelse:#先将添加的节点指向_head
node._next =self._head#移动到链表的尾部,将尾部的节点的_next指向node
cur =self._headwhile cur._next !=self._head:
cur=cur._next
cur._next=node#_head指向新添加的node
self._head =node#尾部添加节点
defappend(self,item):
node=Node(item)#空链表情况
ifself.is_empty:
self._head=node
node._next=self._headelse:#先移动到链表的尾部
cur =self._headwhile cur._next !=self._head:
cur=cur._next#将尾节点指向node
cur._next =node#将node指向头节点_head
node._next =self._head#指定位置添加节点
definsert(self,pos,item):#首部添加
if pos <=0:
self.add(item)#尾部添加
elif pos >=self.length:
self.append(item)#指定位置添加
else:
node=Node(item)
cur=self._head
count=0#先移动到指定位置的前一个节点,注意这里与pos-1比较!
while count < (pos-1):
count+= 1cur=cur._next#先将node的下一个节点设置为cur的_next,然后再将cur的_next设置为node,注意顺序不能反!
node._next =cur._next
cur._next=node#删除一个节点
defremove(self,item):#若链表为空则直接返回None
ifself.is_empty:return
#先将cur指向头节点
cur =self._head
pre=None#若头节点的元素正好是要查找的元素
if cur._item ==item:#若链表不止有一个节点
if cur._next !=self._head:#先找到尾节点,将尾节点的_next指向第二个节点
while cur._next !=self._head:
cur=cur._next#注意cur现在就是尾节点,并且最后需要将self._head指向第二个节点!
cur._next =self._head._next
self._head=self._head._next#链表只有一个节点直接让_head指向None
else:
self._head=Noneelse:
pre=self._head#注意不删除第一个节点!
while cur._next !=self._head:#找到了要删除的元素
if cur._item ==item:
pre._next=cur._nextreturn
#否则pre与cur往前挪动位置
pre =cur
cur=cur._next#临界情况:while循环结束还没找到的话,此时cur就是尾节点,需要单独处理
if cur._item ==item:#尾部删除,让尾节点的上一个节点pre的_next指向头节点即可
pre._next =cur._next#查找节点是否存在
def search(self,item)->bool:#空链表直接返回False
ifself.is_empty:returnFalse
cur=self._head#如果头节点正好是要找的元素
if cur._item ==item:returnTrue#否则遍历链表
while cur._next !=self._head:#先移动再比较!
cur =cur._nextif cur._item ==item:returnTrue#遍历完后还没找到就返回False
returnFalseif __name__ == '__main__':
lst=SinCycLinkedList()print(f"lst is empty? <{lst.is_empty}>")
lst.add(1)
lst.add(2)
lst.travel()
lst.append(33)
lst.append(44)
lst.travel()
lst.insert(2,"OK")
lst.travel()print(f"lst's length is {lst.length}")
lst.remove(44)
lst.travel()print(f"lst is empty? <{lst.is_empty}>")print(f"Does OK in lst? <{lst.search('OK')}>")print(f"Does 666 in lst? <{lst.search('666')}>")