单向循环链表
单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。
节点实现
class Node(object):
def __init__(self,item):
self.item = item
self.next = None
单向循环链表实现
class SinCycLinkedlist(object):
"""单向循环链表"""
def __init__(self,node = None):
"""node虽然有原始值,但可以改变"""
self._head = node
"""最开始为空列表,头节点为None,但如果输入的节点不为None,则执行以下代码"""
if node:
node.next = node
def is_empty(self):
"""是否为空"""
return self._head == None
def length(self):
"""链表长度"""
if self.is_empty():
return 0
cur = self._head
count = 1
while cur.next != self._head:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历整个列表"""
cur = self._head
while cur.next != self._head:
print(cur.item,end=' ')
cur = cur.next
"""尾节点未打印,需要手动打印"""
print(cur.item)
def add(self,item):
"""链表头部添加元素,头插法"""
node = Node(item)
if self.is_empty():
self._head = node
node.next = self._head # 这里也可以写node.next = node,因为此时self._head中寸的就是nodede地址
else:
cur = self._head
while cur.next != self._head:
cur = cur.next
node.next = self._head
self._head = node
cur.next = node
def append(self,item):
"""链表尾部添加元素,尾插法"""
node = Node(item)
if self.is_empty():
self._head = node
node.next = self._head
else:
cur = self._head
while cur.next != self._head:
cur = cur.next
cur.next = node
node.next = self._head
def insert(self,pos,item):
"""指定位置添加元素
:param pos 从0开始索引
"""
node = Node(item)
cur = self._head
if pos<=0:
self.add(item)
elif pos>(self.length()-1):
self.append(item)
# 中间插入时不涉及首尾,与不循环链表一样
else:
i = 0
while i != (pos-1):
i += 1
cur = cur.next
node.next = cur.next
cur.next = node
def remove(self,item):
"""删除结点"""
cur = self._head
pre = None
while cur.next != self._head:
if cur.item == item:
# 判断是否为头节点
if cur == self._head:
rear = self._head
while rear.next != self._head:
rear = rear.next
self._head = cur.next
rear.next = self._head
else:
# 中间节点
pre.next = cur.next
# 注意!这里不能使用break,因为break跳出循环后还会执行循环以外的代码,这里并不需要,所以使用return终止就好,循环外的内容不会执行了
return
else:
pre = cur
cur = cur.next
# 退出循环时cur正指向尾节点,所以尾节点还没判断
if cur.item == item:
# 只有一个节点
if cur == self._head:
self._head = None
else:
pre.next = cur.next
def search(self,item):
"""查找结点是否存在"""
if self.is_empty():
return False
cur = self._head
while cur.next != self._head:
if cur.item == item:
return True
else:
cur = cur.next
if cur.item == item:
return True
else:
return False
测试
if __name__ == '__main__':
s = SinCycLinkedlist()
s.add(1)
s.add(2)
s.append(7)
s.travel()
s.insert(2,9)
s.insert(0,111)
print(s.length())
s.travel()
print(s.search(9))
s.remove(2)
s.travel()
#结果为:
2 1 7
5
111 2 1 9 7
True
111 1 9 7
总结
写方法时,考虑节点在首位、尾部、中间、是否只有一个节点,是否为空链表五种情况。
在添加或者删除元素时,尽量保证链表的完整性。