双向链表是在单向链表的基础上更为复杂的数据结构,其中一个节点除了含有自身信息外,还应该含有下连接一下个节点和上一个节点的信息。
双向链表适用于需要双向查找节点值的场景中,在数据量难以估计并且数据增删操作频繁的场景中,双向链表有一定优势;链表在内存中呈现的状态是离散的地址块,不需要像列表一样预先分配内存空间,在内存的充分利用上更胜一筹,不过增加了一些额外开销。
双向链表结构如图:

定义基本的节点类和链表类:
class Node:
"""节点类"""
def __init__(self, item):
self.item = item
self.next = None
self.prev = None
class DLinkList:
"""
双向列表类
"""
def __init__(self):
self.head = None
时间双向链表类的基本属性:是否为空,链表长度、链表遍历;判断链表是否为空只需要看头部head是否指向空,链表遍历只需要从头部到最后一个节点的下一个节点指向为空的情况,同时链表长度也是根据最后一个节点的下一个节点是否指向空来判断,基本实现如下:
class Node:
"""节点类"""
def __init__(self, item):
self.item = item
self.next = None
self.prev = None
class DLinkList:
"""
双向列表类
"""
def __init__(self):
self._head = None
@property
def is_empty(self):
return None == self._head
@property
def length(self):
if self.is_empty:
return 0
n = 1
cur = self._head
while None != cur.next:
cur = cur.next
n += 1
return n
@property
def ergodic(self):
if self.is_empty:
raise ValueError('ERROR NULL')
cur = self._head
print(cur.item)
while None != cur.next:
cur = cur.next
print(cur.item)
return True
接下来实现添加节点相关的操作,在头部添加、任意位置添加、尾部添加,注意在任意插入节点的时候,需要对节点进行遍历并计数,注意计数起始是1,而不是0,对应的节点是从第二个节点开始。
class Node:
"""节点类"""
def __init__(self, item):
self.item = item
self.next = None
self.prev = None
class DLinkList:
"""
双向列表类
"""
def __init__(self):
self._head = None
@property
def is_empty(self):
"""
是否为空
:return:
"""
return None == self._head
@property
def length(self):
"""
链表长度
:return:
"""
if self.is_empty:
return 0
n = 1
cur = self._head
while None != cur.next:
cur = cur.next
n += 1
return n
@property
def ergodic(self):
"""
遍历链表
:return:
"""
if self.is_empty:
raise ValueError('ERROR NULL')
cur = self._head
print(cur.item)
while None != cur.next:
cur = cur.next
print(cur.item)
return True
def add(self, item):
"""
在头部添加节点
:param item:
:return:
"""
node = Node(item)
if self.is_empty:
self._head = node
else:
node.next = self._head
self._head.prev = node
self._head = node
def append(self, item):
"""
在尾部添加节点
:return:
"""
if self.is_empty:
self.add(item)
else:
node = Node(item)
cur = self._head
while None != cur.next:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self, index, item):
"""
在任意位置插入节点
:param index:
:param item:
:return:
"""
if index == 0:
self.add(item)
elif index+1 >= self.length:
self.append(item)
else:
n = 1
node = Node(item)
cur = self._head
while Node != cur.next:
pre = cur
cur = cur.next
if n == index:
break
pre.next = node
node.prev = pre
node.next = cur
cur.prev = node
在实现较为复杂的删除节点操作和判断节点是否存在的方法。
class Node:
"""节点类"""
def __init__(self, item):
self.item = item
self.next = None
self.prev = None
class DLinkList:
"""
双向列表类
"""
def __init__(self):
self._head = None
@property
def is_empty(self):
"""
是否为空
:return:
"""
return None == self._head
@property
def length(self):
"""
链表长度
:return:
"""
if self.is_empty:
return 0
n = 1
cur = self._head
while None != cur.next:
cur = cur.next
n += 1
return n
@property
def ergodic(self):
"""
遍历链表
:return:
"""
if self.is_empty:
raise ValueError('ERROR NULL')
cur = self._head
print(cur.item)
while None != cur.next:
cur = cur.next
print(cur.item)
return True
def add(self, item):
"""
在头部添加节点
:param item:
:return:
"""
node = Node(item)
if self.is_empty:
self._head = node
else:
node.next = self._head
self._head.prev = node
self._head = node
def append(self, item):
"""
在尾部添加节点
:return:
"""
if self.is_empty:
self.add(item)
else:
node = Node(item)
cur = self._head
while None != cur.next:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self, index, item):
"""
在任意位置插入节点
:param index:
:param item:
:return:
"""
if index == 0:
self.add(item)
elif index+1 >= self.length:
self.append(item)
else:
n = 1
node = Node(item)
cur = self._head
while Node != cur:
pre = cur
cur = cur.next
if n == index:
break
pre.next = node
node.prev = pre
node.next = cur
cur.prev = node
def search(self, item):
"""
查找节点是否存在
:param item:
:return:
"""
if self.is_empty:
raise ValueError("ERROR NULL")
cur = self._head
while None != cur:
if cur.item == item:
return True
cur = cur.next
return False
def deltel(self, item):
"""删除节点元素"""
if self.is_empty:
raise ValueError('ERROR NULL')
else:
cur = self._head
while None != cur:
if cur.item == item:
if not cur.prev: # 第一个节点
if None != cur.next: # 不止一个节点
self._head = cur.next
cur.next.prev = None
else: # 只有一个节点
self._head = None
else: # 不是第一个节点
if cur.next == None: # 最后一个节点
cur.prev.next = None
else: # 中间节点
cur.prev.next = cur.next
cur.next.prev = cur.prev
cur = cur.next
注意在删除节点的时候要考虑几种特殊情况:删除节点为第一个节点,并且链表只有一个节点;删除节点为第一个节点并且链表长度大于1;删除节点是中间节点;删除节点是最后一个节点;

来源:https://yq.aliyun.com/articles/696984
一、队列的基本概念 1、定义 队列是一种先进先出的线性表。它只允许在表的前端进行删除操作,而在表的后端进行插入操作,具有先进先出、后进后出的特点。进行插入操作的一端成为队尾(tail),进行删除操作的一端称为队头(head)。当队列中没有元素时,则称之为空队列。 在队列中插入一个元素称为入队,从队列中删除一个元素称为出队。因为队列只允许在队尾插入元素,在队头删除元素,所以队列又称为先进先出(FIF...
双向链表的实现 本质: 其实就是定义两个指针域, 分别存放直接前驱结点的指针和直接后继结点的指针. 具体实现 定义一个双向链表 创建一个指定大小的双向链表 求链表的长度 双向链表的插入操作 双向链表的删除操作:与插入操作类似, 在此不再赘述 双向链表的遍历 双向链表的销毁 双向链表的倒序遍历 测试 效果图 希望该文章能对大家有所帮助 同时真诚接受大家宝贵评论和建议...
链表的基本操作的实现,个人感觉链表的实现比顺序表的实现复杂了一点,特别是在操作的实现的过程中对边界的判断有点困难,画图吧,画图就可以很清楚地看出各个节点之间的关系和边界了。 1.链表的定义 2.初始化链表 3.创建链表,使链表含有元素 4.打印输出链表内部的元素 5.求链表的长度 6.查找第i个位置,并返回该位置的值 7.查找链表中值为key的节点,并返回位置 8.插入操作 9.删除操作 10.主...
数据结构单链表的基本操作的实现 1.1单链表的初始化 1.2 判断链表是否为空 1.3单链表的销毁 清空单链表 求单链表的表长 取值 按照值查找 插入 删除第i个节点 单链表的建立----头插法 单链表的创建----尾插法...
大话数据结构 一、双向链表(double linked list)如图26.5,是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。双向链表的基本操作与单链表基本一样,除了插入和删除的时候需要更改两个指针变量,需要注意的是修改的顺序很重要,插入如图3-14-5,删除如图3-14-6。 记住口诀:先搞定插入节点的前驱和后继,再搞定后节点的前驱,前节点的后继。 链表的delete操作需要首先找到...
一、基本运算 1、单链表、双链表的定义: 设计链式存储结构时,每个逻辑节点存储单独存储。 2、单链表的基本结构: 头节点在前,首节点在后。 3、顺序表与链表间存储密度的差异: 顺序表的存储密度为1,而链表的存储密度小于1。 4、 一个是data域部分,一个是指向后继节点的指针域。 5、特点: 6、插入节点: p指针指向a节点。 7、删除节点: 二、基本算法 1、头插法建表 这个算法的时...
函数都有prototype属性,它指向原型对象。 实例对象有__proto__属性,它指向对象原型 每一个原型对象都有constructor输赢,指向构造函数,每一个原型对象又具有__proto__属性,这个指向Object.prototype.在这里插入图片描述...
2.Dubbo简介 2.1 什么是dubbo Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。 2.2 流程图 Provider : 暴露服务的服务提供方。 Consumer : 调用远程服务的服务消费方。 Registry : 服务注册与发现的注册中心。 Monito...
mysql基础入门的总结 关于数据库: 数据库是软件开发人员要掌握的基本工具,软件的运行的过程就是操作数据的过程,数据库中的数据无非就是几个操作:增-删-查-改。 Mysql安装完成后,需要配置变量环境,找到配置路径path,然后把mysql安装目录bin文件导入就可以了。 然后运行cm...
adb常用命令: 查看手机是否连接:adb devices 连接设备:adb connect 设备ip:端口号 若有连接多个设备需指明设备ip及端口号 安装APP:adb install [-r] 包名 -r表示覆盖安装,首次安装可省略 卸载APP:adb uninstall 包名 列出设备中所有应用包名:adb shell pm list packages ...
I'm currently trying out the google cloud messaging service with its sample application "Guestbook." https://developers.google.com/cloud/samples/mbs/ I'm attempting to send notifications tha...
Now I came across an article that distinguishes between an Asynchronous function and Synchronous functions. From my understanding of the different examples and explanations, synchronous functions are ...
Good day all I'm busy creating a small costing calculator for the signage department. I'm not getting the calculator to output the amount. Brief Description: You enter the height and width and then wh...
I have 3 models created with Flask-SQLalchemy: User, Role, UserRole role.py: user.py: user_role.py: If I try (in the console) to get all users via User.query.all() I get AttributeError: 'NoneType' obj...
I have many particles that follow an stochastic process in parallel. For each particle, there is a PRNG associated to it. The simulation must go through many repetitions to get average results. For ea...