双向链表
一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
操作
- is_empty() 链表是否为空
- length() 链表长度
- travel() 遍历链表
- add(item) 链表头部添加
- append(item) 链表尾部添加
- insert(pos, item) 指定位置添加
- remove(item) 删除节点
- search(item) 查找节点是否存在
实现
# 导入单链表,将单链表改为双链表
from single_link_list import SingleLinkLise
# 节点
class Node(object):
def __init__(self, item):
self.elem = item
self.next = None
self.prev = None
class DoubleLinkList(SingleLinkLise):
'''双向链表的is_empty,length, travle方法和单链表的一样, 只需继承即可'''
def add(self, item):
'''覆盖单链表add方法'''
node = Node(item)
node.next = self._head
# 如果为空链表
if not self.is_empty():
# 双向链表需要将下一个链表节点的prev指向前一个节点
self._head.prev = node
self._head = node
def append(self, item):
'''链表尾部添加元素'''
node = Node(item)
# 判断是否为空,如果为空则直接指向新节点
if self.is_empty():
self._head = node
# 如果不为空,则找到最后一个节点添加
else:
cur = self._head
while cur.next != None:
cur = cur.next
cur.next = node
node.prev = cur
指定位置插入节点
def insert(self, pos, item):
'''指定位置添加元素'''
cur = self._head
count = 0
# 如果位置在第一个元素之前,就往头添加
if pos <= 0:
self.add(item)
# 如果位置在最后一个元素之后,就往尾添加
elif pos > self.length() - 1:
self.append(item)
else:
while count < pos -1:
count += 1
cur = cur.next
node = Node(item)
node.next = cur.next
cur.next.prev = node
node.prev = cur
cur.next = node
删除元素
def remove(self, item):
'''删除节点'''
# 如果为空链表
if self.is_empty():
return
else:
cur = self._head
while cur != None:
if cur.elem == item:
# 如果是头节点
if not cur.prev:
# 如果只有一个节点
if not cur.next:
self._head = None
else:
cur.next.prev = None
self._head = cur.next
else:
# 如果不是最后一个节点
if cur.next:
# 将删除位置的上一个节点next指向删除位置的下一个节点,将删除位置的下一个节点prev指向删除位置的上一个节点
cur.prev.next = cur.next
cur.next.prev = cur.prev
# 如果是尾节点
else:
cur.prev.next = None
break
else:
cur = cur.next
# 测试
if __name__ == '__main__':
dll = DoubleLinkList()
# 判断是否为空
print(dll.is_empty())
# 获取链表长度
print(dll.length())
# 遍历链表
dll.travel()
# 头添加元素
dll.add(1)
# 只有一个元素时删除
dll.remove(1)
dll.add(100)
print(dll.is_empty())
print(dll.length())
dll.travel()
print()
# 尾添加元素
dll.append(300)
dll.append(400)
dll.travel()
print()
# 指定位置添加元素
dll.insert(1, 200)
dll.insert(6, 500)
dll.travel()
print()
# 删除节点
dll.remove(300)
dll.travel()
print()
# 查找节点
print(dll.search(500))