# 实现双向循环链表
# 头指向尾, 尾指向头
# 特点是不用特意用循环去找到尾结点 用 self.__head.pre 可以表示尾结点
class Node(object):
def __init__(self, item):
self.elem = item
self.prev = None
self.next = None
class DounleCycleLinklist(object):
def __init__(self, node=None):
self.__head = node
if node:
node.next = self.__head
def is_empty(self):
return self.__head is None
def length(self):
if self.is_empty():
return 0
else:
cur = self.__head
cnt = 1
while cur.next is not self.__head:
cnt += 1
cur = cur.next
return cnt
def travel(self):
if self.is_empty():
return
else:
cur = self.__head
while cur.next is not self.__head:
print(cur.elem, end=' ')
cur = cur.next
print(cur.elem)
def add(self, item):
node = Node(item)
if self.is_empty():
# 如果是空链表,将_head指向node
self.__head = node
# 将node的next指向_head的头节点
node.next = self.__head
# node.prev = self._head
self.__head.prev = node
else:
# 尾结点为 self._head.prev
# 尾结点next指向node
self.__head.prev.next = node
# node的prev指向尾结点
node.prev = self.__head.prev
# 将node的next指向头节点self._head
node.next = self.__head
# 头结点的prev指向node
self.__head.prev = node
# 头指针指向node
self.__head = node
def append(self, item):
"""尾部添加元素"""
node = Node(item)
if self.is_empty():
# 如果是空链表,将_head指向node
self.__head = node
else:
# 尾部节点为self._head.prev
# 尾结点的next指向node
self.__head.prev.next = node
# node的prev指向尾结点
node.prev = self.__head.prev
# 将node的next指向头节点self._head
node.next = self.__head
# 头指针指向node
self.__head.prev = node
def insert(self, pos, item):
node = Node(item)
if pos <= 0:
self.add(item)
elif pos > (self.length() - 1):
self.append(item)
else:
cur = self.__head
cnt = 1
while cnt is not pos:
cnt += 1
cur = cur.next
# 循环结束后 cur 指向 pos-1
node.prev = cur
node.next = cur.next
cur.next.prev = node
cur.next = node
def remove(self, item):
"""删除一个节点"""
# 若链表为空,则直接返回
if self.is_empty():
return 0
# 将cur指向头节点
cur = self.__head
# 若头节点的元素就是要查找的元素item
if cur.elem == item:
# 如果链表不止一个节点
if cur.next != self.__head:
# 尾节点为self._head.prev
# 尾节点的next指向self._head.next
self.__head.prev.next = self.__head.next
# self._head.next为新头节点,其prev指向尾结点
self.__head.next.prev = self.__head.prev
# 头指针指向新节点
self.__head = self.__head.next
else:
# 链表只有一个节点
self.__head = None
else:
pre = self.__head
# 第一个节点不是要删除的
while cur.next is not self.__head:
# 找到了要删除的元素
if cur.elem == item:
# 删除
cur.prev.next = cur.next
cur.next.prev = cur.prev
return
else:
cur = cur.next
# cur 指向尾节点
if cur.elem == item:
# 尾部删除
self.__head.prev = cur.prev
cur.prev.next = self.__head
def search(self, item):
if self.is_empty():
return False
cur = self.__head
res = False
while cur.next is not self.__head :
if cur.elem == item:
res = True
break
else:
cur = cur.next
# 退出循环时 cur 指向尾结点, 但是没有经过判断
if cur.elem == item:
# 判断尾结点是否对应 item
res = True
return res
if __name__ == '__main__':
dcll = DounleCycleLinklist()
print(dcll.is_empty())
print(dcll.length())
dcll.append(3)
dcll.append(4)
dcll.travel()
dcll.add(2)
dcll.add(1)
dcll.add(0)
dcll.append(4)
dcll.append(5)
dcll.travel()
dcll.insert(-1, -1)
dcll.insert(100, 7)
dcll.travel()
print(dcll.length())
dcll.insert(8, 6)
dcll.travel()
dcll.remove(7)
dcll.travel()
dcll.remove(-1)
dcll.travel()
dcll.insert(3, 3)
dcll.remove(3)
dcll.remove(4)
dcll.travel()
print(dcll.search(2))
print(dcll.search(-1))
print(dcll.search(0))
print(dcll.search(6))
python 线性表——双向循环链表
最新推荐文章于 2022-11-22 14:40:31 发布