数据结构基础 ——数组VS链表(二)

一、数组

    数组对应的英文是array,是有限个相同类型的变量所组成的有序集合,数组中的每一个变量称为元素。数组是最简单、最常用的数据结构。

数组存储格式:

 在Python语言中,并没有直接使用数组这个概念,而是使用列表(list)和元组( tuple)这两种集合,它们本质上都是对数组的封装。其中,列表是一个动态可扩展的数组,支持任意地添加、删除、修改元素;而元组是一个不可变集合,一旦创建就不再支持修改。

 数据结构的操作无非是增、删、改、查4种情况!

二、数组的基本操作

 1、读取元素

print(ll[3])

 2、更新元素

ll[5]=100

print(ll[5])

可知: 数组读取元素和更新元素的时间复杂度都是O(1)。
 

 3、添加元素

    插入元素有3种情况:

  1. 尾部插入
  2. 中间插入
  3. 超范围插入

 (1)尾部插入,是最简单的情况,直接把插入的元素放在数组尾部的空闲位置即可,等同于更新元素的操作。

 

(2)中间插入,稍微复杂一些。由于数组的每一个元素都有其固定下标,所以不得不首先把插入位置及后面的元素向后移动,有个空位置,再把要插入的元素放到对应的数组位置上。

class MyArray:'''初始化'''def __init__(self, capcity):self.arrs = [None] * capcity  # 数组self.size = 0  # 大小'''添加'''def add(self, index, value):# 判断是否超出范围if index < 0 or index >= self.size:raise Exception('数组下标越界!')# 将数据往后移动,直到index这个位置为止for i in range(self.size - 1, index - 1, -1):self.arrs[i + 1] = self.arrs[i]# 插入新数据self.arrs[index] = value# 个数self.size += 1'''显示'''def show(self):for i in range(self.size):print(self.arrs[i], end=',')
if __name__ == '__main__':# 创建对象my = MyArray(4)#在第一个位置添加数据my.add(0, 8)my.add(0, 10)my.add(0, 20)my.add(0, 2)# IndexError: list assignment index out of range# my.add(0,15)#显示数据my.show()

(1) 索引正常范围

 

 (2)索引超出范围

 (3)如现在有一个长度为6的数组,已经装满了元素,这时还想插入一个新元素。

   解决方法:  可以创建一个新数组,长度是旧数组的2倍,再把旧数组中的元素统统复制过去,这样就实现了数组的扩容。

 #创建一个新数组,其容量扩大旧数组2倍,再把原数组拷贝到新数组中def resize(self):self.arrnews=[None]*len(self.arrs)*2#旧数组的数据拷贝到新数组中for i in range(self.size):self.arrnews[i]=self.arrs[i]#再把新数组给旧数组self.arrs=self.arrnews'''添加'''def add(self, index, value):# 判断是否超出范围if index < 0 or index > self.size:raise Exception('数组下标越界!')#如果超出范围,就扩容if self.size>=len(self.arrs):self.resize()# 将数据往后移动,直到index这个位置为止for i in range(self.size - 1, index - 1, -1):self.arrs[i + 1] = self.arrs[i]# 插入新数据self.arrs[index] = value# 个数self.size += 1
if __name__ == '__main__':# 创建对象my = MyArray(6)#在第一个位置添加数据my.add(0, 8)my.add(0, 10)my.add(0, 20)my.add(0, 2)my.add(0, 7)my.add(0, 3)# IndexError: list assignment index out of range# my.add(100,200)for i in range(30,41):my.add(0,i)#显示数据my.show()

(1) 数组大小超出范围,直接扩容2倍

(2)索引超出范围

 4、删除元素

        数组的删除操作和插入操作的过程相反,如果删除的元素位于数组中间,其后的元素都需要向前挪动1位。

 '''删除数据'''def remove(self,index):if index<0 or index>self.size:raise Exception('数组下标越界!')#从右往左移动,直到indxfor i in range(index,self.size):self.arrs[i]=self.arrs[i+1]#个数减少self.size-=1
if __name__ == '__main__':# 创建对象my = MyArray(6)#在第一个位置添加数据my.add(0, 8)my.add(0, 10)my.add(0, 20)my.add(0, 2)my.add(0, 7)my.add(0, 3)# IndexError: list assignment index out of range# my.add(100,200)for i in range(30,41):my.add(0,i)#显示数据my.show()my.remove(3)# my.remove(23)my.show()

 数组拥有非常高效的随机访问能力优势,数组的劣势体现在插入和删除元素方面。由于数组元素连续紧密地存储在内存中,插入、删除元素都会导致大量元素被迫移动,影响效率。

总的来说,数组所适合的是读操作多、写操作少的场景。

三、链表

链表(linked list〉是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。

(1) 单向链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next

(2) 双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev指针

数组在内存中的存储方式是顺序存储,而链表在内存中的存储方式则是随机存储。 

数组的内存分配方式


链表的内存分配方式
 

四、链表的基本操作

1、查找节点

     从头节点开始找第3个节点

  

class Node:  #新节点def __init__(self,data):self.data=dataself.next=Noneclass MyLinkedList:'''初始化 大小,头部,尾部'''def __init__(self):self.size=0self.head=Noneself.tail=None'''根据索引查找数据'''def get(self,index):if index<0 or index>self.size:raise  Exception('超出链表节点范围!')p=self.headfor i in range(index):p=p.nextreturn p

2、更新节点

     从头节点开始找第2个节点进行修改

3、添加节点

与数组类似,在链表中插入节点时,同样分为3种情况:

  1. 尾部插入
  2. 头部插入
  3. 中间插入
  • 尾部插入

最后一个节点的next指针指向新插入的节点

  • 头部插入
  1. 把新节点的next指针指向原先的头节点。
  2. 把新节点变为链表的头节点。

  • 中间插入
  1. 新节点的next指针指向插入位置的节点。
  2. 插入位置前置节点的next指针,指向新节点。

   

  '''添加新节点'''def insert(self,data,index):if index < 0 or index > self.size:raise Exception('超出链表节点范围!')#获取节点对象node=Node(data)#空链表if self.size==0:self.head=nodeself.tail=node#插入头部elif index==0:node.next=self.head  #将新节点指向原先的头节点self.head=node  #新节点变为链表的头节点#插入尾部elif self.size==index:self.tail.next=node #尾节点指向新节点self.tail=node   #新节点变为链表的尾节点#插入中间else:prev_node=self.get(index-1) #获取前一个节点node.next=prev_node.next  #新节点指向插入位置的节点prev_node.next=node  #前置节点指向新节点self.size+=1
if __name__ == '__main__':my= MyLinkedList()for i in range(5):my.insert(20+i,i)#my.insert(100,10)my.show()

4、删除节点

链表的删除操作同样分为3种情况:

  1. 尾部删除
  2. 头部删除
  3. 中间删除
     
  1. 尾部删除

      2.头部删除

     3.中间删除

 

 '''删除节点'''def remove(self, index):if index < 0 or index > self.size:raise Exception('超出链表节点范围!')#删除头节点if index==0:del_node=self.head  #删除头节点self.head=self.head.next #指向头节点next成为头节点#删除尾节点elif index==self.size-1:prev_node = self.get(index - 1) #获取前一个节点del_node = prev_node.next  #删除前个节点nextprev_node.next=None  #前一个节点为空self.tail=prev_node  #尾节点指向前节点#删除中间节点else:prev_node=self.get(index-1)  #获取前节点next_node=prev_node.next.next   #获取前节点的下一个节点del_node=prev_node.next #删除节点prev_node.next=next_node #前节点指向下个节点self.size-=1return del_node'''显示'''def show(self):# 头节点p=self.head#循环节点是否为空while p is not None:print(p.data)  #打印节点p=p.next   #指向下一个节点指针nextprint('*'*30)
if __name__ == '__main__':my= MyLinkedList()for i in range(5):my.insert(20+i,i)my.show()my.remove(3)#my.remove(30)my.show()

五、数组VS链表

   总之: 数组在于能够快速定位元素,对于读操作多写操作少的场景来说,用数组更合适一些。链表的优势在于能够灵活地进行插入和删除操作,如果需要频繁插入、删除元素,用链表更合适一些。

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

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

相关文章

Transformer模型-encoder编码器,padding填充,source mask填充掩码的简明介绍

今天介绍transformer模型的encoder编码器&#xff0c;padding填充&#xff0c;source mask填充掩码 背景 encoder编码器层是对之前文章中提到的子层的封装。它接收位置嵌入的序列&#xff0c;并将其通过多头注意力机制和位置感知前馈网络。在每个子层之后&#xff0c;它执行残差…

SQLite数据库文件格式(十五)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite 4.9的虚拟表机制(十四) 下一篇&#xff1a;SQLite超详细的编译时选项&#xff08;十六&#xff09; ► 目录 本文档描述和定义磁盘上的数据库文件 自 SQLite 以来所有版本使用的格式 版本 3.0.0 &#xff08;2004-06-18…

PVE系统的安装

一.PVE系统的安装 前置准备环境:windows电脑已安装Oracle VM VirtualBox,电脑支持虚拟化,且已经开启,按住ctrl+shift+ESC打开任务管理器查看是否开启,如果被禁用,可进入BIOS开启虚拟化,重启电脑后再进行后续操作。本步骤选用windows10安装VirtualBox,版本为7.0.8。 …

web安全-SSH私钥泄露

发现主机 netdiscover -r 192.168.164.0 扫描端口 看到开放80和31337端口都为http服务 浏览器访问测试 查看80端口和31337端口网页和源代码并无发现有用信息 目录扫描 扫描出80端口并无有用信息 扫描31337端口 发现敏感文件robots.txt和目录.ssh 访问敏感文件和目录 /.ss…

Ansys Zemax | 如何将光栅数据从Lumerical导入至OpticStudio(下)

附件下载 联系工作人员获取附件 本文介绍了一种使用Ansys Zemax OpticStudio和Lumerical RCWA在整个光学系统中精确仿真1D/2D光栅的静态工作流程。将首先简要介绍方法。然后解释有关如何建立系统的详细信息。 本篇内容将分为上下两部分&#xff0c;上部将首先简要介绍方法工作…

一键修复所有DLL缺失解决步骤,使用dll修复工具详情

在使用电脑或安装软件时&#xff0c;我们有时会遭遇DLL文件丢失的情况&#xff0c;这会阻止软件正常启动或运行。为此&#xff0c;一个简易且有效的解决方案是使用一键修复所有DLL缺失问题的工具。 引言 DLL&#xff08;动态链接库&#xff09;是Windows操作系统的核心部分&am…

k8s_入门_kubelet安装

安装 在大致了解了一些k8s的基本概念之后&#xff0c;我们实际部署一个k8s集群&#xff0c;做进一步的了解 1. 裸机安装 采用三台机器&#xff0c;一台机器为Master&#xff08;控制面板组件&#xff09;两台机器为Node&#xff08;工作节点&#xff09; 机器的准备有两种方式…

文库配置异步转换(宝塔)| 魔众文库系统

执行以下操作前提前进入网站根目录&#xff0c;如 cd /www/wwwroot/example.com执行 artisan 命令前请参照 开发教程 → 开发使用常见问题 → 如何运行 /www/server/php/xxx/bin/php artisan xxx 命令 步骤1&#xff0c;生成数据库队列表迁移文件 在执行该步骤前&#xff0c;请…

橘子学JDK之JMH-02(BenchmarkModes)

一、案例二代码 这次我们来搞一下官网文档的第二个案例&#xff0c;我删除了一些没用的注释&#xff0c;然后对代码做了一下注释的翻译&#xff0c;可以看一下意思。 package com.levi;import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; import …

【科技】2024最新微信机器人一键部署教程

外话 话说上次写文章好像又过了几个月了…… 其实还是因为马上小升初的各种密考&#xff0c;其它地方不知道&#xff0c;反正广东这块名校基本上都得密考考进去 笔者连考几次都惨不忍睹…… 不过5月份会有一个信息技术特长生招生&#xff0c;看看能不能吧~ 正文 先说&#xff…

基于SpringBoot+Vue的高校大学生心理咨询管理系统(源码+文档+部署+讲解)

一.系统概述 系统根据现有的管理模块进行开发和扩展&#xff0c;采用面向对象的开发的思想和结构化的开发方法对高校大学生心理咨询管理的现状进行系统调查。采用结构化的分析设计&#xff0c;该方法要求结合一定的图表&#xff0c;在模块化的基础上进行系统的开发工作。在设计…

springboot相关报错解决

Caused by: java.lang.ClassNotFoundException: 目录 Caused by: java.lang.ClassNotFoundException: org.springframework.context.event.GenericApplicationListener spring-boot-dependencies:jar:2.1.9.RELEASE was not found org.springframework.context.event.Generi…

华为OD-C卷-攀登者1[100分]

攀登者喜欢寻找各种地图,并且尝试攀登到最高的山峰。 地图表示为一维数组,数组的索引代表水平位置,数组的元素代表相对海拔高度。其中数组元素0代表地面。 例如: [0,1,2,4,3,1,0,0,1,2,3,1,2,1,0],代表如下图所示的地图 地图中有两个山脉位置分别为 1,2,3,4,5 和 8,9,1…

SV-7042V 40W网络有源音柱 智慧灯杆广播音柱

SV-7042V 40W网络有源音柱 一、描述 SV-7042V是深圳锐科达电子有限公司的一款壁挂式网络有源音柱&#xff0c;具有10/100M以太网接口&#xff0c;可将网络音源通过自带的功放和喇叭输出播放&#xff0c;其采用防水设计&#xff0c;功率40W。 SV-7042V作为网络广播播放系统的终…

LongVLM:让大模型解读长视频 SOTA 的方法

LongVLM&#xff1a;让大模型解读长视频 SOTA 的方法 使用LongVLM处理长视频的步骤LongVLM 方法3.1 总体架构3.2 局部特征聚合3.3 全局语义整合 效果4.1 实验设置4.2 主要结果4.3 消融研究4.4 定性结果 论文&#xff1a;https://arxiv.org/pdf/2404.03384.pdf 代码&#xff1a…

C语言进阶课程学习记录-main函数与命令行参数

C语言进阶课程学习记录-main函数与命令行参数 main函数验证以下4中定义是否正确实验-main的返回值cmd窗口 实验-main的输入参数cmd窗口 在main函数执其执行的函数实验-程序执行的第一个函数gcc编译器cmd窗口bcc编译器 小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&…

SpringCloud Alibaba Sentinel 规则持久化

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第十七篇&#xff0c;即使用 Sentinel 实现规则持久化。 二、概述 从前面我们做的实验可知&#xff0c;…

VsCode 安装Jupyter Notebook

VsCode 安装Jupyter Notebook 安装 1、打开 VSCode 编辑器&#xff0c;点击界面左端的【扩展】栏&#xff1b; 2、在【搜索框】中输入python&#xff0c;点击第一个Python&#xff0c;检查是否已经安装 python 插件&#xff0c;没安装的点击安装&#xff1b;已安装的继续第3步…

使用新版FLIR (FLIR_ADAS_v2) 数据集创建yolo格式数据集(目标检测)

FLIR在2022.1.19发布了新版的FLIR_ADAS_v2&#xff0c;有着更多的类别和数量更丰富的图像。数据集同步注释热图像和无注释RGB图像供参考。本文章主要介绍如何使用FLIR_ADAS_v2中的rgb图像和thermal图像来制作yolo格式数据集。 1.官方数据集下载&#xff1a;FLIR_ADAS_v2数据集…

【论文阅读——Profit Allocation for Federated Learning】

1.摘要 由于更为严格的数据管理法规&#xff0c;如《通用数据保护条例》&#xff08;GDPR&#xff09;&#xff0c;传统的机器学习服务生产模式正在转向联邦学习这一范式。联邦学习允许多个数据提供者在其本地保留数据的同时&#xff0c;协作训练一个共享模型。推动联邦学习实…