单向循环链表
单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。
操作
- is_empty() 链表是否为空
- length() 链表长度
- travel() 遍历整个链表
- add(item) 链表头部添加元素
- append(item) 链表尾部添加元素
- insert(pos, item) 指定位置添加元素
- remove(item) 删除节点
- search(item) 查找节点是否存在
实现
class SingleNode(object):
"""节点"""
def __init__(self, item):
self.item = item
self.next = None
class SinCycLinkList(object):
"""单向循环链表"""
def __init__(self):
# head存放单向循环链表首节点地址
self.head = None
def is_empty(self):
"""判断链表是否为空"""
return self.head == None
def length(self):
"""计算链表长度"""
cur = self.head
count = 1 # 计数从1开始
while cur.next != self.head:
cur = cur.next
count += 1
return count
def travel(self):
"""遍历链表"""
cur = self.head
while cur.next != self.head:
print(cur.item)
cur = cur.next
print(cur.item)
def add(self,item):
"""头部插入元素"""
# 先新建一个节点
node = SingleNode(item)
# 先判断链表是否为空
if self.is_empty():
self.head = node
node.next = self.head
else:
node.next = self.head
cur = self.head
# 找到尾部节点,尾节点指向首节点
while cur.next != self.head:
cur = cur.next
cur.next = node
self.head = node
def append(self,item):
"""尾部插入元素"""
# 新建节点
node = SingleNode(item)
# 先判断链表是否为空
if self.is_empty():
self.head = node
node.next = self.head
# 若不为空,则找到尾部,将尾节点的next指向新节点,且新节点指向首节点
else:
cur = self.head
while cur.next != self.head:
cur = cur.next
cur.next = node
node.next = self.head
def insert(self, pos, item):
"""在指定位置添加元素"""
# 在头部插入
if pos <=0:
self.add(item)
# 在尾部插入
elif pos >= self.length():
self.append(item)
# 在中间插入
else:
# pre用来指向指定位置pos的前一个位置pos-1,初始从头节点开始移动到指定位置
pre = self.head
count = 0
node = SingleNode(item)
while count < pos-1:
pre = pre.next
count += 1
# 先将新节点node的next指向插入位置的节点
node.next = pre.next
# 将插入位置的前一个节点的next指向新节点
pre.next = node
def remove(self,item):
"""删除节点"""
cur = self.head
pre = None
# 若首节点就找到
if cur.item == item:
# 如果链表不止一个节点,即首节点的next指向的不是首节点
if cur.next != self.head:
# 先找到尾节点,把尾节点的next指向首节点的next,且新首节点为第二个节点
while cur.next != self.head:
cur = cur.next
cur.next = self.head.next
self.head = self.head.next
else:
# 如果链表只有一个节点
self.head = None
else:
while cur.next != self.head:
if cur.item != item:
pre = cur
cur = cur.next
else:
pre.next = cur.next
break
def search(self,item):
cur = self.head
if cur.item == item:
return True
while cur.next != self.head:
cur = cur.next
if cur.item == item:
return True
return False
if __name__ == "__main__":
ll = SinCycLinkList()
ll.add(1)
ll.add(2)
ll.append(3)
ll.insert(2, 4)
ll.insert(4, 5)
ll.insert(0, 6)
print("length:",ll.length())
ll.travel()
print(ll.search(3))
print(ll.search(7))
ll.remove(1)
print("length:",ll.length())
ll.travel()
length: 6
6
2
1
4
3
5
True
False
length: 5
6
2
4
3
5