Python双向链表、循环链表、栈

一、双向链表

1.作用

双向链表也叫双面链表。

对于单向链表而言。只能通过头节点或者第一个节点出发,单向的访问后继节点,每个节点只能记录其后继节点的信息(位置),不能向前遍历。

所以引入双向链表,双向链表可以保持单向链表特点的基础上,让每个节点,既能向后访问后继节点,也可以向前访问前驱节点。

2.节点和链表类的定义

双向链表的链接域有prior记录前驱节点,next记录后继节点

#定义节点类的类型
class Node:#显性定义出构造函数def __init__(self,data):self.data = data #普通节点的数据域self.next = None #保存下一个节点的链接域self.prior = None #保存前一个节点饿链接域#定义双向链表的类的类型
class DoubleLink:#定义构造函数def __init__(self,node = None):self.head = node #头结点的head初始化为Noneself.size = 0 #链表的初始长度为0

3.双向链表的相关操作(判空、头插、遍历、插入、删除、查找) 

#定义节点类的类型
class Node:#显性定义出构造函数def __init__(self,data):self.data = data #普通节点的数据域self.next = None #保存下一个节点的链接域self.prior = None #保存前一个节点饿链接域#定义双向链表的类的类型
class DoubleLink:#定义构造函数def __init__(self,node = None):self.head = node #头结点的head初始化为Noneself.size = 0 #链表的初始长度为0#判空def is_empty(self):return self.head == None# return self.size == 0#头插def add_head(self,data):#创建出一个新的节点node = Node(data)#判断链表是否为空 分为空和非空情况if self.is_empty():self.head = nodeelse:node.next = self.headself.head.prior = node #node.next.prior = nodeself.head = node#插入成功 链表长度自增self.size += 1#遍历def show(self):#判空if self.is_empty():print("链表为空 遍历失败")else:q = self.headwhile q:print("%d "%(q.data),end = " ")q = q.nextprint()#任意位置插入def add_index(self,idex,data):#判断插入的位置是否合理if idex<1 or idex>self.size+1:print("插入失败")else:#判断插入的位置是否是第一个位置if idex == 1:self.add_head(data)else:#创建新的节点node = Node(data)#找到要插入位置的前一个节点q = self.headi=1while i<idex-1:q = q.nexti+=1# 判断插入的位置是否是最后一个节点if q.next == None:  # 如果为真 则插入的是最后一个位置q.next = nodenode.prior = qelse:  # 说明插入不是最后一个node.next = q.nextnode.prior = qq.next.prior = nodeq.next = node#插入成功 链表长度自增self.size += 1#任意位置删除def del_idex(self,idex):#判空  判断位置是否合理:if self.is_empty() or idex<1 or idex>self.size:print("删除失败")else:#判断删除的是否是第一个节点if idex == 1:self.head = self.head.nextself.head.prior = Noneelse:#判断删除的是否是最后一节节点q = self.headi = 1while i<idex:q = q.nexti+=1if q.next:#删除的不是最后一个节点q.prior.next = q.nextq.next.prior = q.priorelse:#删除的是最后一个q.prior.next = None#删除成功 链表长度自减self.size -= 1#查找节点是否存在 按值def find_node(self,data):#判空if self.is_empty():print("查询失败")else:p = self.headwhile p:if p.data == data:return Truep=p.nextreturn False#测试
if __name__ == "__main__":#创建一个双向链表doubleLink = DoubleLink()#头插doubleLink.add_head(10)doubleLink.add_head(20)doubleLink.add_head(30)doubleLink.add_head(40)doubleLink.add_head(50)#遍历doubleLink.show()#任意位置插入doubleLink.add_index(1,33)doubleLink.show()doubleLink.add_index(3, 999)doubleLink.show()doubleLink.add_index(8, 1111)doubleLink.show()#任意位置删除doubleLink.del_idex(1)doubleLink.show()doubleLink.del_idex(4)doubleLink.show()doubleLink.del_idex(6)doubleLink.show()if(doubleLink.find_node(40)):print("存在")

二、循环链表

1.概念

循环链表:就是首尾相连的链表,通过任意一个节点,都能将整个链表遍历一遍

分类:单向循环链表、双向循环链表

2.单向循环链表

单向循环链表也就是单向链表的最后一个节点的next域不再为None,而是第一个节点

3.单向循环链表的操作(创建、判空、尾插、遍历、删除)

#封装节点的类
class Node:def __init__(self,data):self.data = dataself.next = None#封装单向循环链表类
class LinkList:def __init__(self,node = None):self.size = 0self.head = node#判空def is_empty(self):return self.size == 0#return self.head == None#尾插def add_tail(self,data):#创建一个新的节点node = Node(data)#判空if self.is_empty():self.head = nodenode.next = nodeelse:#找到最后一个节点q = self.headwhile q.next != self.head:q = q.nextq.next = nodenode.next = self.head#链表长度自增self.size += 1#遍历def show(self):#判空if self.is_empty():print("失败")else:#两种: 长度遍历   位置遍历(循环结束 多打印一次)q = self.headwhile q.next != self.head:print("%d"%(q.data),end=" ")q = q.nextprint("%d"%(q.data),end=" ")print()#尾删def del_tail(self):#判空if self.is_empty():print("删除失败")else:#判断长度是否为1  是否只有一个节点if self.size == 1:self.head = Noneelse:q = self.headi=1while i<self.size-1:q = q.nexti+=1q.next = self.head#删除成功 链表长度自减self.size -=1
#测试
if __name__ == "__main__":#创建一个单向循环链表linkList = LinkList()#尾插linkList.add_tail(1)linkList.add_tail(2)linkList.add_tail(3)linkList.add_tail(4)linkList.add_tail(5)#显示linkList.show()#尾删linkList.del_tail()linkList.show()linkList.del_tail()linkList.show()linkList.del_tail()linkList.show()linkList.del_tail()linkList.show()linkList.del_tail()linkList.show()

三、栈

1.概念

栈的概念:操作受限的线性表,对数据的插入和删除操作只能在同一端操作

栈的特点:先进后出(FILO ---->First In Last Out) 、后进先出(LIFO ---->Last In First Out)

栈顶:能够被操作的一端称为栈顶

栈底:不能被操作的一端,称为栈底

种类:顺序栈、链式栈

基本操作:创建栈、判空、入栈、出栈、获取栈顶元素、求栈的大小、遍历栈

2.顺序栈

顺序存储的栈 叫顺序栈

3.顺序栈的操作

#封装一个栈的类
class Stack:def __init__(self):self.data = [] #使用列表来完成顺序栈#判空def is_empty(self):return self.data == []#增加数据def push(self,value):self.data.insert(0,value)#遍历def show(self):for i in self.data:print(i, end=" ")print()#弹出元素 删除def pop(self):#self.data.remove(self.data[0])#self.data.pop(0)del self.data[0]#获取栈顶元素def first_value(self):return self.data[0]#返回栈的大小def size(self):return len(self.data)#测试
if __name__ == "__main__":#创建一个栈stack = Stack()#增加元素stack.push("hello")stack.push("world")stack.push("hello")stack.push("meimei")#遍历stack.show()#删除stack.pop()# 遍历stack.show()num = stack.first_value()print(num)size = stack.size()print(size)

四、自行拓展双向循环链表和链式栈

1.双向循环链表

class Node:def __init__(self,data):self.data=dataself.next=Noneself.prior = Noneclass DoubleCirculateLinklist:def __init__(self):self.size = 0self.head = None# 判空def is_empty(self):return self.size==0# 尾插def add_tail(self, value):node = Node(value)  # 创建新节点if self.is_empty():self.head = node  # 如果链表为空,头结点指向新节点node.next = node  # 新节点指向自己,形成循环node.prior = node  # 新节点的前驱指向自己else:tail = self.head.prior  # 找到当前尾节点tail.next = node  # 当前尾节点的下一个指向新节点node.prior = tail  # 新节点的前驱指向当前尾节点node.next = self.head  # 新节点的后继指向头结点self.head.prior = node  # 头结点的前驱指向新节点self.size += 1  # 链表长度自增#遍历def show(self):if self.is_empty():returnelse:q=self.headwhile True:print(f"{q.data}",end=" ")q=q.nextif q==self.head:breakprint()#尾删def del_tail(self):if self.is_empty():returnelif self.size==1:self.head = Noneelse:tail = self.head.prior  # 找到当前尾节点tail.prior.next = self.head  # 当前尾节点的前一个节点的后继指向头结点self.head.prior = tail.prior  # 头结点的前驱指向当前尾节点的前一个节点self.size -= 1  # 链表长度自减if __name__=='__main__':ls=DoubleCirculateLinklist()ls.add_tail(1)ls.add_tail(2)ls.add_tail(3)ls.show()ls.del_tail()ls.del_tail()ls.show()

2.链式栈

class Node:def __init__(self, data):self.data = data  # 节点的数据域self.next = None  # 指向下一个节点的指针class LinkedStack:def __init__(self):self.top = None  # 栈顶指针self.size = 0    # 栈的大小def is_empty(self):return self.size == 0def push(self, value):new_node = Node(value)  # 创建新节点new_node.next = self.top  # 新节点指向当前栈顶self.top = new_node  # 更新栈顶为新节点self.size += 1  # 栈的大小自增def pop(self):if self.is_empty():print("栈为空,无法出栈")return Nonetop_value = self.top.data  # 获取栈顶元素self.top = self.top.next  # 更新栈顶为下一个节点self.size -= 1  # 栈的大小自减return top_value  # 返回出栈的元素def find_top(self):if self.is_empty():print("栈为空,无法查看栈顶元素")return Nonereturn self.top.data  # 返回栈顶元素def show(self):if self.is_empty():print("栈为空")returnq = self.topwhile q:print(q.data, end=" ")q = q.nextprint()  # 换行# 示例代码
if __name__ == "__main__":stack = LinkedStack()stack.push(10)stack.push(20)stack.push(30)stack.show()  print("栈顶元素:", stack.find_top())  print("出栈元素:", stack.pop())  stack.show() 

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

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

相关文章

【数据结构笔记】习题

渐进分析 【2010-THU-Mid】f(n) O(g(n))&#xff0c;当且仅当g(n) Ω(f(n))。&#xff08;√&#xff09; 【2010-THU-Mid】若f(n) O(n^2)且g(n) O(n)&#xff0c;则以下结论正确的是&#xff08;AD&#xff09; A. f(n) g(n) O(n^2) B. f(n) / g(n) O(n) C. g(n) O(f(…

ES实用面试题

一、es是什么&#xff0c;为什么要用它&#xff1f; ES通常是Elasticsearch的简称&#xff0c;它是一个基于Lucene构建的开源搜索引擎。Elasticsearch以其分布式、高扩展性和实时数据分析能力而闻名&#xff0c;广泛用于全文搜索、日志分析、实时监控等多种场景。 基本特点&am…

适用于学校、医院等低压用电场所的智能安全配电装置

引言 电力&#xff0c;作为一种清洁且高效的能源&#xff0c;极大地促进了现代生活的便捷与舒适。然而&#xff0c;与此同时&#xff0c;因使用不当或维护缺失等问题&#xff0c;漏电、触电事件以及电气火灾频发&#xff0c;对人们的生命安全和财产安全构成了严重威胁&#xf…

智能桥梁安全运行监测系统守护桥梁安全卫士

一、方案背景 桥梁作为交通基础设施中不可或缺的重要组成部分&#xff0c;其安全稳定的运行直接关联到广大人民群众的生命财产安全以及整个社会的稳定与和谐。桥梁不仅是连接两地的通道&#xff0c;更是经济发展和社会进步的重要纽带。为了确保桥梁的安全运行&#xff0c;桥梁安…

【Python爬虫五十个小案例】爬取豆瓣电影Top250

博客主页&#xff1a;小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介&#xff1a;分享五十个Python爬虫小案例 &#x1fab2;前言 在这篇博客中&#xff0c;我们将学习如何使用Python爬取豆瓣电影Top250的数据。我们将使用requests库来发送HTTP请求&#xff0c;…

Java基础 设计模式——针对实习面试

目录 Java基础 设计模式单例模式工厂模式观察者模式策略模式装饰器模式其他设计模式 Java基础 设计模式 单例模式 单例模式&#xff08;Singleton Pattern&#xff09; 定义&#xff1a;确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问这个实例。适用场景&…

PGSQL学习笔记 -- 从入门到放弃

pgsq学习笔记 一、基本语法&#xff08;一&#xff09;增删改查&#xff08;二&#xff09;PostgreSQL 语法详细介绍及示例 二、数据类型&#xff08;一&#xff09;基本数据类型&#xff08;二&#xff09;复合类型&#xff08;三&#xff09;JSON 和 XML 数据类型&#xff08…

P1198 [JSOI2008] 最大数

P1198 [JSOI2008] 最大数https://www.luogu.com.cn/problem/P1198 牵制芝士&#xff1a;单调队列 思路&#xff1a; 我们的任务是找出一个区间最大值的 因为插入的数与上一次的答案有关 所以它是强制在线的&#xff08;真无语了&#xff09; 我们可以在每次插入时整一个叫…

【C++】入门【一】

本节目标 一、C关键字&#xff08;C98&#xff09; 二、命名空间 三、C的输入输出 四、缺省函数 五、函数重载 六、引用 七、内联函数 八、auto关键字&#xff08;C11&#xff09; 九、范围for&#xff08;C11&#xff09; 十、指针空值nullptr&#xff08;C11&#xff09; 一.…

RabbitMQ7:消息转换器

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

微知-lspci访问到指定的PCIe设备的几种方式?(lspci -s bus;lspci -d devices)

通过bdf号查看 -s &#xff08;bus&#xff09; lspci -s 03:00.0通过vendor id或者device id等设备查看 -d &#xff08;device&#xff09; lspci -d 15b3: #这里是vendor号&#xff0c;所以在前面 lspci -d :1021 #这里是设备号&#xff0c;所以要:在前vendorid和deviceid…

基于Matlab深度学习的CT影像识别系统研究与实现

通过使用AlexNet、GoogLeNet和VGGNet等预训练模型&#xff0c;并结合迁移学习技术&#xff0c;对CT影像进行特征提取和分类。系统在公开数据集上进行了训练和测试&#xff0c;结果表明&#xff0c;该方法能够有效区分COVID-19和非COVID-19的CT影像&#xff0c;具有较高的准确率…

操作系统 锁——针对实习面试

目录 操作系统 锁什么是死锁&#xff1f;说说死锁产生的条件&#xff1f;死锁如何预防&#xff1f;死锁如何避免&#xff1f;银行家算法具体怎么操作&#xff1f;死锁如何解决&#xff1f;死锁会产生什么影响&#xff1f;乐观锁与悲观锁有什么区别&#xff1f; 操作系统 锁 什么…

【NLP 1、人工智能与NLP简介】

人人都不看好你&#xff0c;可偏偏你最争气 —— 24.11.26 一、AI和NLP的基本介绍 1.人工智能发展流程 弱人工智能 ——> 强人工智能 ——> 超人工智能 ① 弱人工智能 人工智能算法只能在限定领域解决特定的问题 eg&#xff1a;特定场景下的文本分类、垂直领域下的对…

C#结构体排序(数组)

结构体排序&#xff08;数组&#xff09; 1 示例1.1 以PointF为例展示效果1.2 运行结果展示 2实际运用2.1 创建结构体2.2 调用示例2.3 运行结果展示 1 示例 1.1 以PointF为例展示效果 private void button1_Click(object sender, EventArgs e) {Random random new Random();…

搭建AI知识库:打造坚实的团队知识堡垒

在信息爆炸的时代&#xff0c;企业面临着知识管理的挑战。团队知识堡垒的构建&#xff0c;即搭建一个高效的AI知识库&#xff0c;对于保护和利用知识资产、提升团队协作效率和创新能力至关重要。本文将探讨搭建AI知识库的重要性、策略以及如何通过这一系统打造坚实的团队知识堡…

(五)Ubuntu22.04+Stable-Diffusion-webui AI绘画 模型转换插件安装及其使用

一、说明 这是秋叶大佬开发的一个模型转换插件&#xff0c;秋叶整合包中自带。如果你的 Stable Diffusion WebUI 中没有这个插件&#xff0c;请使用下面这个地址安装&#xff0c;安装完成之后别忘了重启 WebUI。 模型转换插件 https://github.com/Akegarasu/sd-webui-model-c…

DevExpress的web Dashboard应用

本文旨在从零开始创建一个包含dashboard的应用 一、前期准备 1、语言&#xff1a;C# 2、软件&#xff1a;Visual Studio 2019 3、框架&#xff1a;DevExpress19.2(付费)、ASP.NET(Web) 4、组件&#xff1a;dashboard 二、创建ASP.NET Web窗体仪表板应用程序 1、创建一个空的w…

记录下在html文件中如何直接使用npm依赖,以threejs为例

参考&#xff1a; https://www.cnblogs.com/shayloyuki/p/17191489.html 共三种方式 我的代码截图 方式一&#xff1a; threejsDemo_script.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&…

鸿蒙面试 --- 性能优化

性能优化可以从三个方面入手 感知流畅、渲染性能、运行性能 感知流畅 在应用开发中&#xff0c;动画可以为用户界面增添生动、流畅的交互效果&#xff0c;提升用户对应用的好感度。然而&#xff0c;滥用动画也会导致应用性能下降&#xff0c;消耗过多的系统资源&#xff0c;…