概念准备
前驱节点:某个节点之前的那个节点
后继节点:某个节点之后的那个节点
双向链表的第一个结点,是没有前驱节点的,指向None
双向链表的最后一个节点,是没有后继节点的,指向None
每个节点有三个区域:prev区域保存前驱节点的地址指向前驱节点,elem区域保存数据item,next区域指向后继节点保存后继节点地址
继承
双向链表的判空is_empty,长度length,遍历travel,搜索search的实现方式和单链表一样
用面向对象的思想,继承自单链表类
详见链接: 单链表 – python描述.
双向链表代码
#导入单链表类
from 单链表类的模块 import SingleLinkList
class Node(object):
'''结点类'''
def __init__(self,item): #item为传进来的数据,即elem区
#结点的pre区域(存放前一个结点的地址)
self.prev = None
#结点的数据区域
self.elem = item
#结点的next区域(存放后一个结点的地址)
self.next = None
#继承自单链表类,is_empty(),length(),travle(),search()方法直接无需重写
class DoubleLinkList(object):
'''双向链表类'''
#双向链表指向
def add(self,item):
'''链表头部添加元素,头插法'''
#创建一个新结点
node = Node(item)
#第一步:将新节点的next区域指向第一个结点
node.next = self.__head
#第二步:将头结点指向新节点
self.__head = node
#第三步:将第一个结点的prev区域指向新节点
node.next.prev = node
def append(self,item):
'''链表尾部添加元素,尾插法'''
node = Node(item):
#如果链表是空链表
if self.is_empty():
self.__head = node
else:
cur = self.__head #创建一个游标
while cur.next != None: #游标走到最后一个节点时停止,最后一个节点的cur.next 指向 None
cur = cur.next
#游标走到最后一个节点,将最后一个节点的next指向新节点,新节点的prev区域指向cur
cur.next == node
node.prev == cur
def insert(self,pos,item):
'''指定位置添加元素
:param pos 从0开始
'''
if pos <= 0: #当用户输入的位置<0时,默认为头插法
self.add(item)
elif pos > (self.length()-1): #当用户输入的pos大于最大索引时,默认为尾插法
self.append(item)
else:
#创建游标记录位置
cur = self.__head
count = 0
while count < pos: #让cur走到要插入的位置
count += 1
cur = cur.next
#然后插入新节点
node = Node(item)
#将新节点的next指向cur走到的节点
Node.next = cur
#将新节点的prev指向cur指向的节点的前一个节点
Node.prev = cur.prev
#将cur指向的节点的prev指向新节点
cur.prev = node
#将cur指向的节点的原前驱节点(现已断开被node新节点指着)的next指向新节点
node.prev.next = node
def remove(self):
cur = self.__head
while cur != None: #指针从第一个节点走到最后一个节点
#当cur.elem等于用户输入的值时删除
if cur.elem == item:
#如果要删除的节点是第一个节点
if cur == self.__head:
#将头结点指向第一个节点的后继节点
self.__head = cur.next
#如果删了第一个节点后还有节点(该链表不止有一个节点)
if cur.next:
#将第一个节点的后继节点的prev区域指向None
cur.next.prev = None
#如果要删除的是中间节点或最后一个节点
else:
#将cur指向的节点的前驱节点的next区域指向后继节点
cur.prev.next = cur.next
#因为最后一个节点时cur.next指向None,不存在cur.net.prev
if cur.next:
#将cur指向的节点的后继节点的prev指向前驱节点
cur.next.prev = cur.prev
break #删除节点后推出循环
#当cur.elem不等于item时,继续前行
else:
cur = cur.next
if __name__ == '__main__':
ll = DoubleLinkList()
print(ll.is_empty())
print(ll.length())
ll.append(1)
print(ll.is_empty())
pritn(ll.length())
ll.append(2)
ll.add(8)
ll.append(3)
ll.append(4)
ll.insert(-1,9)
ll.travle()
ll.remove(100)
ll.travle()