用 python 学习数据结构(二)双向链表

##一、相比单向链表,双向链表的优势
双向链表的每个节点保存了前一个节点和后一个节点的引用(指针),到达某个节点是,可以向前或者向后遍历,提高了操作的效率。比如,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,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值