python 双向循环链表实现_python实现双向循环链表基本结构及其基本方法
双向循环链表是在双向链表的基础上发展的,双向链表的最后一个节点指向起始节点,起始节点的上一个节点指向最后一个节点,就得到双向循环链表。
双向循环链表比双向链表具有更多的优势,节点的增加和删除有很多优化的地方,从起点开始不必循环完整个链表就可以增加或删除节点。
首先定义双向链表的基本类和节点的基本类:
image
class Node:
def __init__(self, item):
self.item = item # 该节点值
self.next = None # 连接一下一个节点
self.prev = None # 上一个节点值
class DoubleCircularLinkedList:
"""双向循环列表类"""
def __init__(self):
self._head = None
下面我们添加基本属性方法的逻辑,注意判断是否为最后一个节点的方式是:最后一个节点的下一个节点是否指向头部指向的节点。
class Node:
def __init__(self, item):
self.item = item # 该节点值
self.next = None # 连接一下一个节点
self.prev = None # 上一个节点值
class DoubleCircularLinkedList:
"""双向循环列表类"""
def __init__(self):
self._head = None
@property
def is_empty(self):
"""
判断链表是否为空
:return:
"""
return not self._head
@property
def length(self):
"""
链表长度
:return:
"""
if self.is_empty:
return 0
else:
cur = self._head.next
n = 1
while cur != self._head:
cur = cur.next
n += 1
return n
@property
def ergodic(self):
"""
遍历链表
:return:
"""
if self.is_empty:
raise ValueError("ERROR NULL")
else:
cur = self._head.next
print(self._head.item)
while cur != self._head:
print(cur.item)
cur = cur.next
链表类的操作有几个核心的地方,第一个是判断是否为最后一个节点,通过链表的相关特性,如单向链表最后一个节点的next属性为None、单向循环链表的最后一个节点的next属性等于头部节点;第二个是使用游标来替代节点指向,这个在操作节点的时候需要有时还需要两个游标,但是对于双向节点而言只需要一个游标,通过当前节点的属性可以找到上下节点。
继续给对象添加方法:头部插入节点、尾部添加节点、任意位置插入节点。
class Node:
def __init__(self, item):
self.item = item # 该节点值
self.next = None # 连接一下一个节点
self.prev = None # 上一个节点值
class DoubleCircularLinkedList:
"""双向循环列表类"""
def __init__(self):
self._head = None
@property
def is_empty(self):
"""
判断链表是否为空
:return:
"""
return not self._head
@property
def length(self):
"""
链表长度
:return:
"""
if self.is_empty:
return 0
else:
cur = self._head.next
n = 1
while cur != self._head:
cur = cur.next
n += 1
return n
@property
def ergodic(self):
"""
遍历链表
:return:
"""
if self.is_empty:
raise ValueError("ERROR NULL")
else:
cur = self._head.next
print(self._head.item)
while cur != self._head:
print(cur.item)
cur = cur.next
def add(self, item):
"""
头部添加节点
:return:
"""
node = Node(item)
if self.is_empty:
node.next = node
node.prev = node
self._head = node
else:
node.next = self._head
node.prev = self._head.prev
self._head.prev.next = node
self._head.prev = node
self._head = node
def append(self, item):
"""
尾部添加节点
:param item:
:return:
"""
if self.is_empty:
self.add(item)
else:
node = Node(item)
cur = self._head.next
while cur.next != self._head:
cur = cur.next
cur.next = node
node.prev = cur
node.next = self._head
self._head.prev = node
def insert(self, index, item):
"""
任意位置插入节点
:param item:
:return:
"""
if index == 0:
self.add(item)
elif index+1 >= self.length:
self.append(item)
else:
cur = self._head.next
n = 1
while cur.next != self._head:
if n == index:
break
cur = cur.next
n += 1
node = Node(item)
node.prev = cur.prev
cur.prev.next = node
node.next = cur
cur.prev = node
接着实现判断节点是否存在以及删除指定节点。
class Node:
def __init__(self, item):
self.item = item # 该节点值
self.next = None # 连接一下一个节点
self.prev = None # 上一个节点值
class DoubleCircularLinkedList:
"""双向循环列表类"""
def __init__(self):
self._head = None
@property
def is_empty(self):
"""
判断链表是否为空
:return:
"""
return not self._head
@property
def length(self):
"""
链表长度
:return:
"""
if self.is_empty:
return 0
else:
cur = self._head.next
n = 1
while cur != self._head:
cur = cur.next
n += 1
return n
@property
def ergodic(self):
"""
遍历链表
:return:
"""
if self.is_empty:
raise ValueError("ERROR NULL")
else:
cur = self._head.next
print(self._head.item)
while cur != self._head:
print(cur.item)
cur = cur.next
def add(self, item):
"""
头部添加节点
:return:
"""
node = Node(item)
if self.is_empty:
node.next = node
node.prev = node
self._head = node
else:
node.next = self._head
node.prev = self._head.prev
self._head.prev.next = node
self._head.prev = node
self._head = node
def append(self, item):
"""
尾部添加节点
:param item:
:return:
"""
if self.is_empty:
self.add(item)
else:
node = Node(item)
cur = self._head.next
while cur.next != self._head:
cur = cur.next
cur.next = node
node.prev = cur
node.next = self._head
self._head.prev = node
def insert(self, index, item):
"""
任意位置插入节点
:param item:
:return:
"""
if index == 0:
self.add(item)
elif index+1 >= self.length:
self.append(item)
else:
cur = self._head.next
n = 1
while cur.next != self._head:
if n == index:
break
cur = cur.next
n += 1
node = Node(item)
node.prev = cur.prev
cur.prev.next = node
node.next = cur
cur.prev = node
def search(self, item):
"""
查找节点是否存在
:return:
"""
if self.is_empty:
return False
else:
cur = self._head.next
if self._head.item == item:
return True
else:
while cur != self._head:
if cur.item == item:
return True
else:
cur = cur.next
return False
def delete(self, item):
"""
删除指定值的节点
:param item:
:return:
"""
if self.is_empty:
raise ValueError("ERROR NULL")
else:
if self._head.item == item:
if self.length == 1:
self._head = Node
else:
self._head.prev.next = self._head.next
self._head.next.prev = self._head.prev
self._head = self._head.next
cur = self._head.next
while cur != self._head:
if cur.item == item:
cur.prev.next = cur.next
cur.next.prev = cur.prev
cur = cur.next
只以基本的思路实现基本的方法,对于双向循环链表而言还有很多可以优化的地方,正向遍历和逆向遍历获得结果的时间是不一样的。
image
python 双向循环链表实现_python实现双向循环链表基本结构及其基本方法相关推荐
- python rsa 公钥解密_python利用rsa库做公钥解密的方法教程
前言 对于RSA的解密,即密文的数字的 D 次方求mod N 即可,即密文和自己做 D 次乘法,再对结果除以 N 求余数即可得到明文.D 和 N 的组合就是私钥(private key). 算法的加密 ...
- python编写ATM类_Python中编写类的各种技巧和方法
有关 Python 内编写类的各种技巧和方法(构建和初始化.重载操作符.类描述.属性访问控制.自定义序列.反射机制.可调用对象.上下文管理.构建描述符对象.Pickling).你可以把它当作一个教程, ...
- python 字符串去空格_Python去除、替换字符串空格的处理方法
个人想到的解决方法有两种,一种是 .replace(' old ',' new ') 第一个参数是需要换掉的内容比如空格,第二个是替换成的内容,可以把字符串中的空格全部替换掉. 第二种方法是像这样 s ...
- python读取txt文件_python实现读写txt文件的几种方法
一.读写模式: w:向文件中写入内容,w会清空原来文本内容 a:向文件中追加内容 r:从文件中读取内容 wb:以二进制形式写入内容. rb:以二进制形式读文件内容 ab:以二进制形式追加内容 a+.r ...
- python数据库安装教程_python MySQLdb Windows下安装教程及问题解决方法
使用python访问mysql,需要一系列安装 linux下MySQLdb安装见 Python MySQLdb在Linux下的快速安装 https://www.jb51.net/article/657 ...
- python获取输入数字_python获取从命令行输入数字的方法
本文实例讲述了python获取从命令行输入数字的方法.分享给大家供大家参考.具体如下: #---------------------------------------- # Name: numeri ...
- python处理文本格式_python linecache 处理固定格式文本数据的方法
小程序大功能 对一批报文要处理要处理里面的得分,发现python linecache ,特记录如下. #!/usr/bin/env python # -*- coding: utf-8 -*- ''' ...
- python控制台不能输入_python实现在控制台输入密码不显示的方法
本文实例讲述了python实现在控制台输入密码不显示的方法.分享给大家供大家参考.具体实现方法如下: import console; namespace console{ //控制台读取密码,并显示星 ...
- math python 向上取整_Python的数值基本运算和其它数学运算方法
数值基本运算 支持最基本的数学运算符号:+ - * / % **.取正负+x -x,地板除法//,除法和取模divmod(x, y): 12345678910111213141516171819202 ...
最新文章
- 23 岁的 Java 成为编程界的扛把子,网友回复:这就是实力
- java常用数据类型之间转换
- 如何用笔记本建立wifi热点
- cf1208E. Let Them Slide
- 速达服务器账套定期维护么,速达软件常见操作问题解决方法
- debian dhcp服务启动不了_网刻批量装系统pxe启动教程全自动分区装系统
- css背景图充满整个屏幕
- [Asp.net]Uploadify上传大文件,Http error 404 解决方案 - wolfy
- c语言程序设计逗号作用,逗号运算符C语言程序设计.pdf
- 命令行删除RMS SCP 连接点
- thinkPHP框架
- tableau实战系列(十二)-使用盒须图查看你的数据分布
- python天眼查爬虫_学习Python3 天眼查 爬虫
- 第一次开发EOS区块链的经验总结
- 【面试总结】JNI层MediaScanner的分析,挥泪整理面经
- 服务器更新维护公告语,6月1日阴阳师服务器更新维护内容公告
- 在C语言中如何产生随机数
- Android游戏源码合集(主要是AndEngine和Libgdx的)
- 编写ESM风格的nodejs应用
- Windows 如何配置 scratch 3.0 GUI
热门文章
- 2020年的风口来了!传统企业如何做数字化转型?
- 飞鸽传书下载 分析企业OpenEIM
- 努力的钻研深层次的【飞鸽传书】技术
- 企业巧妙运用飞秋提高工作效率
- 程序员救赎之路:从“996”到微软“4天6小时工作制”
- 清华2020计算机系张晨,2020清华特奖入围名单公布:电子系学霸两篇顶会一作
- php xmldom扩展,如何使用比根更深入的PHP DOM向XML添加新元素?
- 机器学习 | 网络搜索及可视化
- 图像入门二之视频操作
- 复现原文(一):Single-cell RNA sequencing of human kidney(step by step)