python--数据结构--链表

最近会更新很多内容,感兴趣的友友支持一下吧!!

一、链表介绍

概述:

属于线性结构, 即: 每个节点都有1个父节点(前驱节点) 和 1个子节点(后继节点)

链表可以看做是 用链条(一根绳) 把节点连接起来的 一种结构.

节点介绍(此处以 单链表举例):

由 元素域(数值域) 和 地址域(链接域)组成, 其中 数值域存储的是 数值, 地址域存储的是 下个节点的地址.

链表根据节点不同, 分类如下:

单向链表:

每个节点由 1个数值域和1个地址域组成, 且每个节点的地址域指向下个节点的地址. 最后1个节点的地址域为: None

单向循环链表:

每个节点由 1个数值域和1个地址域组成, 且每个节点的地址域指向下个节点的地址. 最后1个节点的地址域为: 第1个节点的地址

双向链表:

每个节点由 1个数值域和2个地址域组成, 且每个节点的地址域分别指向前1个节点的地址 和 后1个节点的地址.

第1个节点的(前)地址域为: None, 最后1个节点的(后)地址域为: None

双向循环链表:

每个节点由 1个数值域和2个地址域组成, 且每个节点的地址域分别指向前1个节点的地址 和 后1个节点的地址.

第1个节点的(前)地址域为: 最后1个节点的地址, 最后1个节点的(后)地址域为: 第1个节点的地址.

二、案例:

自定义代码, 模拟(单向)链表.

分析:

节点类: SingleNode

属性:

item 表示: 数值域

next 表示: 地址域, 即: 指向下个节点的地址的.

链表类: SingleLinkedList

属性:

head 表示: 头结点, 即: 默认指向链表第1个节点的 地址.

函数:

is_empty(self) 链表是否为空

length(self) 链表长度

travel(self. ) 遍历整个链表

add(self, item) 链表头部添加元素

append(self, item) 链表尾部添加元素

insert(self, pos, item) 指定位置添加元素

remove(self, item) 删除节点

search(self, item) 查找节点是否存在

示例代码:

# 1. 定义SingleNode, 表示: 节点类. class SingleNode(object): # 1.1 初始化节点的属性. def __init__(self, item): # 1.2 接收由用户传入的: 数值, 放到数值域中. self.item = item # 1.3 地址域默认为: None self.next = None # 2. 定义SingleLinkedList, 表示: 链表类. class SingleLinkedList(object): # 2.1 初始化链表的属性. def __init__(self, head=None): # 2.2 默认: 头结点为: None self.head = head # 2.2 is_empty(self) 链表是否为空 def is_empty(self): # 判断依据: 头结点head是否为None # 写法1: if方式 # if self.head is None: # return True # 链表为空 # else: # return False # 链表不为空 # 写法2: 三元表达式 # return True if self.head is None else False # 写法3: 直接返回即可. # return self.head == None return self.head is None # 2.3 length(self) 链表长度 def length(self): # 1. 定义变量count, 记录: 链表长度. count = 0 # 2. 定义变量cur, 表示: 当前的节点, 初值为: 头结点. cur = self.head # 3. 判断当前节点是否为空, 不为空就一直遍历. while cur is not None: # 4. 走到这里, 说明当前节点不为空, 就: 计数器 + 1, 然后设置当前节点为它的下个节点. count += 1 cur = cur.next # 5. 返回结果(链表的长度). return count # 2.4 travel(self ) 遍历整个链表 def travel(self): # 1. 定义变量cur, 表示: 当前的节点, 初值为: 头结点. cur = self.head # 2. 判断当前节点是否为空, 不为空就一直遍历. while cur is not None: # 3. 走到这里, 说明当前节点不为空. print(cur.item) # 打印当前节点的 数值域 cur = cur.next # 设置当前节点为它的下个节点. # 2.5 add(self, item) 链表头部添加元素 def add(self, item): # 1. 把传入的item(元素值)封装成: 节点 new_node = SingleNode(item) # 2. 设置新节点的 地址域为: 头结点. new_node.next = self.head # 3. 设置新节点为: 新的头结点. self.head = new_node # 2.6 append(self, item) 链表尾部添加元素 def append(self, item): # 1.把要添加的元素值封装成: 节点. new_node = SingleNode(item) # 2. 判断当前链表是否为空. if self.is_empty(): # 3. 走到这里, 说明链表为空, 直接设置新节点为: 头结点即可. self.head = new_node else: # 4. 走到这里, 说明链表不为空, 需找到最后1个节点. cur = self.head # 设置当前节点为: 头结点. # 5. 只要当前节点的地址域不为空, 就说明还有下个节点, 就一直遍历即可. while cur.next is not None: # 当前节点不为空, 继续往下找. cur = cur.next # 6. 走到这里, 说明cur的下个节点为空, 即: cur已经为最后1个节点了. # 设置最后1个节点(cur)的地址域为: 新的节点. cur.next = new_node # 2.7 insert(self, pos, item) 指定位置添加元素 def insert(self, pos, item): # 1. 判断pos(要插入的位置)是否合法. if pos <= 0: # 往头部添加. self.add(item) elif pos >= self.length(): # 往尾部添加 self.append(item) else: # 2. 走到这里, 说明pos是合法位置, 即: 链表的中间位置. # 解题核心: 找到要插入的位置的前边那个节点, 即: pos - 1位置的那个节点. # 3. 定义变量cur, 表示: 要插入的位置前 那个节点. cur = self.head # 4. 定义变量count, 表示: 要插入的位置前 那个节点的 索引. count = 0 # 5. 只要cur不是要插入节点 前一个节点, 就一直遍历. while count < pos - 1: # 如果不减1, 拿的是插入后. pos位置后的哪个元素. # 走到这里, 说明cur不是要找的元素, 就继续往后找. cur = cur.next # 计数器 要 + 1 count += 1 # 6. 走到这里, 说明cur就是 要插入位置前的那个节点. # 先设置 新节点的地址域为: cur节点的地址域 new_node = SingleNode(item) new_node.next = cur.next # 再设置 cur节点的地址域为: 新节点 cur.next = new_node # 2.8 remove(self, item) 删除节点 def remove(self, item): # 1. 定义变量, 表示: 要被删除的元素. cur = self.head # 从头结点往后找. # 2. 定义变量, 表示: 要被删除的节点的 前1个节点. pre = None # 初值为None # 3. 具体的判断动作, 只要当前节点不为空, 就一直遍历. while cur is not None: # 4. 判断当前节点是否是要被删除的节点. if cur.item == item: # 走这里, 说明cur就是要被删除的节点. # 5. 判断cur是否是头结点, 如果是头结点, 直接设置它的地址域 为 新的头结点即可. if cur == self.head: self.head = cur.next else: # 6. 走这里, 说明cur不是头结点, 设置它的前1个节点的地址域 = cur的地址域即可. pre.next = cur.next # 7. 删完以后, 记得: break break else: # 8. 走这里, 说明cur不是要被删除的节点, 我们继续往下找. pre = cur # 当前节点已经是: 要被删除的节点的 前1个节点了 cur = cur.next # 当前节点变更为: 它的下个节点. # 2.9 search(self, item) 查找节点是否存在 def search(self, item): # 1. 定义变量cur, 表示: 当前节点, 默认从头结点开始. cur = self.head # 2. 判断当前节点是否为空, 不为空就一直遍历. while cur is not None: # 3. 判断当前节点的 元素域 是否和 要查找的元素值相同. if cur.item == item: # 4. 走这里, 找到了, return True即可. return True # 5. 走到这里, 说明当前节点不是我们要的, 继续往下找. cur = cur.next # 6. 走到这里, 说明 没找到, return False即可. return False # 3. 在main方法中测试 if __name__ == '__main__': # 3.1 测试 节点类. node1 = SingleNode('乔峰') print(node1) # 地址: <__main__.SingleNode object at 0x0000015D0D48C5C0> # 3.2 打印该节点的属性 print(node1.item) # 数值域, 乔峰 print(node1.next) # 地址域, None print('-' * 21) # 3.2 测试 链表类 linkedlist1 = SingleLinkedList() # 空链表. print(linkedlist1.head) # 打印链表的: 头结点 print('-' * 21) linkedlist2 = SingleLinkedList(node1) # 打印链表的: 头结点, 这里是: node1节点, <__main__.SingleNode object at 0x0000015D0D48C5C0> print(linkedlist2.head) print(linkedlist2.head.item) # 打印 头结点的 数值域, 乔峰 print(linkedlist2.head.next) # 打印 头结点的 地址域, None print('-' * 21) # 3.3 测试链表的方法: add() linkedlist2.add('虚竹') linkedlist2.add('段誉') # 3.4 测试链表的方法: append() linkedlist2.append('王语嫣') linkedlist2.append('李清露') # 3.5 测试链表的方法: insert() linkedlist2.insert(-2, '鸠摩智') linkedlist2.insert(20, '慕容复') linkedlist2.insert(3, '丁春秋') # 3.6 测试链表的方法: remove() linkedlist2.remove('乔峰') linkedlist2.remove('鸠摩智') # 3.7 测试链表的方法: search() print(linkedlist2.search('慕容复')) print(linkedlist2.search('鸠摩智')) print('#' * 21) # 3.8 测试链表的方法: is_empty() print(linkedlist1.is_empty()) print(linkedlist2.is_empty()) # 3.9 测试链表的方法: length() len1 = linkedlist1.length() len2 = linkedlist2.length() print(f'len1: {len1}') # 0 print(f'len2: {len2}') # 1 print('-' * 21) # 3.10 测试链表的方法: travel() linkedlist2.travel() # 鸠摩智, 段誉, 虚竹, 丁春秋, 乔峰, 王语嫣, 李清露, 慕容复

运行结果:

<__main__.SingleNode object at 0x00000125ED554FE0>
乔峰
None
---------------------
None
---------------------
<__main__.SingleNode object at 0x00000125ED554FE0>
乔峰
None
---------------------
True
False
#####################
True
False
len1: 0
len2: 6
---------------------
段誉
虚竹
丁春秋
王语嫣
李清露
慕容复

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

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

相关文章

【计算机毕业设计案例】深度学习基于python的手势识别数字

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

2027年80%平台将出局?数藏行业合规化与技术革命双轨突围指南

引言&#xff1a;当数字藏品陷入“信任危机”2025年&#xff0c;数字藏品市场迎来关键转折点。一方面&#xff0c;全球市场规模突破千亿美元&#xff0c;中国用户规模超2亿&#xff1b;另一方面&#xff0c;行业乱象频发&#xff1a;某头部平台因二级市场炒作被立案调查&#x…

原理:XinServer 是如何实现开箱即用的后端服务的?

原理&#xff1a;XinServer 是如何实现开箱即用的后端服务的&#xff1f; 不知道你有没有过这种经历&#xff1a;产品经理或者客户拿着一个原型图过来&#xff0c;说“咱们这个App/小程序/管理后台&#xff0c;下个月能上线吗&#xff1f;”你一看&#xff0c;好家伙&#xff0…

音乐喷泉博途V14与MCGS7.7触摸屏程序资料包2:探索奇妙的喷泉世界

音乐喷泉博途v14和mcgs7.7触摸屏程序资料包2&#xff0c;带运行效果视频&#xff0c;流程图和io表最近在研究自动化控制项目时&#xff0c;发现了一款超有趣的资料包——音乐喷泉博途V14和MCGS7.7触摸屏程序资料包2 &#xff0c;还附带运行效果视频、流程图以及IO表&#xff0c…

Python---多线程相关内容

最近会更新很多内容,感兴趣的友友点个关注,支持一下博主吧! 一、线程基本内容 概述: 线程是CPU调度资源的最基本单位, 进程是CPU分配资源的基本单位. 进程 = 可执行程序, 文件. 即: *.exe = 进程, 微信, QQ都是进程. 线程 = 进程的执行路径, 执行单元. 微信这个进程, 可以…

【程序员必看】RAG技术天花板被打破!AutoRefine让大模型学会“思考式检索“,代码开源,小白也能上手!

背景 大语言模型的推理能力受限于训练数据的质量和覆盖范围&#xff0c;检索增强生成&#xff08;RAG&#xff09;技术应运而生&#xff1a;让模型在回答时调用外部知识库&#xff0c;弥补相关知识缺口。但现有RAG方法存在两个关键问题&#xff1a; 噪音干扰&#xff1a;检索…

黑客、骇客、白客、红客终极指南:四大角色工作全揭秘,收藏这篇就够了!

黑客 起源 “黑客”一词是英文Hacker的音译。这个词早在莎士比亚时代就已存在了&#xff0c;但是人们第一次真正理解它时&#xff0c;却是在计算机问世之后。根据《牛津英语词典》解释&#xff0c;“hack”一词最早的意思是劈砍&#xff0c;而这个词意很容易使人联想到计算机…

JavaScript作用域全解析:前端新人不再被变量“捉迷藏”搞晕(附实战

JavaScript作用域全解析&#xff1a;前端新人不再被变量“捉迷藏”搞晕&#xff08;附实战 JavaScript作用域全解析&#xff1a;前端新人不再被变量“捉迷藏”搞晕&#xff08;附实战技巧&#xff09;引言&#xff1a;变量到底藏哪儿了&#xff1f;JavaScript作用域初印象&…

吐血推荐8个AI论文平台,助你轻松搞定本科毕业论文!

吐血推荐8个AI论文平台&#xff0c;助你轻松搞定本科毕业论文&#xff01; AI 工具助力论文写作&#xff0c;轻松应对学术挑战 对于正在撰写本科毕业论文的同学们来说&#xff0c;时间紧、任务重是常态。从选题到开题&#xff0c;再到撰写初稿和反复修改&#xff0c;每一个环节…

震惊!14B小模型吊打72B大模型,MiA-RAG让AI从“盲人摸象“到“全局视野“

引言&#xff1a;RAG的困境 在2025年&#xff0c;RAG&#xff08;检索增强生成&#xff09;已经成为大模型应用的标配技术。 从视频理解到文档问答&#xff0c;从知识库检索到Agent系统&#xff0c;RAG无处不在。 但当我们把RAG用在真正复杂的长文本场景时&#xff0c;会发现…

网络安全从入门到进阶:快速掌握核心技术与防御体系

1 TCP/IP 模型基础 OSI参考模型 OSI(Open System Interconnect Reference Model)&#xff0c;开放式系统互联参考模型&#xff0c;它是由 国际标准化组织 ISO 提出的一个网络系统互连模型。 OSI 模型的设计目的是成为一个所有销售商都能实现的开放网络模型&#xff0c;来克服…

深度学习毕设项目推荐-基于python深度学习的手势识别数字

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

光伏逆变器并网Matlab/Simulink仿真模型探索

光伏逆变器并网matlab/simiulink仿真模型 有参考lun文和模型说明 利用MATLAB搭建光伏并网模型验证逆变控制策略的可行性。 对仿真结果进行优化&#xff0c;LCL 滤波器消除逆变时引起的谐波分量&#xff0c;使谐波畸变率THD低于5%。 实现控制响应既快速高效&#xff0c;又可以提…

6.面向对象初级

类与对象的概述1.类的定义&#xff1a;类是抽象的概念的&#xff0c;代表一类事物&#xff08;比如人类&#xff0c;猫类&#xff09;&#xff0c;本质是一种数据类型&#xff0c;类将这一类对象所共有的属性和行为进行定义&#xff08;比如猫都有名字&#xff0c;颜色&#xf…

Burp Suite插件 | AI连接本地工具、数据库或远程 Agent,辅助安全测试

工具介绍 BurpAgent 将大语言模型 (LLM) 和 MCP (Model Context Protocol) 引入 Burp Suite&#xff0c;使其能够连接本地工具、数据库或远程 Agent&#xff0c;辅助安全测试。工具功能 1. 流量分析 利用 GPT-4/DeepSeek 等模型对 HTTP 请求/响应进行分析。支持自定义 Prompt 模…

万字长文,全面解析“黑、骇、白、红”客:他们的技术与使命

黑客 起源 “黑客”一词是英文Hacker的音译。这个词早在莎士比亚时代就已存在了&#xff0c;但是人们第一次真正理解它时&#xff0c;却是在计算机问世之后。根据《牛津英语词典》解释&#xff0c;“hack”一词最早的意思是劈砍&#xff0c;而这个词意很容易使人联想到计算机…

强烈安利专科生必用TOP10 AI论文平台

强烈安利专科生必用TOP10 AI论文平台 专科生论文写作的“好帮手”怎么选&#xff1f; 随着AI技术在教育领域的不断渗透&#xff0c;越来越多的专科生开始借助AI工具提升论文写作效率。然而面对市场上五花八门的平台&#xff0c;如何选择真正适合自己的成了难题。为此&#xff0…

在同一局域网下,使用ssh命令进行文件传输

文章目录目标步骤目标 操作本电脑&#xff0c;将另外一台电脑上面的文件通过ssh远程传输到本电脑上。 步骤 1.首先需要知道本设备和另一台设备的ip地址和用户名称。 比如本电脑的用户名&#xff1a;home&#xff1b;ip&#xff1a;192.168.1.1 另外一台电脑的用户名&#xf…

yolo11_yolov8_opencv 使用yolo11和yolov8分别训练混凝土裂缝检测数据集 建立基于深度学习YOLOV8_11框架混凝土缺陷检测系统

深度学习框架混凝土裂缝检测系统&#xff0c;yolo11/yolov8/opencv使用yolo11和yolov8分别训练&#xff0c;数据集图片7998张(其中训练集5998 75%,验证集1500 19%,测试集500 6%),已经训练好了&#xff0c;也可以自己重新训练&#xff0c;使用opencv&#xff0c;thinter构建的gu…