当前位置: 首页 > news >正文

Python数据结构(链表)

Python数据结构(链表)

单向链表

单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。

image-20231017180640208

表元素域elem用来存放具体的数据
链接域next用来存放下一个节点的位置(python中的标识)
变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点

节点实现
class node(object):def __init__(self,item):# __item存放的是数据元素self.item = item# __next是下一个节点的表示self.next = None
单链表的操作
class node(object):def __init__(self,item):# __item存放的是数据元素self.item = item# __next是下一个节点的表示self.next = Noneclass SingleLinkList(object):def __init__(self,node=None):self.head = node # 定义头节点,默认值为Nodedef is_empty(): #链表是否为空return self.head == None:def length(): #链表长度cur = self.head #cur游标表当前的节点,用来移动遍历节点count = 0while cur != None:count += 1cur = cur.nextreturn countdef travel(): #遍历整个链表cur = self.headwhile cur != None:print(cur.item, end=" ")cur = cur.nextprint("")def get_all(self):#查找整个链表数据cur = self.headres = []while True:#遍历整个链表,并转成列表形式if cur.next == None:if cur.item:res.append(cur.item)breakelse:if cur.item:res.append(cur.item)cur = cur.nextreturn resdef reverse_printing(self):res = self.get_all()#获取列表形式所有链表数据ret =res[::-1]#反转列表return retdef reverse(self):#反转链表res = self.reverse_printing()#获取逆序的列表形式链表sign1 = self.head#创建游标while True:#遍历整个链表,断开各连接,没有指向的数据会被垃圾回收if sign1.next == None:breaksign2 = sign1.nextsign1.next = Nonesign1 = sign2sign = self.headfor ele in res:#根据逆序列表形式链表,重新构建链表body = Item(ele)sign.next = bodysign = sign.nextdef ReverseList(self): #反转链表            cur = self.head         pre = None              while cur:              nextNode = cur.next cur.next = pre      pre = cur           cur = nextNode      return pre              def add(item): #链表头部添加元素,头插法node = Node(item)node.next = self.headself.head = nodedef append(item): #链表尾部添加元素,尾插法node = Node(item)if self.is_empty():self.head = nodeelse:cur = self.headwhile cur.next != None:cur = cur.nextcur.next = nodedef insert(pos,item): #指定位置添加元素if pos <= 0:self.add(item)elif pos > (self.length()-1):self.append(item)else:pre = self.headcount = 0while count < (pos-1):count += 1pre = pre.next# 当循环退出后,pre指向pos-1的位置node = Node(item)node.next = pre.nextpre.next = nodedef remove(item): #删除节点# 双指针cur = self.headpre = Nonewhile cur != None:if cur.item == item:# 先判断此节点是否为头结点if cur == self.head:self.head = cur.nextelse:pre.next = cur.nextbreakelse:pre = curcur = cur.next# 单指针pre = self.headwhile pre != None:if pre.next.item == item:if pre == self.head:self.head = pre.nextelse:pre.next = pre.next.nextbreakelse:pre = pre.nexdef search(item): #查找节点是否存在cur = self.headwhile cur != None:if cur.item == item:return Trueelse:cur = cur.nextreturn False
链表与顺序表的对比

链表失去了顺序表随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大,但对存储空间的使用要相对灵活。
链表与顺序表的各种操作复杂度如下所示:

操作链表顺序表
访问元素O(n)O(1)
在头部插入/删除O(1)O(n)
在尾部插入/删除O(n)O(1)
在中间插入/删除O(n)O(n)

注意虽然表面看起来复杂度都是 O(n),但是链表和顺序表在插入和删除时进行的是完全不同的操作。链表的主要耗时操作是遍历查找,删除和插入操作本身的复杂度是O(1)。顺序表查找很快,主要耗时的操作是拷贝覆盖。因为除了目标元素在尾部的特殊情况,顺序表进行插入和删除时需要对操作点之后的所有元素进行前后移位操作,只能通过拷贝和覆盖的方法进行。

单向循环链表

单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点

image-20231018162154478

操作
class Node(object):def __init__(self,item):self.item = itemself.next = Node
class SingleCycleLinkList(object): #单向循环链表def __init__(self,node=Node):self.head = node# 定义头节点if node:node.next = nodedef is_empty(self): #判空return self.head = Nonedef length(self): #链表长度if self.is_empty():return 0cur = self.headcount = 1while cur.next != self.head:count += 1cur = cur.nextreturn countdef travel(self): #遍历链表if self.is_empty():returncur = self.headwhile cur.next != self.next:print(cur.item, end=' -> ')cur = cur.nextprint(cur.item) #尾节点不能进入循环所以要出循环后打印出来def add(self,item): #头插法node = Node(item)if self.is_empty():self.head = nodenode.next = nodeelse:cur = self.headwhile cur.next != self.head:cur = cur.next#退出循环后cur指向尾节点node.next = self.headself.head = nodecur.next = self.head #cur.next = nodedef append(self,item): #尾插法node = Node(item)if self.is_empty():self.head = nodenode.next = nodeelse:cur = self.headwhile cur.next != self.head:cur =cur.nextnode.next = self.headcur.next = nodedef insert(self,pos,item): #在指定位置插入元素if pos < 0:self.add(item)elif pos > (self.length()-1):self.append(item)else:pre = self.headcount = 0while count < (pos-1):count += 1pre = pre.nextnode = Node(item)node.next = pre.nextpre.next = nodedef remove(self,item): #删除节点cur = self.headpre = Nonewhile cur.next != self.head:if cur.item == item;#判断此节点是否为头结点if cur == sef.head:#删除是头结点的情况先找到尾节点rear = self.headwhile rear.next != self.head:rear = rear.nextself.head = cur.nextrear.next = self.headelse:#中间节点pre.next = cur.nextreturnelse:pre = curcur = cur.next#退出循环,cur指向尾节点       if cur.item == item:if cur == self.head:#链表只有一个节点的情况self.head = Noneelse:pre.next = cur.nextdef search(self,item): #查找节点if self.is_empty():return Falsecur = self.headwhile cur.next= self.head:if cur.item = item:return Trueelse:cur = cur.next#退出循环,cur指向尾节点if cur.item == item:return Truereturn False

双向链表

一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值,而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。

image-20231018184234093

操作
class Node(object): #应为前几个方法与单链表都一样用面向对象的思想可以把单链表中的类继承过来"""双链表的节点"""def __init__(self, item):self.item = itemself.next = Noneself.prev = Nonedef is_empty(): #链表是否为空return self.head == None:def length(): #链表长度cur = self.head #cur游标表当前的节点,用来移动遍历节点count = 0while cur != None:count += 1cur = cur.nextreturn countdef travel(): #遍历整个链表cur = self.headwhile cur != None:print(cur.item, end=" ")cur = cur.nextprint("")def add(item): #链表头部添加元素,头插法node = Node(item)node.next = self.headself.head.prev = nodeself.head = nodedef append(item): #链表尾部添加元素,尾插法node = Node(item)if self.is_empty():self.head = nodeelse:cur = self.headwhile cur.next != None:cur = cur.nextcur.next = nodenode.prev = curdef insert(pos,item): #指定位置添加元素if pos <= 0:self.add(item)elif pos > (self.length()-1):self.append(item)else:cur = self.headcount = 0while count < pos:count += 1cur = cur.next# 当循环退出后,cur指向pos的位置node = Node(item)node.next = curnode.prev = cur.prevcur.prev.next = nodecur.prev = nodedef remove(item): #删除节点cur = self.headwhile cur != None:if cur.item == item:if cur == self.head:self.head = cur.nextif cur.next: #判断链表是否只有一个节点cur.next.prev = Noneelse:cur.prev.next = cur.nextif cur.next:cur.next.prev = cur.prevbreakelse:cur = cur.nexdef search(item): #查找节点是否存在cur = self.headwhile cur != None:if cur.item == item:return Trueelse:cur = cur.nextreturn False

相关文章:

Python数据结构(链表)

Python数据结构&#xff08;链表&#xff09; 单向链表 单向链表也叫单链表&#xff0c;是链表中最简单的一种形式&#xff0c;它的每个节点包含两个域&#xff0c;一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点&#xff0c;而最后一个节点的链接域则指向…...

连续/离散的控制系统阶跃测试(包括MATLAB里的step()函数)

阶跃测试 只要是连续时间系统&#xff0c;无论是传递函数还是连续状态空间形式的模型&#xff0c;直接可以用**step()**做阶跃测试&#xff1b;但是对于离散系统而言&#xff0c;不能用step()函数&#xff0c;可以自行编写代码&#xff0c;如下。 1、离散系统&#xff1a;x(k…...

【六:pytest框架介绍】

常见的请求对象requests.get()requests.post()requests.delete()requests.put()requests.request()常见的响应对象reprequests.request()//返回字符串格式数据print(req.text)//返回字节格式数据print(req.content)//返回字典格式数据print(req.json)#状态码print(req.status_c…...

提升医院安全的关键利器——医院安全(不良)事件报告系统源码

医院是人们寻求医疗服务和康复的场所&#xff0c;安全是医院运营的基石。然而&#xff0c;医疗过程中不可避免地会出现不良事件&#xff0c;如药物错误、手术事故等。为了及时发现、评估和解决这些问题&#xff0c;医院安全&#xff08;不良&#xff09;事件报告系统应运而生。…...

【瑞吉外卖部分功能补充】

瑞吉外卖部分功能补充 菜品的启售和停售 在浏览器控制台点击对应功能后可以看到前端发送的请求是&#xff1a;http://localhost:9999/dish/status/1?ids1413342036832100354&#xff0c;请求方式为POST。 接收到前端参数后&#xff0c;进行controller层代码补全&#xff0c…...

react的setState做了什么

1、为什么需要setState setState的作用是帮助我们更改数据的同时并且通知视图进行渲染。因为React并不会绑定视图和state&#xff0c;需要我们手动去更新视图。 2、setState什么时候是同步的&#xff0c;什么时候是异步的 setState这个方法在调用的时候是同步的&#xff0c;…...

ubuntu18.04 RTX3060 rangnet++训练 bonnetal语义分割

代码链接&#xff1a; https://github.com/PRBonn/lidar-bonnetal 安装anaconda环境为 CUDA 11.0&#xff08;11.1也可以&#xff09; anaconda环境如下 numpy1.17.2 torchvision0.2.2 matplotlib2.2.3 tensorflow1.13.1 scipy0.19.1 pytorch1.7.1 vispy0.5.3 opencv_python…...

Linux:权限是什么

本篇文章来简单介绍一下Linux操作系统中权限的基本概念和一些操作方法&#xff0c;对Linux权限有一个基本的了解&#xff0c;希望对大家学习Linux有所帮助。 目录 1.权限的概念 2.Linux权限管理 2.1 文件访问者的分类 2.2 文件类型与访问权限&#xff08;事物属性&#xff…...

uni-app yrkDataPicker 日期和时间选择控件

uni-app 选择日期时间控件有 2 月份有 31 天的问题&#xff0c;一直没有修复&#xff0c;uni-calendar 苹果有选择年份和月份后无法显示问题。自己写了一个&#xff0c;只支持 H5 和微信小程序&#xff0c;其他没有试过。 <template><view class"yrk-data-picke…...

PAM从入门到精通(十九)

接前一篇文章&#xff1a;PAM从入门到精通&#xff08;十八&#xff09; 本文参考&#xff1a; 《The Linux-PAM Application Developers Guide》 PAM 的应用开发和内部实现源码分析 先再来重温一下PAM系统架构&#xff1a; 更加形象的形式&#xff1a; 六、整体流程示例 2.…...

apache httpd 多后缀解析漏洞

形成原因 Apache HTTPD 支持一个文件拥有多个后缀&#xff0c;并为不同后缀执行不同的指令 在有多个后缀的情况下&#xff0c;只要一个文件含有.php后缀的文件即将被识别成PHP文件&#xff0c;没必要是最后一个后缀。利用这个特性&#xff0c;将会造成一个可以绕过上传白名单…...

Flutter ☞ 数据类型

数值类型 int、double、num int 整型&#xff0c;取值通常在 -253 ~ 253 之间 int class double 64-bt(双精度)浮点数&#xff0c;符合 IEEE 754 标准。 double class num 数值类型的基类&#xff0c;int 和 double 都继承自num。 num class 数值转换 // String -> …...

MyBatis-Plus 实战教程一

这里写目录标题 简介快速上手数据库建立创建实体类修改参数引入依赖测试常见注解介绍TableNameTableIdTableField 常见配置仓库地址 简介 MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;…...

闭包(函数)

把内部函数通过return扔出去 必要条件...

Go包介绍与初始化:搞清Go程序的执行次序

Go包介绍与初始化&#xff1a;搞清Go程序的执行次序 文章目录 Go包介绍与初始化&#xff1a;搞清Go程序的执行次序一、main.main 函数&#xff1a;Go 应用的入口函数1.1 main.main 函数1.2 main.main 函数特点 二、包介绍2.1 包介绍与声明2.2 非 main包的 main 函数2.3 包的命名…...

Python教程(15)——Python流程控制语句详解

目录 if语句else if语句for循环遍历类型range关键字 while循环break语句continue语句 Python流程控制是Python编程中非常重要的一部分&#xff0c;它用于控制程序的执行流程。Python提供了多种流程控制语句&#xff0c;包括if语句、while循环、for循环、break和continue语句等。…...

JavaScript基础知识16——分支语句

哈喽&#xff0c;大家好&#xff0c;我是雷工。 今天学习JavaScript基础知识的分支语句&#xff0c;以下为学习笔记。 1、程序三大流程控制语句 ○写几句就从上往下执行几句&#xff0c;这种叫做顺序结构&#xff1b; ○有时要根据条件选择执行代码&#xff0c;这种叫分支结构…...

web开发初级工程师学习笔记

web开发初级工程师学习笔记 前端开发工具实验1 VS Code 初体验介绍 前端开发工具 实验1 VS Code 初体验 介绍 VS Code 环境提供的是一个可以在浏览器中使用原生 VS Code 编辑代码的程序。在该环境中&#xff0c;你可以使用到与本地安装近乎一致的 VS Code 程序来编辑代码文件…...

Linux下Samba服务安装及启用全攻略

Linux下Samba服务安装及启用全攻略 前言一、安装SSH Server二、安装Samba Server1.安装net-tool2.建立账号的samba3.windows通过Samba与linux共享文件4.使用远程工具登录Linux 总结 前言 提示&#xff1a;本文详解了在Linux系统下如何安装和启用Samba服务&#xff0c;涵盖了从…...

【C++】引用’‘的深入解析

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...