数据结构基础 ——数组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.mzph.cn/news/810403.shtml

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

相关文章

投资认知第一篇-股票分红是怎么回事?

购买股票的收益分为两种&#xff0c;一种是低价买高价卖的差价&#xff08;也就是俗称的炒股&#xff09;&#xff0c;另一种就是分红收益。购买一家上市公司的股份&#xff0c;投资者有权享受其分红&#xff0c;这是投资者的权益。一般来讲&#xff0c;上市公司分红有两种形式…

重磅,新GPT-4-Turbo重新夺回大模型第一名

好消息&#xff0c;新版 GPT-4 Turbo 今天开始现已向所有付费 ChatGPT 用户开放。GPT-4 Turbo提高了写作、数学、逻辑推理和编码能力。上下文长度128k 输出速度更快。现在已经开始陆续推送&#xff0c;如果你发现你的知识库截止时间是2024年4月&#xff0c;那么就是最新版本了&…

蓝桥杯 — — RSA解密

RSA解密 友情链接&#xff1a;RSA解密 题目&#xff1a; 思路&#xff1a; 对于这道题目&#xff0c;给出了三个已知量n d C&#xff0c;要我们进行解密&#xff0c;对于解密的公式 X C e m o d n X C^e \mod n XCemodn来讲&#xff0c;我们有唯一的参数e是未知的&#xf…

.[[backup@waifu.club]].svh勒索病毒数据怎么处理|数据解密恢复

尊敬的读者&#xff1a; 近年来&#xff0c;随着信息技术的迅猛发展&#xff0c;网络安全问题日益凸显&#xff0c;其中勒索病毒成为了一大威胁。.[[backupwaifu.club]].svh、.[[MyFilewaifu.club]].svh勒索病毒就是其中之一&#xff0c;它以其独特的传播方式和恶劣的加密手段…

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

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

山洪灾害防治监测报警系统方案

一、概述 我国是全球地区复杂程度最高的国家之一&#xff0c;多种气候和地形特征&#xff0c;特定的地质环境条件决定了我国地质灾害呈现增长和频发的态势。加之全球气候的变化使得我国极端、恶劣的天气在各地区发生的频率逐渐增高。据统计&#xff0c;在中国有1300多个乡镇&am…

交换机与路由器缓冲区:寻找完美大小

*本文系SDNLAB编译自瞻博网络技术专家兼高级工程总监Sharada Yeluri领英 在路由器和交换机中&#xff0c;缓冲区至关重要&#xff0c;可以防止网络拥塞期间的数据丢失。缓冲区到底要多大&#xff1f;这个问题在学术界和工业界一直备受争议。本文探讨了高端路由器中数据包缓冲的…

PSPICE、Multisim和Saber哪个更适合电路仿真?没想到是它

PSPICE、Multisim和Saber这三个软件都是非常流行的模拟电路仿真工具&#xff0c;它们各自有各自的优缺点&#xff0c;我简单讲一下&#xff1a; PSPICE&#xff1a; 优点&#xff1a; 精度高&#xff1a;PSPICE是专业的电路仿真软件&#xff0c;可以进行高精度的模拟电路仿真…

关于DNS解析那些事儿,了解DNS解析的基础知识

DNS&#xff0c;全称Domain Name System域名系统&#xff0c;是一个将域名和IP地址相互映射的一个分布于世界各地的分布式数据库&#xff0c;而DNS解析就是将域名转换为IP地址的过程&#xff0c;使人们可以轻松实现通过域名访问网站。DNS解析是网站建设非常关键的一步&#xff…

深度学习在三维点云处理与三维重建中的应用探索

目录 点云数据处理 数据清洗 数据降噪和简化 数据配准 特征提取 数据增强 数据组织 性能考量 PointNet PointNet ​编辑 算法问题 改进方法 三维重建 重建算法 架构模块 流程步骤 标记说明 优点和挑战 点云数据处理 数据清洗 去噪&#xff1a;点云数据通常…

数据结构—顺序表(如果想知道顺序表的全部基础知识点,那么只看这一篇就足够了!)

前言&#xff1a;学习完了C语言的基础知识点之后&#xff0c;我们就需要使用我们所学的知识来进一步对存储在内存中的数据进行操作&#xff0c;这时候我们就需要学习数据结构。而这篇文章为数据结构中顺序表的讲解。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以…

一、OpenCvSharp环境搭建

一、Visual Studio 创建新项目 二、选择Windows窗体应用&#xff08;.NET Framework&#xff09; 直接搜索模板&#xff1a;Windows窗体应用(.NET Framework) 记得是C#哈&#xff0c;别整成VB(Visual Basic)了 PS&#xff1a;若搜索搜不到&#xff0c;直接点击安装多个工具和…

MemoryAnalyzer分析OpenJ9上的phd格式文件

在做excel大数据写入时&#xff0c;发生内存泄漏 core.20240412.093703.1.0001.dmp heapdump.20240412.093703.1.0002.phd需要分析heap dump文件 mat本身不支持&#xff0c;需要我们下载插件 https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/runtimes/tools…

同等学力申硕-计算机专业-历年真题及其他资料分享

同等学力申请硕士学位考试是比较适合在职人员的提升学位方式&#xff0c;了解过的人应该都知道&#xff0c;现在社会的竞争压力越来越大&#xff0c;为了提高职业生存能力&#xff0c;提升学位在所难免。 我将与大家分享一份珍贵的复习资料&#xff1a;这不仅是我个人备考的心…

Docker Desktop修改镜像存储路径 Docker Desktop Start ... 卡死

1、CMD执行wsl -l -v --all 2、Clean / Purge data 3、导出wsl子系统镜像: wsl --export docker-desktop D:\docker\wsl\distro\docker-desktop.tar wsl --export docker-desktop-data D:\docker\wsl\data\docker-desktop-data.tar4、删除现有的wsl子系统&#xff1a; wsl -…

Springboot集成RabbitMq+延时队列

1. 引入jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> 2.配置yml 2.1 配置生产者yml spring:rabbitmq:host: localhostport: 5672virtual-host: …

主题换肤操作

有许多项目会遇见有light和dark多种颜色方案展示&#xff0c;如下&#xff1a; 这种是怎么实现的呢&#xff1f; 方案1&#xff1a;采用css变量来实现 /* 默认粉色主题 */ :root {--underline-dark: #000d8a;--gray-light: 229, 233, 240;--gray-dark: 34, 41, 57;--black: 1…

华为远程登陆管理配置:轻松掌握核心要点

实验拓扑及需求 实验步骤 A、配置相关地址及连通性测试 R1&#xff1a; [R1]int GigabitEthernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 192.168.12.1 24 R2&#xff1a; [R2]int gi 0/0/0 [R2-GigabitEthernet0/0/0]ip add 192.168.12.2 24 [R2]int gi 0/0/1 […

如何将对象转换成json字符串,以json格式输出,并获取到其中的特定字段

小王学习录 Json格式示例 1&#xff1a;简单的 JSON 对象示例 2&#xff1a;JSON 对象嵌套示例 3&#xff1a;JSON 数组示例 4&#xff1a;混合使用对象和数组 使用Gson将java对象转换成json字符串哪些数据类型的对象可以使用Gson转换为json字符串如何使用Gson将java对象转换成…

go语言学习--3.常用语句

目录 1.条件语句 1.1 if语句 1.2 if-else语句 1.3 switch语句 1.4 select语句 2.循环语句 2.1循环处理语句 2.2循环控制语句 3.go语言关键字 1.条件语句 和c语言类似&#xff0c;相关的条件语句如下表所示&#xff1a; 1.1 if语句 if 布尔表达式 {/* 在布尔表达式为 t…