#-*- coding: utf-8 -*-
classNode(object):__slots__ = ('value', 'prev', 'next') #save memory
def __init__(self, value=None, prev=None, next=None):
self.value, self.prev, self.next=value, prev, nextclassCircularDoubleLinkedList(object):"""循环双端链表 ADT
多了个循环其实就是把 root 的 prev 指向 tail 节点,串起来"""
def __init__(self, maxsize=None):
self.maxsize=maxsize
node=Node()
node.next, node.prev=node, node
self.root=node
self.length=0def __len__(self):returnself.lengthdefheadnode(self):returnself.root.nextdeftailnode(self):returnself.root.prevdef append(self, value): #O(1), 你发现一般不用 for 循环的就是 O(1),有限个步骤
if self.maxsize is not None and len(self) >=self.maxsize:raise Exception('LinkedList is Full')
node= Node(value=value)
tailnode= self.tailnode() orself.root
tailnode.next=node
node.prev=tailnode
node.next=self.root
self.root.prev=node
self.length+= 1
defappendleft(self, value):if self.maxsize is not None and len(self) >=self.maxsize:raise Exception('LinkedList is Full')
node= Node(value=value)if self.root.next is self.root: #empty
node.next =self.root
node.prev=self.root
self.root.next=node
self.root.prev=nodeelse:
node.prev=self.root
headnode=self.root.next
node.next=headnode
headnode.prev=node
self.root.next=node
self.length+= 1
def remove(self, node): #O(1),传入node 而不是 value 我们就能实现 O(1) 删除
"""remove
:param node # 在 lru_cache 里实际上根据key 保存了整个node:"""
if node isself.root:return
else: # node.prev.next =node.next
node.next.prev=node.prev
self.length-= 1
returnnodedefiter_node(self):if self.root.next isself.root:returncurnode=self.root.nextwhile curnode.next is notself.root:yieldcurnode
curnode=curnode.nextyieldcurnodedef __iter__(self):for node inself.iter_node():yieldnode.valuedefiter_node_reverse(self):"""相比单链表独有的反序遍历"""
if self.root.prev isself.root:returncurnode=self.root.prevwhile curnode.prev is notself.root:yieldcurnode
curnode=curnode.prevyieldcurnodedeftest_double_link_list():
dll=CircularDoubleLinkedList()assert len(dll) ==0
dll.append(0)
dll.append(1)
dll.append(2)assert list(dll) == [0, 1, 2]assert [node.value for node in dll.iter_node()] == [0, 1, 2]assert [node.value for node in dll.iter_node_reverse()] == [2, 1, 0]
headnode=dll.headnode()assert headnode.value ==0
dll.remove(headnode)assert len(dll) == 2
assert [node.value for node in dll.iter_node()] == [1, 2]
dll.appendleft(0)assert [node.value for node in dll.iter_node()] == [0, 1, 2]if __name__ == '__main__':
test_double_link_list()