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

数据结构从入门到精通二 ~ 数组和链表

1. 前言

在计算机科学和软件工程领域,数据结构是指在计算机中组织和存储数据的方式,数组和链表是其中最基础也是最常用的两种数据结构之一。

  • 数组(Array):是一种线性表数据结构,它使用连续的内存空间来存储一组相同类型的数据。数组提供了快速随机访问元素的能力,但插入和删除操作可能比较耗时,因为需要移动大量元素。

  • 链表(Linked List):也是一种线性表数据结构,但不同于数组,链表中的元素(节点)通过指针相互连接。每个节点包含数据和指向下一个节点的指针。链表支持快速插入和删除操作,但访问特定位置的元素时需要从头开始遍历,效率较低。

2. 内存结构

数组和链表这两种基础且重要的数据结构,它们分别代表了“连续存储”和“分散存储”两种物理结构。 

物理结构在很大程度上决定了程序对内存和缓存的使用效率,进而影响算法程序的整体性能。 

  1. 硬盘用于长期存储大量数据
  2. 内存用于临时存储程序运行中正在处理的数据
  3. 缓存则用于存储经常访问的数据和指令

内存是有限的,且同一块内存不能被多个程序共享,因此我们希望数据结构能够尽可能高效地利用空间。数组的元素紧密排列,不需要额外的空间来存储链表节点间的引用(指针),因此空间效率更高。然而,数组需要一次性分配足够的连续内存空间,这可能导致内存浪费,数组扩容也需要额外的时间和空间成本。

链表以“节点”为单位进行动态内存分配和回收,提供了更大的灵活性。

另一方面,在程序运行时,随着反复申请与释放内存,空闲内存的碎片化程度会越来越高,从而导致内存的利用效率降低。数组由于其连续的存储方式,相对不容易导致内存碎片化。相反,链表的元素是分散存储的,在频繁的插入与删除操作中,更容易导致内存碎片化。

“缓存未命中”越少,CPU 读写数据的效率就越高。

缓存的容量有限,只能存储一小部分频繁访问的数据,因此当 CPU 尝试访问的数据不在缓存中时,就会发生缓存未命中(cache miss),此时 CPU 不得不从速度较慢的内存中加载所需数据。

  1. 占用空间:链表元素比数组元素占用空间更多,导致缓存中容纳的有效数据量更少。
  2. 缓存行:链表数据分散在内存各处,而缓存是“按行加载”的,因此加载到无效数据的比例更高。
  3. 空间局部性:数组被存储在集中的内存空间中,因此被加载数据附近的数据更有可能即将被访问。

数组具有更高的缓存命中率,因此它在操作效率上通常优于链表。

如果数据量非常大、动态性很高、栈的预期大小难以估计,那么基于链表实现的栈更加合适。链表能够将大量数据分散存储于内存的不同部分,并且避免了数组扩容产生的额外开销。

程序运行时,数据主要存储在内存中。数组可提供更高的内存空间效率,而链表则在内存使用上更加灵活。

数组灵活性:栈上的数组的大小需要在编译时确定,而堆上的数组的大小可以在运行时动态确定。 

数组实现额外支持随机访问,但这已超出了栈的定义范畴,因此一般不会用到。效率并不高。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 一线大厂java面试题
  • go语言Gin框架的学习路线(九)
  • 构造+位运算,CF 1901C - Add, Divide and Floor
  • mac M1安装换脸Roop教程及所遇到的问题
  • 微信小程序:多图片显示及图片点击放大,多视频显示
  • git的一些使用技巧(git fetch 和 git pull的区别,git merge 和 git rebase的区别)
  • milvus的批量向量搜索
  • 数模·插值和拟合算法
  • 【Zotero插件】Zotero Tag为文献设置阅读状态 win11下相关设置
  • 上海市计算机学会竞赛平台2022年9月月赛丙组二叉树的遍历
  • 【JavaScript】 JS 的单线程和浏览器的多进程架构
  • PHP常量
  • 图灵测试:人工智能与人类沟通的界限
  • UniVue@v1.5.0版本发布:里程碑版本
  • linux学习笔记整理: 关于linux:nginx服务器 2024/7/20;
  • 【Linux系统编程】快速查找errno错误码信息
  • 08.Android之View事件问题
  • 77. Combinations
  • CSS魔法堂:Absolute Positioning就这个样
  • exports和module.exports
  • Java,console输出实时的转向GUI textbox
  • Java-详解HashMap
  • js
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • 创建一个Struts2项目maven 方式
  • 和 || 运算
  • 计算机在识别图像时“看到”了什么?
  • 前端知识点整理(待续)
  • 全栈开发——Linux
  • 深入浏览器事件循环的本质
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 通过几道题目学习二叉搜索树
  • 追踪解析 FutureTask 源码
  • 阿里云ACE认证学习知识点梳理
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • # 飞书APP集成平台-数字化落地
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (arch)linux 转换文件编码格式
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (转载)Google Chrome调试JS
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • ***利用Ms05002溢出找“肉鸡
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .net framework profiles /.net framework 配置
  • .Net Remoting常用部署结构
  • .net 调用php,php 调用.net com组件 --
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .net2005怎么读string形的xml,不是xml文件。
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • .net网站发布-允许更新此预编译站点
  • .Net转前端开发-启航篇,如何定制博客园主题
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • [2010-8-30]