##一、相比单向链表,双向链表的优势
双向链表的每个节点保存了前一个节点和后一个节点的引用(指针),到达某个节点是,可以向前或者向后遍历,提高了操作的效率。比如,insertBefore(nodeA, value) 操作,可以一步完成,而不需要先查找 nodeA 的前序节点。
newNode = ListNode(value)
nodeA.prev.next = newNode
newNode.prev = nodeA.prev
newNode.next = nodeA
nodeA.prev = newNode
##二、关于List 的遍历访问,使用迭代器。
可以把迭代器理解为指向 List 的一个游标,这个游标可以向前或者向后(一般是从前向后遍历)遍历整个 List。
如果我们的 List 想要支持迭代访问,比如 for val in listA: xxx, 就必须实现迭代器,必须要实现自己的迭代器类和迭代方法。
##三、语言描述总数太抽象,直接看代码吧。
如果发现问题或者有疑问,欢迎与我讨论。看完代码,相信你对 python 的迭代器以及可迭代对象有了新的认识。
欢迎加入我们免费的 python 学习交流社群,请先扫描群主二维码,加群主为好友,然后申请入群。群内技术大牛每日交流,即时答疑。也欢迎关注我们的技术公众号,会定期推送学习材料(简书markdown 图片尺寸好像不能调整,丑哭)。
# -*- coding: utf-8 -*-
# 定义节点类,保存数据和前后对象的引用
class ListNode():
def __init__(self,value):
self.value = value
self.next = None
self.prev = None
# 根据 python 的迭代器规范,定义一个迭代器
class ListIterator():
def __init__(self, l):
self.list = l
self.cur = l.head
def __iter__(self):
return self
# next 函数,用来返回下一个数据
def next(self):
if self.cur.next == l.tail:
# 如果迭代结束了,按照规范需要抛出 StopIteration 异常
raise StopIteration()
else:
self.cur = self.cur.next
return self.cur.value
# 定义List类,实现可迭代操作的接口
class List():
def __init__(self):
self.head = ListNode(0)
self.tail = ListNode(0)
self.head.next = self.tail
self.tail.prev = self.head
self.count = 0
def __len__(self):
return self.count
def __iter__(self):
return ListIterator(self)
# 插入列表尾部
def append(self, value):
return self.insertBefore(self.tail, value)
# 插入列表头部
def addFirst(self, value):
return self.insertAfter(self.head, value)
def find(self, value):
cur = self.head.next
while cur and cur.value != value:
cur = cur.next
return cur
# 删除一个节点
def remove(self, node):
node.prev.next = node.next
node.next.prev = node.prev
self.count -= 1
# 在某个节点前面插入新的数据
def insertBefore(self, node, value):
newNode = ListNode(value)
node.prev.next = newNode
newNode.prev = node.prev
newNode.next = node
node.prev = newNode
self.count+=1
return newNode
# 有没有发现双向链表的插入操作实现起来非常的简单了
def insertAfter(self, node, value):
return self.insertBefore(node.next, value)
if __name__ == '__main__':
# append
l = List()
l.append(1)
l.append(2)
l.append(3)
# find
v1 = l.find(1)
v2 = l.find(2)
v3 = l.find(3)
print(v1.value)
print(v2.value)
#remove
l.remove(v1)
l.remove(v2)
#insert before
v22 = l.insertBefore(v3, -2)
v33 = l.insertBefore(v22, -3)
#insert after
v4 = l.insertAfter(v3, 4)
v5 = l.insertAfter(v4, 5)
#count 5
print(len(l))
#print list -3, -2, 3, 4, 5
for val in l: print val,