python中的双向链表实现
引子

双向链表比之单向链表,多数操作方法的实现都没有什么不同,如is_empty, __len__, traverse, search。这些方法都没有涉及节点的变动,也就可通过继承单向链表来实现即可。
不同之处一是在于节点实现的不同。因为增加了指向前一个节点的前驱区,因此需要为节点添加一个新属性prev,用以指向前一个节点。
另外一点就是在做增删的操作时,需要额外考虑节点的前驱区的指向。其中的remove方法更是需要考虑多种特殊情况。
下面给出代码前,先放一个自己做的图示。(右键选择在新页面打开可看完整图示)

代码
class Node(object):
def __init__(self, value):
self.value = value
# 前驱区
self.prev = None
# 后继区
self.next = None class LinkedListTwoway(object):
def __init__(self):
self.__head = None def is_empty(self):
return self.__head is None def __len__(self):
count = 0
cur = self.__head
while cur:
count += 1
cur = cur.next
return count def traverse(self):
cur = self.__head
while cur:
print(cur.value)
cur = cur.next def add(self, value):
node = Node(value)
if self.is_empty():
self.__head = node
else:
# 待插入节点的后继区指向原头节点
node.next = self.__head
# 原头节点的前驱区指向待插入节点
self.__head.prev = node
self.__head = node def append(self, value):
node = Node(value)
cur = self.__head
if self.is_empty():
self.__head = Node
return
while cur.next:
cur = cur.next
cur.next = node
node.prev = cur def insert(self, pos, value):
if pos <= 0:
self.add(value)
elif pos > len(self) - 1:
self.append(value)
else:
# 单向链表中为了在特定位置插入,要先在链表中找到待插入位置和其前一个位置
# 双向链表中就不需要两个游标了(当然单向链表中一个游标也是可以只找前一个位置)
node = Node(value)
count = 0
cur = self.__head
while count < pos - 1:
count += 1
cur = cur.next
# 此时的游标指向pos的前一个位置
# 这里的相互指向需尤为注意,有多种实现,需细细分析
node.next = cur.next
cur.next.prev = node
node.prev = cur
cur.next = node def search(self, value):
cur = self.__head
while cur:
if cur.value == value:
return True
else:
cur = cur.next
return False def remove(self, value):
if self.is_empty():
return
cur = self.__head
while cur:
if cur.value == value:
if cur == self.__head:
self.__head = cur.next
# 处理链表只有一个节点的特殊情况
if cur.next:
cur.next.prev = None
else:
cur.prev.next = cur.next
# 处理待删除节点是最后一个情况
if cur.next:
cur.next.prev = cur.prev
return
else:
cur = cur.next
python中的双向链表实现的更多相关文章
- 【转载】Python中的垃圾回收机制
GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使用.GC彻底把程序员从资源管理的重担中解放出来,让他们有更多的时间放在 ...
- Python 中的垃圾回收机制--备忘
GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使用.GC彻底把程序员从资源管理的重担中解放出来,让他们有更多的时间放在 ...
- Python 中的垃圾回收机制(转载)
from: https://foofish.net/python-gc.html GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来 ...
- Python中collections模块的使用
本文将详细讲解collections模块中的所有类,和每个类中的方法,从源码和性能的角度剖析. 一个模块主要用来干嘛,有哪些类可以使用,看__init__.py就知道 '''This module i ...
- Python中的垃圾回收机制(转)
原文:https://foofish.net/python-gc.html GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他 ...
- Python 中的垃圾回收机制
GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使用.GC彻底把程序员从资源管理的重担中解放出来,让他们有更多的时间放在 ...
- Redis安装、说明、Python中使用
Redis安装与简单使用 Redis说明 redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 redis特点 Redis 支持数据的持久化,可以将内存中的数据保存在磁盘 ...
- Python 中的内存管理
Python 中一切皆对象,这些对象的内存都是在运行时动态地在堆中进行分配的,就连 Python 虚拟机使用的栈也是在堆上模拟的.既然一切皆对象,那么在 Python 程序运行过程中对象的创建和释放就 ...
- 16.python中的回收机制
python中的垃圾回收机制是以引用计数器为主,标记清除和分代回收为辅的 + 缓存机制 1.引用计数器 在python内部维护了一个名为refchain的环状双向链表,在python中创建的任何对象都 ...
随机推荐
- # 20175333曹雅坤《Java程序设计》第五周学习总结
教材学习内容总结 第六章要点: 1.接口:1)接口声明: interface //接口的名字 2)接口体 2.实现接口:类实现接口:一个类需要在类声明中使用关键字implements声明该类实现一个或 ...
- 阻塞IO,非阻塞IO,IO多路复用模型
#服务端 import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() while True: conn, ad ...
- Spring Cloud配置中心搭建(集成Git)
1. 在Github(或其他)创建配置中心仓库bounter-config-repo,然后在仓库创建两个配置文件:simon.properties.susan.properties,链接如下: htt ...
- C - Heavy Transportation && B - Frogger(迪杰斯变形)
Background Hugo Heavy is happy. After the breakdown of the Cargolifter project he can now expand bus ...
- 源码解析Django CBV的本质
Django CBV模式的源码解析 通常来说,http请求的本质就是基于Socket Django的视图函数,可以基于FBV模式,也可以基于CBV模式. 基于FBV的模式就是在Django的路由映射表 ...
- jQuery时间轴插件timeline.js
http://www.jq22.com/jquery-info13695 http://www.jq22.com/jquery-info13357 简要教程 timeline.js是一款jQuery时 ...
- SQL语句原理解析(原创)
基本的sql语句很好理解这里不做分析,这里只考虑复杂的sql语法和关键词用法的实验分析: 一,join关联的作用: 作用: 1,为了生成信息信息更加全面的中间表:2,为了where可以使用含有单表外字 ...
- vertx的Future设计
异步痛点 1.回调地狱(CallBack hell) ; 解决方式 Promise 或 Future 2.执行异步后的结果如何回调currentThread ; 解决方式 Context 设计 3.如 ...
- Spring框架xml配置中属性ref与value的区别
1.spring批量扫描mybatis的mapper,使用value 2.spring管理mybatis的单个mapper,用的是ref 虽然引用的是同一个bean,但两个对象的属相类型明显不一样,一 ...
- 可持久化线段树——区间更新hdu4348
和线段树类似,每个结点也要打lazy标记 但是lazy标记和线段树不一样 具体区别在于可持久化后lazy-tag不用往下传递,而是固定在这个区间并不断累加,变成了这个区间固有的性质(有点像分块的标记了 ...