# CY3761 | 2021-12-15 20:58
import types
import copy
# 链表的节点可以通过 头尾进行找下一个或者上一个
# A => prev item next
# B => prev item next
# C => prev item next
# A.next = B
# B.prev = A B.next = C
# C.prev = B
class Node:
def __init__(self, _item, **kwargs):
self.item = _item # 当前节点值
self.prev = self.next = None
if kwargs.get('prev'): # 指向上一个节点
self.prev = kwargs.get('prev')
if kwargs.get('next'): # 指向下一个节点
self.next = kwargs.get('next')
class DoubleChain:
def __init__(self):
self.head = None # 链表头
self.leng = 0 # 链表长度
pass
def isEmpty(self):
return self.leng <= 0
pass
def items(self, isItem=False):
items = []
aItem = self.head
while aItem:
items.append(aItem)
aItem = aItem.next
if isItem:
return [_.item for _ in items]
return items
def before(self, item):
# A => prev item next
# self.head = A, self.leng = 1
# B => prev item next | B, A
# self.head = B, self.leng = 2 | B.next = A, A.prev = B
# C => prev item next | C, B, A
# self.head = C, self.leng = 3 | C.next = B, B.prev = C
# ...
node = Node(item)
if self.isEmpty():
self.head = node
else:
node.next = self.head
self.head.prev = node
self.head = node
self.leng += 1
pass
def after(self, item):
# A => prev item next
# self.head = A, self.leng = 1
# B => prev item next | A, B
# self.head = A, self.leng = 2 | A.next = B, B.prev = A
# C => prev item next | A, B, C
# self.head = A, self.leng = 3 | B.next = C, C.prev = B
# ...
node = Node(item)
if self.isEmpty():
self.head = node
else:
foot = self.head
while foot.next: # 这里必须 aItem.next
foot = foot.next
foot.next = node # 原尾节点.next = 新节点
node.prev = foot # 新节点.prev = 原尾节点
pass
self.leng += 1
def where(self, pos, item): # 不需要改变
pos = int(pos)
if pos <= 0:
return self.before(item)
elif pos >= self.leng:
return self.after(item)
else:
# A, C, ...
# self.head = A, self.leng = 3
# 1 B => prev item next | A, B, C,
# A.next = B, B.prev = A, B.next = C, C.prev = B
# self.leng = 4
print('-' * 80)
print(item)
item = Node(item) # 新建节点
nItem = self.head # 后一个节点
pItem = nItem # 前一个节点
# 找插入位置的 前一个和后一个
while pos > 0:
pItem = nItem
nItem = nItem.next
pos -= 1
print(pItem, pItem.item)
print(nItem, nItem.item)
item.prev = pItem # 新节点.prev = 前一个节点
item.next = nItem # 新节点.next = 后一个节点
pItem.next = item # 前一个节点.next = 新节点
nItem.prev = item # 后一个节点.prev = 新节点
self.leng += 1
def remove(self, item):
"""
找到删除值
删除值的前一个的next = 删除值的后一个
删除值的后一个的prev = 删除值的前一个
删除值的next = 删除值的prev = None
"""
aItem = self.head
while aItem:
if aItem.item == item:
if aItem == self.head: # 是头节点
self.head = aItem.next
else:
aItem.prev.next = aItem.next
if aItem.next:
aItem.next.prev = aItem.prev
self.leng -= 1
return 0
aItem = aItem.next
return -1
pass
def update(self, pos, item):
pos = int(pos)
if 0 > pos > self.leng:
return -1
aItem = self.head
while pos > 0:
aItem = aItem.next
pos -= 1
aItem.item = item
pass
# 查找指定值的节点是否存在
def search(self, item):
aItem = self.head # A
isHas = False
while aItem:
if aItem.item == item:
isHas = True
break
aItem = aItem.next
return 1 if isHas else -1
def eachDoubleChain(args, method, methodString, chain=None):
if chain is None:
a = DoubleChain()
else:
a = chain
print('-' * 80)
print(a.leng, a.items(True))
if not isinstance(method, types.LambdaType):
raise Exception('method not is LambdaType')
for _ in args:
b = method(a, _)
print(_, b, a.leng, methodString.format(*_), a.items(True))
return a
if __name__ == '__main__':
eachDoubleChain([
'A', 'B', 'C', 'D', 'E'
], lambda a, _: a.before(_), 'a.before({})')
b = eachDoubleChain([
'A', 'B', 'C', 'D', 'E'
], lambda a, _: a.after(_), 'a.after({})')
c = eachDoubleChain([
(0, 'a'), (2, 'b'), (4, 'c'), (6, 'd'), (8, 'e')
], lambda a, _: a.where(*_), 'a.where({},{})', b)
d = copy.deepcopy(c)
eachDoubleChain([
'A', 'B', 'C', 'D', 'E'
], lambda a, _: a.remove(_), 'a.remove({})', c)
c = eachDoubleChain([
(0, '一'), (4, '二'), (1, '三'), (2, '四'), (3, '五')
], lambda a, _: a.update(*_), 'a.update({},{})', d)
eachDoubleChain([
'一', '二', '三', '四', '五'
], lambda a, _: a.search(_), 'a.search({})', c)