1.双向链表的结点只是比单向链表的结点多一个属性前置结点
这里双向结点的类继承了(上一篇)单向链表使用的结点的类
class DoubleLinkedNode(BaseNode):
"""
双向链接结点
"""
def __init__(self, item):
"""双向链表的结点,就是比单向链表多一个前置结点的属性"""
# 前置结点
self.pre = None
super(DoubleLinkedNode, self).__init__(item)
2.双向链表的操作:
如果不涉及增、删操作,和单向链表的操作一致
这里双向链表的类继承了(上一篇)单向链表的类,然后对涉及增删操作的方法进行重写
class DoubleLinkedList(SingleLinkedList):
def add(self, item):
"""
头部添加一个结点
:param item:
:return:
"""
# 创建结点
node = DoubleLinkedNode(item)
# 将新结点的下一个结点指向原来的头结点,并将头结点指向新的结点(同单向链表)
node.next, self.head = self.head, node
# 如果原头结点不是None(此时node.next指向原来的头结点)
if node.next:
# 将原来的头结点的前一个结点指向新结点
node.next.pre = node
def append(self, item):
"""
从尾部添加一个结点
:param item: 将要添加的结点的值
:return: None
"""
# 创建新结点
new_node = DoubleLinkedNode(item)
if not self.head:
self.head = new_node
else:
# 获取头结点
node = self.head
# 如果当前结点的下一个结点不为None
while node.next:
# 将当前结点指向下一个结点
node = node.next
# 将当前结点的下一个结点指向新节点,并将新结点的前置结点指向当前结点
node.next, new_node.pre = new_node, node
def remove(self, item):
"""
根据值删除结点
:param item: 要删除的结点的值
:return: None
"""
# 如果链表不为空
if self.head:
# 获取头结点
node = self.head
# 如果头结点即是要删除的结点
if node.item == item:
# 将头结点指向下一个结点
self.head = self.head.next
# 如果此时链表不为空
if self.head:
# 将头结点的前一个结点指向None
self.head.pre = None
return
# 如果当前结点的下一个结点不为None
while node.next:
# 如果当前结点的下一个结点是要删除的结点
if node.next.item == item:
# 如果当前结点的下下个节点不为None
if node.next.next:
# 将当前结点的下下个节点的前置结点指向当前结点
node.next.next.pre = node
# 将当前结点的下一个结点指向下下个结点
node.next = node.next.next
# 返回
return
# 将当前结点指向下一个结点
node = node.next
# 值不在链表中
raise ValueError('item not in DoubleLinkedList')
def insert(self, site, item):
"""
插入一个结点
:param site: 要插入的位置
:param item: 要插入的值
:return:
"""
if not isinstance(site, int):
raise TypeError("site must be integers")
# 创建新结点
new_node = DoubleLinkedNode(item)
# 如过要插入的位置小于等于零
if site <= 0:
# 从头部添加
self.add(item)
# 如果要插入的位置大于等于链表的长度
elif site >= self.length():
# 从尾部添加
self.append(item)
else:
# 获取头部结点
node = self.head
# 找到要插入的位置的结点
for i in range(site):
node = node.next
# 将新结点的前置结点和下一个结点 分别指向当前结点的前一个结点和当前结点
# 将当前结点的前一个节点的下一个结点指向新结点 并将当前结点的前置结点指向新结点
new_node.next, new_node.pre, node.pre.next, node.pre = node, node.pre, new_node, new_node