# -*- coding:utf-8 -*-
"""
每一个结点包含prev, value , next。 prev指向上一个结点。 root根节点作为接口。根节点的下一个结点是head结点。尾结点尾tail,tail.next=root, root.prev = tail所以说这是一个双端循环结点
"""
class Node(object):
def __init__(self, prev = None, value = None, next = None):
self.value = value
self.next = next
self.prev = prev
class CircualDoubleLinedList(object):
def __init__(self, maxsize=None):
self.maxsize = maxsize
node = Node()
node.next, node.prev = node, node
self.root = node # 根结点默认是自己指向自己的
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): # 加入到尾结点的后面。 该结点的下一结点是root, 上一结点是尾结点tailnode
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: # 此时双端链表为空 除了根结点外只有一个结点
self.root.next = node
self.root.prev = node
node.next = self.root
node.prev = self.root
else:
head = self.root.next
self.root.next = node
node.prev = self.root
node.next = head
head.prev = node
self.length += 1
def remove(self, node): # 这里传入的node, 不是value
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 # yield 尾结点
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 # tailnode
while curnode.prev is not self.root:
yield curnode
curnode = curnode.prev
yield curnode
def insert(self, value, new_value): # 插入替换方法
for node in self.iter_node():
if node.value == value:
node.value = new_value
def test_double_link_lis():
dll = CircualDoubleLinedList()
assert len(dll) == 0
dll.append(0)
dll.append(1)
dll.append(2)
assert len(dll) == 3
assert list(dll) == [0, 1, 2] # 会调用iter方法
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 len(dll) == 3
assert [node.value for node in dll.iter_node()] == [0,1,2]
dll.insert(0,3)
assert [node.value for node in dll.iter_node()] == [3,1,2]