循环列表
实现一个循环链表
- is_empty() 链表是否为空
- length() 链表长度
- travel() 遍历整个链表
- append(item) 链表尾部添加元素
- add(item) 链表头部添加元素
- insert(pos, item) 指定位置添加元素
- search(item) 查找节点是否存在
- remove(item) 节点删除
先实现一个节点
class CircleNode(object):
# 循环链表节点
def __init__(self, item):
# 用来存储数据
self.item = item
# 存储下一个节点数据的地址
self.next = None
循环链表的实现
因为跟单链表有很多相似的地方,所以先附上代码,后面加入分析过程
class CircleNode(object):
# 循环链表节点
def __init__(self, item):
# 用来存储数据
self.item = item
# 存储下一个节点数据的地址
self.next = None
class CircleLinkList(object):
def __init__(self, node = None):
# 空链表self._head = None
# 非空,1个节点,自己指向自己
self._head = node
if node:
node.next = node
def is_empty(self):
# 判断列表是否为空
return self._head == None
def length(self):
'''链表的长度'''
if self._head == None:
return 0
cur = self._head
# 如果count = 0最后一个节点不会被计入,也可以采用返回值+1的方式
count = 1
while cur.next != self._head:
count += 1
cur = cur.next
return count
def travel(self):
'''遍历链表'''
if self.is_empty():
return None
cur = self._head
while cur.next != self._head:
print(cur.item, end=' ')
cur = cur.next
print(cur.item)
print(' ')
def append(self, item):
'''尾部添加'''
node = CircleNode(item)
if self.is_empty():
self._head = node
node.next = node
else:
cur = self._head
while cur.next != self._head:
cur = cur.next
cur.next = node
node.next = self._head
def add(self, item):
'''头部添加'''
node = CircleNode(item)
if self.is_empty():
self._head = node
node.next = node
cur = self._head
while cur.next != self._head:
cur = cur.next
cur.next = node
node.next = self._head
self._head = node
def insert(self, pos, item):
'''指定位置添加元素'''
node = CircleNode(item)
if pos < 0:
self.add(item)
elif pos > self.length():
self.append(item)
else:
cur = self._head
count = 0
while count < (pos - 1):
cur = cur.next
count += 1
node.next = cur.next
cur.next = node
def search(self, item):
'''查询某个值在链表中是否存在'''
if self.is_empty():
return None
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
def remove(self, item):
'''删除节点'''
if self.is_empty():
return None
cur = self._head
pre = None
# 如果要删除的是第一个节点
if cur.item == item:
# 循环链表中不只一个节点
if cur.next != self._head:
while cur.next != self._head:
cur = cur.next
cur.next = self._head.next
self._head = cur.next
# 循环链表中只有一个节点
else:
self._head = None
# 删除中间或尾部节点
else:
while cur.next != self._head:
if cur.item == item:
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
if cur.item == item:
pre.next = self._head
c = CircleLinkList()
print(c.is_empty())
print(c.length())
c.append(9)
# c.append(2)
# c.append(1)
c.add(6)
c.add(5)
c.add(4)
c.add(3)
c.insert(7, 200)
c.travel()
c.remove(4)
c.travel()
print(c.search(520))
is_empty()&length()&travel()
is_empty():只需关注开头,_head指向了空,它就是空链表,若非空,就不是空链表,无需关注链表有多长
length(): 引入一个游标(指针),指针往后移动一次,count就加1,注意如果count起始值为0,那返回的count需要加1。注意空列表的情况
travel(): 也需要一个游标,让游标循环,游标指向哪里就打印哪里。注意空列表的情况
append()
append(): 尾部添加,先让尾节点指向新节点,再让新节点指向头结点即可。如果是空节点,_head指向新节点,新节点指向自己。
add()
add(): 头部添加,通过循环找到最后一个节点,尾结点指向新节点,新节点指向原头结点,_head指向新节点。若是空链表,_head指向新节点,新节点指向自己。
insert()
insert():分三种情况,中间插入,头插,尾插
中间插入,如图,根据pos和count定位到要插入位置,让新节点指向后面,cur指向新节点,
尾插,与append同理
头插,与add同理。
注意空链表
search()
与便利类似
remove()
remove中间节点:通过cur和pre两个指针,cur定位到要删除的节点,pre指向cur前一个节点,pre.next直接指向cur.next,就跳过了要删除的节点,即实现删除的效果。
remove最后节点:如果一直没有找到要删除的节点,while循环后,cur停留在尾结点,需要单独判别尾结点是否是需要删除的节点,是-删除
remove头节点
头节点有分两种情况
链表长度大于1,先循环链表(因为我们需要用到最后一个节点),如果cur指向的节点与我们传入的相同,即删除第一个节点,让尾结点指向self._head.next,再让_head指向cur.next
链表长度等于1,_head直接指向None