数据结构之线性表(python)

华子目录

  • 线性表的定义
    • 前驱与后继
  • 1.顺序表(顺序存储结构)
    • `python列表与数组的区别`
      • 列表
      • 数组
    • 1.1插入数据
      • 实例
    • 1.2删除元素
      • 实例
    • 1.3查找元素
    • 1.4修改元素
    • 1.5综合示例
  • 2.单链表
    • 2.1单链表的初始化
    • 2.2插入元素
      • 示例
      • 注意
    • 2.3删除元素
      • 示例
    • 2.4修改元素
    • 2.5查找元素
    • 2.6综合示例

线性表的定义

  • 线性表零个多个数据元素的有限序列
  • 在逻辑结构上具有线性关系。将具有“一对一”关系的数据“线性”地存储到物理空间中,这种存储结构就称为线性存储结构(简称线性表)。
  • 线性表元素的个数nn>=0)定义为线性表的长度,当n=0时,称为空表
  • 在较复杂线性表中,一个数据元素可以有若干个数据项组成。
  • 线性表又可以分为顺序表顺序存储结构)和链表链式存储结构

前驱与后继

  • 某一元素的左侧相邻元素称为“直接前驱”,位于此元素左侧所有元素都统称为“前驱元素
  • 某一元素的右侧相邻元素称为“直接后继”,位于此元素右侧所有元素都统称为“后继元素

在这里插入图片描述

1.顺序表(顺序存储结构)

  • 用一段地址连续存储单元依次存储线性表数据元素

在这里插入图片描述

python列表与数组的区别

列表

  • 列表顺序表,不是链式表
  • 列表(其他语言称为数组)是一种基本数据类型
  • 当进行列表取值a[2]时,列表中的每一个格子存的是值的地址。当进行a[2]时,它取得是a[2]的地址。通过地址指向来取值
  • python不需要提前申请列表长度,因为python内部会自动申请内存。
  • python列表插入删除时间复杂度都是O(n)

数组

  • 当进行数组取值时a[2],假如说电脑是32位,a开头编号是100内存内部会执行100+2*4=108,取到a[2]对应的
  • 数组元素类型要相同
  • 数组长度固定

1.1插入数据

向已有顺序表中插入数据元素,根据插入位置的不同,可分为以下3种情况:

  • 在表头插入元素
  • 在表的中间位置插入元素
  • 在表尾插入元素

虽然数据元素插入顺序表中的位置有所不同,但是都使用的是同一种方式去解决,即:通过遍历,找到数据元素插入位置,然后做如下两步工作:

  • 将要插入位置元素以及后续的元素整体向后移动一个位置
  • 插入的元素放到腾出来的位置上

实例

{1,2,3,4,5} 的第 3 个位置上插入元素 6,实现过程如下:

  • 遍历至顺序表存储第 3 个数据元素的位置
  • 在这里插入图片描述
  • 将元素 3 以及后续元素 4 和 5 整体移动一个位置
  • 在这里插入图片描述
  • 新元素 6 放入腾出的位置
  • 在这里插入图片描述

1.2删除元素

顺序表删除指定元素,实现起来非常简单,只需找到目标元素,并将其后续所有元素整体前移 1 个位置即可。

  • 后续元素整体前移一个位置,会直接将目标元素删除,可间接实现删除元素的目的

实例

{1,2,3,4,5} 中删除元素 3 的过程如图所示:

  • 找到目标元素
    在这里插入图片描述
  • 后续元素整体前移

在这里插入图片描述

1.3查找元素

顺序表中查找目标元素,可以使用多种查找算法实现,比如说二分查找算法、插值查找算法等。

1.4修改元素

顺序表修改元素实现过程是:

  • 找到目标元素
  • 直接修改该元素的值

1.5综合示例

import randomclass SqList:# 初始化顺序表def __init__(self, length):self.length = length        #表示顺序表的长度(元素个数)self.sqlist = [random.randint(1, 100) for i in range(length)]    #顺序表内容# 返回所有元素def ShowList(self):return self.sqlist# 遍历所有元素def ErgodList(self):for i in range(self.length):print(f"第{i+1}个元素值为{self.sqlist[i]}")# 取值(按位取值)def GetElement(self, i):# 首先判断插入的位置是否在合法范围内[0,length-1]if i < 1 or i > self.length:return Falsereturn self.sqlist[i - 1]# 查找def FindElement(self, e):for i in range(self.length):if e == self.sqlist[i]:print(f"查找的元素在第{i+1}个位置")breakelse:print("无查找元素")# 插入def InsertList(self, i, e):if i < 1 or i > self.length+1:return Falseself.sqlist.insert(i - 1, e)self.length += 1return True# 删除(按位删除)def DeleteList_space(self, i):if i < 1 or i > self.length:return Falseself.sqlist.pop(i - 1)self.length -= 1return True# 删除(按值删除)def DeleteList_value(self, e):for i in range(self.length):if e == self.sqlist[i]:self.sqlist.pop(i)self.length -= 1return Truereturn False# 修改(按值修改)def SetElement(self, eold, enew):for i in range(self.length):if eold == self.sqlist[i]:self.sqlist[i] = enewreturn Truereturn False# 修改(按位修改)def SetElement_space(self, i, enew):if i < 1 or i > self.length:return Falseself.sqlist[i-1] = enewreturn Truel = eval(input("请输入初始化长度:"))
my_sqlist = SqList(l)   #初始化对象# 输出所有值
mylist = my_sqlist.ShowList()
print(mylist)
print("------------------------------------------------")# 遍历元素
my_sqlist.ErgodList()
print("------------------------------------------------")# 插入元素
i, e = map(int, input("请输入插入元素的位置和值(空格分割):").split())
my_sqlist.InsertList(i, e)
print(f"插入后列表:{my_sqlist.sqlist}")
print("------------------------------------------------")# 删除(按值删除)
e = eval(input("请输入要删除的值:"))
my_sqlist.DeleteList_value(e)
print(f"删除之后的列表{my_sqlist.sqlist}")
print("------------------------------------------------")# 删除(按位删除)
i = eval(input("请输入删除元素的位置:"))
my_sqlist.DeleteList_space(i)
print(f"删除之后的列表{my_sqlist.sqlist}")
print("------------------------------------------------")# 修改 (按值修改)
old, new = map(int, input("请输入需要修改的值和新值:").split())
my_sqlist.SetElement(old, new)
print(f"修改之后的列表{my_sqlist.sqlist}")
print("------------------------------------------------")# 修改(按位修改)
i, new = map(int, input("请输入需要修改的位置和新值:").split())
my_sqlist.SetElement_space(i, new)
print(f"修改之后的列表{my_sqlist.sqlist}")
print("------------------------------------------------")# 查找
e = eval(input("请输入要查找的值:"))
my_sqlist.FindElement(e)
请输入初始化长度:5
[98, 27, 99, 63, 54]
------------------------------------------------
第1个元素值为98
第2个元素值为27
第3个元素值为99
第4个元素值为63
第5个元素值为54
------------------------------------------------
请输入插入元素的位置和值(空格分割):6 99
插入后列表:[98, 27, 99, 63, 54, 99]
------------------------------------------------
请输入要删除的值:99
删除之后的列表[98, 27, 63, 54, 99]
------------------------------------------------
请输入删除元素的位置:2
删除之后的列表[98, 63, 54, 99]
------------------------------------------------
请输入需要修改的值和新值:98 0
修改之后的列表[0, 63, 54, 99]
------------------------------------------------
请输入需要修改的位置和新值:2 66
修改之后的列表[0, 66, 54, 99]
------------------------------------------------
请输入要查找的值:0
查找的元素在第1个位置进程已结束,退出代码0

2.单链表

  • 为了表示每个数据元素 ai 与其直接后继数据元素 ai+1 之间的逻辑关系,对数据元素 ai 来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。我们把存储数据元素信息称为数据域,把存储直接后继位置称为指针域指针域中存储的信息称做指针。这两部分信息组成数据元素 ai存储映像,称为结点(Node)
  • n个结点链结成一个链表,即为线性表(a1,a2,…,an)的链式存储结构,因为此链表每个结点中只包含一个指针域,所以叫做单链表

在这里插入图片描述
在这里插入图片描述

  • 头指针:一个普通的指针,它的特点是永远指向链表第一个节点的位置
  • 头节点:其实就是一个不存任何数据空节点,通常作为链表第一个节点。对于链表来说,头节点不是必须的
  • 首元节点:由于头节点(也就是空节点)的缘故,链表中称第一个存有数据的节点首元节点
  • 其他节点链表中其他的节点

在这里插入图片描述

  • 注意:链表中有头节点时,头指针指向头节点;反之,若链表中没有头节点,则头指针指向首元节点

2.1单链表的初始化

  • 声明一个头指针(如果有必要,可以声明一个头节点
  • 创建多个存储数据节点,在创建的过程中,要随时与其前驱节点建立逻辑关系

2.2插入元素

同顺序表一样,向链表中增添元素,根据添加位置不同,可分为以下 3 种情况:

  • 头插法:插入到链表的头部头节点之后),作为首元节点
  • 中插法插入到链表中间某个位置
  • 尾插法插入链表最末端,作为链表最后一个数据元素

虽然新元素插入位置不固定,但是链表插入元素的思想是固定的,只需做以下3步操作,即可将新元素插入到指定的位置

  • 找到插入位置前一个结点
  • 新结点next指针 指向插入位置结点
  • 插入位置前结点next指针 指向插入结点

示例

例如,我们在链表 {1,2,3,4} 的基础上分别实现在头部中间部位尾部插入新元素 5,其实现过程如图1 所示:
在这里插入图片描述

  • 从图中可以看出,虽然新元素插入位置不同,但实现插入操作方法一致的,都是先执行步骤 1 ,再执行步骤 2

注意

链表插入元素的操作必须是先步骤 1,再步骤 2;反之,若先执行骤步 2,除非再添加一个指针,作为插入位置后续链表的头指针,否则会导致插入位置后的这部分链表丢失无法再实现步骤1

2.3删除元素

链表删除指定数据元素时,实则就是将存有该数据元素节点链表摘除,但作为一名合格的程序员,要对存储空间负责,对不再利用存储空间及时释放。因此,从链表删除数据元素需要进行以下 2 步操作:

  • 结点链表摘下来
  • 手动释放掉结点回收被结点占用的存储空间

其中,从链表上摘除某节点的实现非常简单,只需找到该节点直接前驱节点temp

  • temp.next = temp.next.next

示例

例如,从存有 {1,2,3,4}链表中删除元素3,则此代码执行效果如图 2 所示:
在这里插入图片描述

2.4修改元素

  • 修改链表中的元素,只需通过遍历找到存储此元素的节点,对节点中的数据域做更改操作即可

2.5查找元素

  • 链表查找指定数据元素最常用方法是:从表头依次遍历表中节点,用被查找元素各节点数据域存储数据元素进行比对,直至比对成功遍历至链表最末端NULL比对失败的标志
  • 注意,遍历有头节点链表时,需避免头节点对测试数据影响

2.6综合示例

# 定义节点类,包含两个成员:节点数据域和指向下一个节点的指针域(带有头节点的单链表)
class SingleNode:def __init__(self, item):self.item = item   #数据域self.next = None   #指针域class SingleLinkList:def __init__(self):self.head = None# 判断链表是否为空def is_empty(self):return self.head == None# 输出链表长度def get_length(self):return len(self.travel())# 遍历整个链表def travel(self):# 思路就是先判断链表是否为空# 为空直接返回None# 不为空的话,就先定义一个列表,然后通过next指针从头指针开始遍历,依次将节点存储的值加入列表中,直到下一个指针指向为空,则停止遍历if self.is_empty():return Noneelse:curlist = []cur = self.headwhile cur != None:curlist.append(cur.item)cur = cur.nextreturn curlist# 头插法创建单链表def add(self,newItem):node = SingleNode(newItem)node.next = self.headself.head = node# 尾插法def append(self,newItem):node = SingleNode(newItem)if self.is_empty():return self.add(newItem)# 从头节点开始遍历nod = self.headwhile nod.next != None:nod = nod.nextnod.next = node# 指定位置添加元素def insert(self, pos, newItem): # 在指定pos位置上添加newItem元素# 链表的插入需要分几种情况# 第一步:判断pos是否在合理范围内,如果不在,则直接终止# 第二步:判断pos是否在第一个,如果是则采用头插法# 第三步:如果pos在最后一个,则采用尾插法# 第四步:如果即不在头,也不在尾,则通过循环遍历到pos位置,再用insert插入node = SingleNode(newItem)cur = self.headcount = 0if pos == 0:return self.add(newItem)elif pos < (self.get_length()):while count < pos - 1:    #找到指定位置的前一个节点cur = cur.nextcount += 1node.next = cur.nextcur.next = nodeelif pos == (self.get_length()):return self.append(newItem)else:return '输入的位置有误,请确认'# 删除指定位置上的节点def remove(self, pos):# 第一步:判断给定的pos是否在合理范围内# 第二步:通过循环,遍历到pos位置,遍历期间通过next指针依次指向下一个节点# 第三步:找到指定位置的节点后,通过nod.next = nod.next.next删除cur = self.headcount = 0if 1 <= pos < (self.get_length()):while count < pos - 1:  #找到指定位置的前一个节点cur = cur.nextcount += 1cur.next = cur.next.nextelif pos == 0:self.head = cur.nextelse:return '输入的位置有误,请确认'# 查找指定位置的节点值def find(self, pos):cur = self.headcount = 0if 0 <= pos < (self.get_length()):while count < pos:     #找到指定位置的节点cur = cur.nextcount += 1return cur.itemelse:return '输入的位置有误,请确认'# 更新链表中某个位置的值def update(self, pos, newItem):cur = self.headcount = 0if 0 <= pos < (self.get_length()):while count < pos:    #找到指定位置的节点cur = cur.nextcount += 1cur.item = newItemelse:return '输入的位置有误,请确认'# 清空链表def clear(self):self.head = Nonesinglelinklist = SingleLinkList()  #实例化对象
print("初始化单链表:",singlelinklist)
print("-----------------------------")
print("判断单链表是否为空:",singlelinklist.is_empty())
print("-----------------------------")# 添加数据
import random
for i in range(10):singlelinklist.add(random.randint(1,100))# 遍历数据
print("遍历单链表:",singlelinklist.travel())
print("-----------------------------")
print("判断单链表是否为空:",singlelinklist.is_empty())
print("-----------------------------")# 末尾添加数据
singlelinklist.append(10)
print("末尾添加元素后的单链表遍历结果:",singlelinklist.travel())
print("-----------------------------")
# 开头添加数据
singlelinklist.add(1)
print("开头添加元素后的单链表遍历结果:",singlelinklist.travel())
print("-----------------------------")# 查看数据长度
print("单链表长度:",singlelinklist.get_length())
print("-----------------------------")# 指定位置插入数据,位置从0开始
singlelinklist.insert(1, 13)
print("插入数据后的遍历单链表:",singlelinklist.travel())
print("-----------------------------")# 删除指定位置数据
singlelinklist.remove(0)
print("删除数据后的遍历单链表:",singlelinklist.travel())
print("-----------------------------")# 更新指定位置数据
singlelinklist.update(2, 2)
print("更新数据后的遍历单链表:",singlelinklist.travel())
print("-----------------------------")# 清空所有数据
singlelinklist.clear()
print("清空数据后的遍历单链表:",singlelinklist.travel())
初始化单链表: <__main__.SingleLinkList object at 0x0000020DA4358460>
-----------------------------
判断单链表是否为空: True
-----------------------------
遍历单链表: [39, 42, 88, 51, 64, 60, 66, 29, 29, 35]
-----------------------------
判断单链表是否为空: False
-----------------------------
末尾添加元素后的单链表遍历结果: [39, 42, 88, 51, 64, 60, 66, 29, 29, 35, 10]
-----------------------------
开头添加元素后的单链表遍历结果: [1, 39, 42, 88, 51, 64, 60, 66, 29, 29, 35, 10]
-----------------------------
单链表长度: 12
-----------------------------
插入数据后的遍历单链表: [1, 13, 39, 42, 88, 51, 64, 60, 66, 29, 29, 35, 10]
-----------------------------
删除数据后的遍历单链表: [13, 39, 42, 88, 51, 64, 60, 66, 29, 29, 35, 10]
-----------------------------
更新数据后的遍历单链表: [13, 39, 2, 88, 51, 64, 60, 66, 29, 29, 35, 10]
-----------------------------
清空数据后的遍历单链表: None

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

图解Self-Attention和代码实现,大语言模型基础思维导图

文章目录 1 Self-Attention的概念注意优缺点 2 Self-Attention的原理Q,K,V, and Self-Attention计算公式代码实现 Self-Attention的计算细节输入是如何Embedding的&#xff1f;Word EmbeddingsSentence EmbeddingsPre-trained Embeddings SelfAttention是如何计算的计算图 4 Se…

无畏契约 (Valorant)YOLO 模型数据集

4万数据集 无畏契约 Valorant YOLO 模型 数据集 截图大小&#xff1a;256x256 截图数量&#xff1a;40000包含保安拌线&#xff0c;被闪被黑&#xff0c;蝰蛇大招内 模型类别&#xff1a;2类 头身类 1身0头 人物&#xff1a;黄色色盲 已添加部分负样本&#xff0c;防止识别除敌…

数据结构——“二叉搜索树”

二叉搜索树是一个很重要的数据结构&#xff0c;它的特殊结构可以在很短的时间复杂度找到我们想要的数据。最坏情况下的时间复杂度是O(n)&#xff0c;最好是O(logn)。接下来看一看它的接口函数的实现。 为了使用方便&#xff0c;这里采用模版的方式&#xff1a; 一、节点 temp…

docker部署Stirling-PDF

github网址&#xff1a; GitHub - Stirling-Tools/Stirling-PDF: #1 Locally hosted web application that allows you to perform various operations on PDF files 1、官方docker镜像无法拉取&#xff0c;使用别人阿里云私人镜像仓库下载Stirling-PDF镜像&#xff1a; regi…

微服务以及注册中心

一、什么是微服务 微服务是指开发一个单个小型的但有业务功能的服务&#xff0c;每个服务都有自己的处理和轻量通讯机制&#xff0c;可以部署在单个或多个服务器上。微服务也指一种松耦合的、有一定的有界上下文的面向服务架构。也就是说&#xff0c;如果每个服务都要同时修改…

Objects as Points基于中心点的目标检测方法CenterNet—CVPR2019

Anchor Free目标检测算法—CenterNet Objects as Points论文解析 Anchor Free和Anchor Base方法的区别在于是否在检测的过程中生成大量的先验框。CenterNet直接预测物体的中心点的位置坐标。 CenterNet本质上类似于一种关键点的识别。识别的是物体的中心点位置。 有了中心点之…

AI助力遥感影像智能分析计算,基于高精度YOLOv5全系列参数【n/s/m/l/x】模型开发构建卫星遥感拍摄场景下地面建筑物智能化分割检测识别系统

随着科技的飞速发展&#xff0c;卫星遥感技术已成为获取地球表面信息的重要手段之一。卫星遥感图像以其覆盖范围广、数据量大、信息丰富等特点&#xff0c;在环境监测、城市规划、灾害评估等多个领域发挥着不可替代的作用。然而&#xff0c;面对海量的卫星图像数据&#xff0c;…

wx小程序渗透思路

免责声明:本文仅做分享! 目录 WX小程序源代码 wx小程序目录位置: 反编译: e0e1-wx.py工具 unveilr.exe工具 查看源代码: 微信开发者工具: WX抓包 Fiddler抓包 官网下载 下载证书 操作: bp proxifier bp:(代理抓包) proxifier:(本地代理) WX小程序源代码 其实就…

程序修改题(41-50)

第四十一题 题目 给定程序modi1.c的主函数中&#xff0c;将a、b、c三个结点链成一个单向链表&#xff0c;并给各结点的数据域赋值&#xff0c;函数fun()的作用是:累加链表结点数据域中的数据作为函数值返回。 #include <stdio.h> typedef struct list { int data…

【数据结构-扫描线】力扣57. 插入区间

给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval [start, end] 表示另一个区间的开始和…

李宏毅结构化学习 02

文章目录 一、上篇博文复习二、Separable Case三、Non-separable Case四、Considering Errors五、Regularization六、Structured SVM七、Cutting Plane Algorithm for Structured SVM八、Multi-class and binary SVM九、Beyond Structured SVM 一、上篇博文复习 图中x表示输入的…

Android Framework(六)WMS-窗口显示流程——窗口内容绘制与显示

文章目录 窗口显示流程明确目标 窗户内容绘制与显示流程窗口Surface状态完整流程图 应用端处理finishDrawingWindow 的触发 system_service处理WindowState状态 -- COMMIT_DRAW_PENDING本次layout 流程简述 窗口显示流程 目前窗口的显示到了最后一步。 在 addWindow 流程中&…

基于Python的自然语言处理系列(10):使用双向LSTM进行文本分类

在前一篇文章中&#xff0c;我们介绍了如何使用RNN进行文本分类。在这篇文章中&#xff0c;我们将进一步优化模型&#xff0c;使用双向多层LSTM来替代RNN&#xff0c;从而提高模型在序列数据上的表现。LSTM通过引入一个额外的记忆单元&#xff08;cell state&#xff09;来解决…

24.Redis实现全局唯一ID

是一种分布式系统下用来生成全局唯一ID的工具。 特点 1.唯一性 2.高可用 3.高性能 4.递增性&#xff0c;数据也要保持一种递增&#xff0c;有利于数据库进行查询。 5.安全性 全局唯一ID的生成策略 1.UUID(没有顺序&#xff0c;字符串类型&#xff0c;效率不高) 2.Redis…

【电路笔记】-差分运算放大器

差分运算放大器 文章目录 差分运算放大器1、概述2、差分运算放大器表示2.1 差分模式2.2 减法器模式3、差分放大器示例3.1 相关电阻3.2 惠斯通桥3.3 光/温度检测4、仪表放大器5、总结1、概述 在之前的文章中,我们讨论了反相运算放大器和同相运算放大器,我们考虑了在运算放大器…

floodfill算法(二)

目录 一、太平洋大西洋水流问题 1. 题目链接&#xff1a;417. 太平洋大西洋水流问题 2. 题目描述&#xff1a; 3. 解法 &#x1f334;算法思路&#xff1a; &#x1f334;算法代码&#xff1a; 二、扫雷游戏 1. 题目链接&#xff1a;529. 扫雷游戏 2. 题目描述&#xf…

softmax回归的从零实现(附代码)

softmax回归是一个多分类模型&#xff0c;但是他跟线性回归一样将输入特征与权重做线性叠加&#xff0c;与线性不同的是他有多个输出&#xff0c;输出的个数对应分类标签的个数&#xff0c;比如四个特征和三种输出动物类别&#xff0c;则权重包含12个标量&#xff08;带下标的w…

深度学习之线性代数预备知识点

概念定义公式/案例标量(Scalar)一个单独的数值&#xff0c;表示单一的量。例如&#xff1a;5, 3.14, -2向量 (Vector)一维数组&#xff0c;表示具有方向和大小的量。 &#xff0c;表示三维空间中的向量 模(Magnitude)向量的长度&#xff0c;也称为范数&#xff08;通常为L2范数…

HCIA--实验十六:ACL通信实验(2)

2.高级ACL配置 一、实验内容 1.需求/要求&#xff1a; 使用三台PC和一台交换机&#xff0c;在交换机上配置高级ACL&#xff0c;测试PC1、PC2、PC3间的连通性。 二、实验过程 1.拓扑图&#xff1a; 2.步骤&#xff1a; 1.给PC3配置ip地址&#xff1a; 2.给交换机SW3配置高…

Hello,Spring Boot...

今天开启了Spring Boot学习之旅。 首先就是&#xff0c;JDK、Maven、IDEA以及各种官网的下载、安装与配置 然后通过组件创建小类&#xff0c;最让人头痛的就是&#xff0c;这个spring-boot-starter-thymeleaf&#xff0c;下错版本了 其他的一切顺利&#xff0c;自动化明显 最后…