单链表是单向的,缺点是remove删除是 o(n)。
双链表: 每个链有三个元素:指向前面的指针,值,指向后面的指针。
data: maxsize, root, length
method: headnode, tailnode ,append, appendleft, remove(O(1)),iter_node, iter_node_reverse(反向遍历)
class Node(object):
def __init__(self, value=None, prev=None, next=None):
self.value, self.prev, self.next = value, prev, next
class CircleDoubleLinedList(object):
def __init__(self, maxsize=None):
self.maxsize = maxsize
node = Node()
node.next, node.prev = node, node # 开始头节点和尾节点都指向node
self.root = node # root节点不计入长度
self.length = 0
def __len__(self):
return self.length
def headnode(self):
return self.root.next
def tailnode(self):
return self.root.prev
def append(self, value):
if self.maxsize is not None and len(self) > self.maxsize:
raise Exception("full")
node = Node(value=value)
tailnode = self.tailnode()
tailnode.next = node
node.prev = tailnode
node.next = self.root # 注意这里是根节点,不是头节点
self.root.prev = node
self.length += 1
def appendleft(self, value):
if self.maxsize is not None and len(self) > self.maxsize:
raise Exception("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 = node
else:
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,不是值
if node is self.root:
return
else:
node.prev.next = node.next
node.next.prev = node.prev
self.length -= 1
return node
def iter_node(self):
"""遍历"""
if self.root.next is self.root:
return
curnode = self.root.next
while curnode.next is not self.root:
yield curnode
curnode = curnode.next
yield curnode
def __iter__(self):
for node in self.iter_node():
yield node.value
def iter_node_reverse(self):
if self.root.prev is self.root:
return
curnode = self.root.prev
while curnode.prev is not self.root:
yield curnode
curnode = curnode.prev
yield curnode
def test_double_link_list():
dll = CircleDoubleLinedList()
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]