学习日志016--python实现双向循环列表与链栈

python中一些复合数据结构通过类的封装来实现的。双向循环链表与链栈也在其中。

双向循环链表

双向循环链表是一种特殊类型的链表,它结合了双向链表和循环链表的特点。在双向循环链表中,每个节点不仅包含数据,还持有指向前一个和后一个节点的指针,而且链表的最后一个节点指向第一个节点,形成一个闭环。

封装

就像上面介绍的一样,每一个结点(头结点除外)都有前驱,后继,以及数据域。由此创建结点类。

# 创建双向链表节点
# 双向链表结点有前驱有后继有数据域
class Node:def __init__(self,data):self.data = dataself.prior = Noneself.next = None

头结点

不是必须的,但为了方便对链表的操作,我们还是会创建。和其他链表的头结点一样,包含链表长度和head的成员变量。

#创建头结点便于操作链表
class Double:# 头结点记录链表地址,链表长度def __init__(self,node = None):self.head = nodeself.size = 0

判空

同样由于链式存储的优点,我们只需要判空。

    # 判空def is_empty(self):return self.size == 0

双向链表的插入与删除,根据表内元素个数不同,需要分开编写代码

尾插法

#尾插 根据链表是否为空有不同的插入方法def insert_rear(self,value):node = Node(value)# 当表为空时if self.is_empty():# 当只有一个元素时,循环链表前驱和后继指向自己self.head = nodenode.next =  nodenode.prior = nodeelse:# 变量指向最后一个结点,即head的前驱p = self.head.priornode.next = p.nextnode.prior = pp.next.prior = nodep.next = nodeself.size += 1

尾删法

# 尾删def del_rear(self):if self.is_empty():print("删除失败")elif self.size == 1:self.head = Noneelse:# 尾删直接将头结点的前驱指向前前结点,同时将现前结点的后继指向头结点q = self.head.prior.priorself.head.prior = qq.next = self.headself.size -= 1

遍历

双向循环列表可以使用前驱遍历和后继遍历两种方式

# 后继 def show(self):if self.size == 0:print("遍历失败")returnelse:p = self.headwhile p.next != self.head:print(f"{p.data}",end=" ")p = p.nextprint(f"{p.data}")#前驱def r_show(self):if self.size == 0:print("遍历失败")returnelse:p = self.headwhile p.prior != self.head:print(f"{p.data}", end=" ")p = p.priorprint(f"{p.data}")

全部代码

# 创建双向链表节点
# 双向链表结点有前驱有后继有数据域
class Node:def __init__(self,data):self.data = dataself.prior = Noneself.next = None#创建头结点便于操作链表
class Double:# 头结点记录链表地址,链表长度def __init__(self,node = None):self.head = nodeself.size = 0# 判空def is_empty(self):return self.size == 0#尾插 根据链表是否为空有不同的插入方法def insert_rear(self,value):node = Node(value)# 当表为空时if self.is_empty():# 当只有一个元素时,循环链表前驱和后继指向自己self.head = nodenode.next =  nodenode.prior = nodeelse:# 变量指向最后一个结点,即head的前驱p = self.head.priornode.next = p.nextnode.prior = pp.next.prior = nodep.next = nodeself.size += 1# 根据链表长度遍历输出def show(self):if self.size == 0:print("遍历失败")returnelse:i = 1p = self.headwhile p.next != self.head:print(f"{p.data}",end=" ")p = p.nexti+=1print(f"{p.data}")def r_show(self):if self.size == 0:print("遍历失败")returnelse:i = 1p = self.headwhile p.prior != self.head:print(f"{p.data}", end=" ")p = p.priori += 1print(f"{p.data}")# 尾删def del_rear(self):if self.is_empty():print("删除失败")elif self.size == 1:self.head = Noneelse:# 尾删直接将头结点的前驱指向前前结点,同时将现前结点的后继指向头结点q = self.head.prior.priorself.head.prior = qq.next = self.headself.size -= 1if __name__ =="__main__":d = Double()# 尾插法d.insert_rear(10)d.insert_rear(20)d.insert_rear(30)d.insert_rear(40)d.show()d.r_show()# 尾删法d.del_rear()d.show()d.del_rear()d.show()d.del_rear()d.show()d.del_rear()d.show()
10 20 30 40
10 40 30 20
10 20 30
10 20
10
遍历失败

链栈

链栈(Linked Stack)是一种基于链表实现的栈结构。在链栈中,每个元素都是一个节点,包含数据域和指向下一个节点的指针。链栈不需要像顺序栈那样预先分配固定大小的存储空间,它可以动态地分配和释放内存,因此更加灵活。

经过之前的练习,对于链式存储已经得心应手,简单完成栈的结点与头结点的封装

结点

和我们学习的线性表相同,链栈的结点也是由数据域与链接域组成。

# 创建链栈
# 创建链栈的结点,包含数据域data与链接域next
class Node:def __init__(self,data):self.data = dataself.next = None

 头结点

栈没有像线性表一样,计算长度的实例变量。有一个指向栈顶元素的top

# 封装链栈 一个永远指向栈顶的头结点,不限于统计链栈长度 ,记录栈顶位置
class LinkStack:def __init__(self,top = None):self.top = top

判空

    # 判空def is_empty(self):return self.top is None

入栈

类似之前线性表的头插法 ,新结点指向栈顶,top指向新的结点

   # 入栈 每个新元素充当栈顶def push(self,value):node = Node(value)
#         根据是否栈空这里有不同的插入方法if self.is_empty():self.top = nodeelse:node.next = self.topself.top = node

出栈

先入后出是栈的特性,最后入栈的元素后出来。出栈会返回该元素并删除。

     出栈 返回栈顶元素并删除def pop(self):
#         这里根据元素的多少有两种写法i = self.topif self.is_empty():print("栈空操作失败")return ielse:if self.top.next is None:self.top = Nonereturn i.dataelse:self.top = self.top.nextreturn i.data

返回栈顶元素

    def peek(self):#         这里根据元素的多少有两种写法i = self.topif self.is_empty():print("栈空操作失败")return ielse:self.top = self.top.nextreturn i

统计栈的大小

    def size(self):i = 0p = self.topwhile p:p = p.nexti+=1return i

遍历栈的元素

  def show(self):if self.is_empty():print("栈空操作失败")else:p =self.topwhile p:print(f"{p.data}",end=" ")p = p.nextprint()

全部代码

# 创建链栈
# 创建链栈的结点,包含数据域data与链接域next
class Node:def __init__(self,data):self.data = dataself.next = None# 封装链栈 一个永远指向栈顶的头结点,不限于统计链栈长度 ,记录栈顶位置
class LinkStack:def __init__(self,top = None):self.top = top# 判空def is_empty(self):return self.top is None# 入栈 每个新元素充当栈顶def push(self,value):node = Node(value)
#         根据是否栈空这里有不同的插入方法if self.is_empty():self.top = nodeelse:node.next = self.topself.top = node#     出栈 返回栈顶元素并删除def pop(self):
#         这里根据元素的多少有两种写法i = self.topif self.is_empty():print("栈空操作失败")return ielse:if self.top.next is None:self.top = Nonereturn i.dataelse:self.top = self.top.nextreturn i.datadef peek(self):#         这里根据元素的多少有两种写法i = self.topif self.is_empty():print("栈空操作失败")return ielse:self.top = self.top.nextreturn idef size(self):i = 0p = self.topwhile p:p = p.nexti+=1return idef show(self):if self.is_empty():print("栈空操作失败")else:p =self.topwhile p:print(f"{p.data}",end=" ")p = p.nextprint()if __name__ == "__main__":s = LinkStack()s.push(10)s.push(20)s.push(30)s.push(40)s.push(50)print(s.size())s.show()s.pop()s.show()s.peek()s.show()s.pop()s.show()s.pop()s.show()s.pop()s.show()s.pop()s.show()
D:\xn\hqyj\pythonProject\.venv\Scripts\python.exe C:\Users\31284\OneDrive\Desktop\PYTHON\数据结构\day03\03.py 
5
50 40 30 20 10 
40 30 20 10 
30 20 10 
20 10 
10 
栈空操作失败
栈空操作失败
栈空操作失败进程已结束,退出代码为 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/478855.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【自动化Selenium】Python 网页自动化测试脚本(上)

目录 1、Selenium介绍 2、Selenium环境安装 3、创建浏览器、设置、打开 4、打开网页、关闭网页、浏览器 5、浏览器最大化、最小化 6、浏览器的打开位置、尺寸 7、浏览器截图、网页刷新 8、元素定位 9、元素交互操作 10、元素定位 (1)ID定位 &…

微软Ignite 2024:建立一个Agentic世界!

在今年的Microsoft Ignite 2024上,AI Agent无疑成为本次大会的重点,已经有十万家企业通过Copilot Studio创建智能体了。微软更是宣布:企业可以在智能体中,使用Azure目录中1800个LLM中的任何一个模型了! 建立一个Agent…

嵌入式linux系统中图像处理基本方法

目录 2.1 BMP图像处理 2.1.1 BMP文件格式解析 2.1.2 代码实现:将BMP文件解析为RGB格式,在LCD上显示 2.2 JPEG图像处理 2.2.1 JPEG文件格式和libjpeg编译 2.2.2 libjpeg接口函数的解析和使用 2.2.3 使用libjpeg把JPEG文件解析为RGB格式,在LCD上显示 …

探索 GAN 的演变之路

2014 年,在论文Generative Adversarial Networks中,首次提出了 GAN,其核心思想是“生成”与“对抗”。GAN 由一个生成器 G(Generator)和一个判别器 D(Discriminator)构成,前者用于捕捉数据分布,后者用于判别某个样本是…

Vue实训---5-路由搭建

回顾之前的代码 我们在my-vue-project\src\router\index.js中的代码如下: // 什么是路由?路由就是url地址和组件的对应关系 // 1.引入vue-router import { createRouter, createWebHashHistory } from vue-router// 2.定义路由 const routes [{path: …

【GAMES101笔记速查——Lecture 19 Cameras,Lenses and Light Fields】

本章节内容:相机、棱镜、光场 计算机图形学的两种成像方法: 1.合成方法:光栅化、光线追踪(展示出现实没有的东西) 2.捕捉方法:相机(捕捉现实已有的东西) 目录 1 相机 1.1 针孔相…

MacOS系统上Jmeter 录制脚本遇到的证书坑位

一、JMeter介绍与安装 1,下载及安装 jmeter官网地址 二、录制百度链接https请求时,需要导入jmeter相关证书到macos系统的更目录中. 导入方式,直接拖入mac的系统中,始终新人就可以; 三、jmeter 创建相关的录制组件…

软件团队的共担责任

问责制被认为是个人与其社会系统之间的纽带,它创造了一种将个人与其行为和绩效联系起来的身份关系。在入门系列的第一篇文章《超越工具和流程:成功软件开发团队的策略》中,我们介绍了问责制的概念,并提出了以下定义: …

【Python爬虫实战】深入解析 Scrapy:从阻塞与非阻塞到高效爬取的实战指南

🌈个人主页:易辰君-CSDN博客 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html ​ 目录 前言 一、阻塞和非阻塞 (一)阻塞 (二)非阻塞 二、Scrapy的工作…

【Python数据分析五十个小案例】电影评分分析:使用Pandas分析电影评分数据,探索评分的分布、热门电影、用户偏好

博客主页:小馒头学python 本文专栏: Python数据分析五十个小案例 专栏简介:分享五十个Python数据分析小案例 在现代电影行业中,数据分析已经成为提升用户体验和电影推荐的关键工具。通过分析电影评分数据,我们可以揭示出用户的…

第八篇:CamX RawHdr Feature Enable

CamX RawHdr Feature Enable RawHdr feature介绍: 试用于拍照场景,输入3张Raw,输出一张Raw。 对应的pipeline: camxSWMFMergeRaw.xml (usecases: UsecaseZSL) featureGraph: RTRawHDRBayer2YUVJPEG ​ RT -> RawHdr -> Bayer2Yuv -> JPEG RTRawHDRBayer2YUVJPE…

Python毕业设计选题:基于django+vue的期货交易模拟系统的设计与实现

开发语言:Python框架:djangoPython版本:python3.7.7数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 系统首页 期货信息 个人中心 管理员登录界面 管理员功能界面 用户管理 期货公司管理…

文件内容扫描工具

简介 文件扫描助手是一款基于Vite Vue 3 Electron技术栈开发的跨平台桌面应用程序。它提供了强大的文件内容搜索功能,支持Word、Excel、PDF、PPT等常见办公文档格式。用户可以通过关键词快速定位到包含特定内容的文件,极大地提高了文件管理和查找效率…

数据结构--AVL树(平衡二叉树)

✅博客主页:爆打维c-CSDN博客​​​​​​ 🐾 🔹分享c、c知识及代码 🐾 🔹Gitee代码仓库 五彩斑斓黑1 (colorful-black-1) - Gitee.com 一、AVL树是什么?(含义、性质) 1.AVL树的概念 AVL树是最…

【算法】连通块问题(C/C++)

目录 连通块问题 解决思路 步骤: 初始化: DFS函数: 复杂度分析 代码实现(C) 题目链接:2060. 奶牛选美 - AcWing题库 解题思路: AC代码: 题目链接:687. 扫雷 -…

24.11.26 Mybatis2

resultMap 中的标签和属性 如果是主键列 一般用id标签对应 propertyjava对象的属性 column 数据库中的列( javaType实体类数据类型 jdbcType数据库列的数据类型 ) 不需要配置 <id property"empno" column"empno" />如果是普通列 一般用result对…

Redis设计与实现第14章 -- 服务器 总结(命令执行器 serverCron函数 初始化)

14.1 命令请求的执行过程 一个命令请求从发送到获得回复的过程中&#xff0c;客户端和服务器都需要完成一系列操作。 14.1.1 发送命令请求 当用户在客户端中输入一个命令请求的时候&#xff0c;客户端会把这个命令请求转换为协议格式&#xff0c;然后通过连接到服务器的套接字…

ArcGIS pro中的回归分析浅析(加更)关于广义线性回归工具的补充内容

在回归分析浅析中篇的文章中&#xff0c; 有人问了一个问题&#xff1a; 案例里的calls数据貌似离散&#xff0c;更符合泊松模型&#xff0c;为啥不采用泊松而采用高斯呢&#xff1f; 确实&#xff0c;在中篇中写道&#xff1a; 在这个例子中我们为了更好地解释变量&#x…

【面试题】2025年百度校招Java后端面试题

文章目录 前言一、网络IO1、服务器处理并发请求有哪几种方式&#xff1f;2、说一下select&#xff0c;poll&#xff0c;epoll的区别&#xff1f;3、Java 有一种现代的处理方式&#xff0c;属于异步I/O&#xff0c;是什么&#xff1f;redis&#xff0c;nginx&#xff0c;netty 是…

【Zookeeper 和 Kafka】为什么 Zookeeper 不用域名?

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…