class Node:
"""实现单向节点的类"""
# value值,next下一个节点的地址
def __init__(self, value=None, next=None, prev=None):
# 存放值的实例属性
self.value = value
# 下一个节点的“引用”,
self.next = next
# 上一个节点的“引用”
self.prev = prev
# print(obj) # -> obj.__str__()
# str(obj) # obj.__str__()
def __str__(self):
return "{}".format(self.value)
# 1.python终端中执行时输出的结果。
# 2.将对象存入对象中时,显示的结果。
def __repr__(self):
return str(self.value)
# node1 > node2 == node1.__gt__(node2)
def __gt__(self, other):
return self.value > other.value
def __lt__(self, other):
return self.value < other.value
def __eq__(self, other):
return self.value == other.value
def __ne__(self, other):
return self.value != other.value
def __add__(self, other):
return Node(value=(self.value + other.value))
class DoubleLinkedList:
"""双向链表类"""
def __init__(self, data=None):
self.head = None
self.tail = None
self.size = 0
self.temp = False
if data is not None:
for i in data:
self.append(i)
def append(self, value) -> None:
# 节点对象
node = Node(value)
if self.head is None:
self.head = self.tail = node
else:
# 让原来的尾部next-> node
self.tail.next = node
# 新节点的前一个元素是原来尾部
node.prev = self.tail
# 将添加的节点变成尾部
self.tail = node
self.size += 1
def get_items(self, revers: bool = False) -> Node:
"""按顺序输出输出所有节点"""
temp = self.tail if revers else self.head
while temp is not None:
yield temp
temp = temp.prev if revers else temp.next
def revers(self):
return self.get_items(revers=True)
def pop(self) -> Node:
"""弹出最后一个元素"""
# 0.将元素的数量减1
self.size -= 1
# 1.获取最后一个元素
tail = self.tail
# 当最后一个元素的上一个元素是空时,它就是最后一个元素
# self.tail is self.head
if tail.prev is None:
self.head = self.tail = None
return tail
# 2.将最后一个元素改为倒数第二个元素
self.tail = self.tail.prev
# 3.将现在最后一个元素的下一个元素为空
self.tail.next = None
return tail
def get_value(self, index: int):
"""通过下标获取链表元素中的值"""
# 获取数据生成器
if index < 0:
data = self.get_items(revers=True)
index = abs(index) - 1
else:
data = self.get_items()
for i, node in enumerate(data):
if i == index:
return node
def index(self, value) -> int:
"""通过值找到元素的下标"""
data = self.get_items()
for index, node in enumerate(data):
if node.value == value:
return index
else:
return -1
def insert(self, index, value) -> None:
"""任意位置插入一个值"""
# 1.通过下标找到原节点
old_node = self.get_value(index)
# 2.如果原节点为空,则追加新节点
if old_node is None:
# 在尾部添加新节点
self.append(value)
return None
# 3.如果原节点的上一个值为None,我们就把新节点变成头节点
prev = old_node.prev
new_node = Node(value=value, next=old_node, prev=prev)
# 原节点上一个节点设置为新节点
old_node.prev = new_node
if prev is None or index == 0:
# 头部添加新节点,将新节点设置为头部
self.head = new_node
else:
# 原节点的上一个节点的下一个节点指向新节点
prev.next = new_node
self.size += 1
def remove(self, value) -> None:
"""删除值"""
temp = None
for i, node in enumerate(self.get_items()):
if node.value == value:
temp = node
break
if temp is None:
raise ValueError("找不到要删除的数据。")
prev = temp.prev
next = temp.next
if prev is None and next is None:
self.head = self.tail = None
elif prev is None:
# 删除头节点
# 这个节点的下一个节点向上执行空
next.prev = None
self.head = next
elif next is None:
# 删除结尾
# 让它的前一个元素next值向空
prev.next = None
self.tail = prev
else:
# 删除中间的任意值
next.prev = prev
prev.next = next
self.size -= 1
del temp
def clear(self) -> None:
"""清空链表"""
for _ in range(self.size):
temp = self.pop()
del temp
self.head = self.tail = None
def update(self, index, value):
"""修改数据"""
if index >= self.size or (abs(index) - 1) >= self.size:
raise IndexError("超出范围!")
data = self.get_value(index)
data.value = value
def extend(self, other):
self.tail.next = other.head
other.tail.prev = self.tail
self.tail = other.tail
self.size += other.size
# 在判断时,没有__bool__方法时会执行__len__
def __len__(self):
"""当len(obj)时被执行"""
return self.size
def __iter__(self):
return self
def __next__(self):
if self.temp is False:
self.temp = self.head
elif self.temp is None:
self.temp = False
raise StopIteration
t, self.temp = self.temp, self.temp.next
return t.value
def __reversed__(self):
"""执行reversed(obj)时执行"""
return self.get_items(revers=True)
def __str__(self):
return "[" + ",".join(map(str, self.get_items())) + "]"
def __repr__(self):
return self.__str__()
def __add__(self, other):
new = self.__copy__()
new.tail.next = other.head
other.head.prev = new.tail.next
new.size += other.size
return new
def __copy__(self):
new = DoubleLinkedList()
for i in self:
new.append(i)
return new
def __mul__(self, other):
data = self
for i in range(other - 1):
data = data + self
return data
def __getitem__(self, item):
"""使用[index]执行取值"""
data = self.get_value(item)
if data:
return data
raise StopIteration
def __setitem__(self, key, value):
self.update(key, value)
def __delitem__(self, key):
data = self.get_value(key)
self.remove(data.value)
del data
# in 当进行成员运算时执行 obj.__contains__
def __contains__(self, item):
data = self.get_value(item)
if data is not None:
return True
else:
return False
# 当被判断或bool()时调用
def __bool__(self):
return self.size > 0
if __name__ == '__main__':
ddl = DoubleLinkedList([1])
# print(bool(ddl))
# for i in ddl:
# print(i)
# print(11 in ddl)
# print(ddl)
# ddl.append("a")
if ddl:
print("True")
else:
print("False")
链表的增删改插
最新推荐文章于 2020-05-28 14:04:05 发布