数据结构单链表之链表与数组 | 第二套

简介: 数据结构单链表之链表与数组 | 第二套

数组将元素存储在连续的内存位置,从而为存储的元素提供易于计算的地址,这允许更快地访问特定索引处的元素。链表的存储结构不那么严格,元素通常不存储在连续的位置,因此它们需要与提供下一个元素的引用的附加标签一起存储。数据存储方案的这种差异决定了哪种数据结构更适合给定情况。

image.png

数组的数据存储方案

image.png

链表的数据存储方案

主要区别如下:

  • 大小: 由于数据只能存储在数组中连续的内存块中,由于存在覆盖其他数据的风险,因此无法在运行时更改其大小。但是,在链表中,每个节点都指向下一个节点,因此数据可以存在于分散的(不连续的)地址中;这允许可以在运行时更改的动态大小。
  • 内存分配: 用于编译时的数组和运行时的链表。但是,动态分配的数组也会在运行时分配内存。
  • 内存效率: 对于相同数量的元素,链表使用更多的内存作为对下一个节点的引用也与数据一起存储。但是,链表的大小灵活性可能会使它们总体上使用更少的内存;当大小不确定或数据元素的大小变化很大时,这很有用;在使用数组时,必须分配相当于大小上限的内存(即使不是全部都被使用),而链表可以根据数据量逐步增加它们的大小。
  • 执行时间: 数组中的任何元素都可以通过其索引直接访问;然而,在链表的情况下,必须遍历所有先前的元素才能到达任何元素。此外,数组中更好的缓存位置(由于连续内存分配)可以显着提高性能。因此,某些操作(例如修改某个元素)在数组中速度更快,而其他一些操作(例如在数据中插入/删除元素)在链表中速度更快。

以下是支持链表的要点。

(1)数组的大小是固定的:所以我们必须提前知道元素数量的上限。另外,一般来说,分配的内存与使用量无关,都等于上限,在实际使用中,很少达到上限。

(2) 在元素数组中插入一个新元素是昂贵的,因为必须为新元素创建一个房间,并且必须移动现有元素才能创建一个房间。

例如,假设我们在一个数组 id[] 中维护一个排序的 ID 列表。

id[] = [1000, 1010, 1050, 2000, 2040, .....]。

而如果我们要插入一个新的ID 1005,那么为了保持排序顺序,我们必须将1000之后的所有元素(不包括1000)移动。

除非使用一些特殊技术,否则删除数组的代价也很高。例如,要删除 id[] 中的 1010,必须移动 1010 之后的所有内容。

所以链表提供了以下两个优于数组的优点

  1. 动态大小
  2. 易于插入/删除

链表有以下缺点:

  1. 不允许随机访问。我们必须从第一个节点开始按顺序访问元素。所以我们不能对链表进行二分查找。
  2. 列表的每个元素都需要额外的指针存储空间。
  3. 数组具有更好的缓存局部性,可以在性能上产生相当大的差异。
  4. 遍历和改变指针需要很多时间。
  5. 当我们使用指针时会很混乱。
目录
相关文章
|
5天前
|
Java
java数据结构,双向链表的实现
文章介绍了双向链表的实现,包括数据结构定义、插入和删除操作的代码实现,以及双向链表的其他操作方法,并提供了完整的Java代码实现。
java数据结构,双向链表的实现
|
5天前
|
存储 Java
java数据结构,线性表链式存储(单链表)的实现
文章讲解了单链表的基本概念和Java实现,包括头指针、尾节点和节点结构。提供了实现代码,包括数据结构、接口定义和具体实现类。通过测试代码演示了单链表的基本操作,如添加、删除、更新和查找元素,并总结了操作的时间复杂度。
java数据结构,线性表链式存储(单链表)的实现
|
27天前
|
存储 Java 索引
【数据结构】链表从实现到应用,保姆级攻略
本文详细介绍了链表这一重要数据结构。链表与数组不同,其元素在内存中非连续分布,通过指针连接。Java中链表常用于需动态添加或删除元素的场景。文章首先解释了单向链表的基本概念,包括节点定义及各种操作如插入、删除等的实现方法。随后介绍了双向链表,说明了其拥有前后两个指针的特点,并展示了相关操作的代码实现。最后,对比了ArrayList与LinkedList的不同之处,包括它们底层实现、时间复杂度以及适用场景等方面。
42 10
【数据结构】链表从实现到应用,保姆级攻略
|
23天前
|
存储 算法 C语言
数据结构基础详解(C语言):单链表_定义_初始化_插入_删除_查找_建立操作_纯c语言代码注释讲解
本文详细介绍了单链表的理论知识,涵盖单链表的定义、优点与缺点,并通过示例代码讲解了单链表的初始化、插入、删除、查找等核心操作。文中还具体分析了按位序插入、指定节点前后插入、按位序删除及按值查找等算法实现,并提供了尾插法和头插法建立单链表的方法,帮助读者深入理解单链表的基本原理与应用技巧。
|
23天前
|
存储 算法 C语言
C语言手撕实战代码_循环单链表和循环双链表
本文档详细介绍了用C语言实现循环单链表和循环双链表的相关算法。包括循环单链表的建立、逆转、左移、拆分及合并等操作;以及双链表的建立、遍历、排序和循环双链表的重组。通过具体示例和代码片段,展示了每种算法的实现思路与步骤,帮助读者深入理解并掌握这些数据结构的基本操作方法。
|
5天前
|
存储 Java
java数据结构,线性表顺序存储(数组)的实现
文章介绍了Java中线性表顺序存储(数组)的实现。线性表是数据结构的一种,它使用数组来实现。文章详细描述了线性表的基本操作,如增加、查找、删除、修改元素,以及其他操作如遍历、清空、求长度等。同时,提供了完整的Java代码实现,包括MyList接口和MyLinearList实现类。通过main函数的测试代码,展示了如何使用这些方法操作线性表。
|
2月前
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
34 0
|
2月前
|
存储 Java 开发者
揭秘!HashMap底层结构大起底:从数组到链表,再到红黑树,Java性能优化的秘密武器!
【8月更文挑战第24天】HashMap是Java集合框架中的核心组件,以其高效的键值对存储和快速访问能力广受开发者欢迎。在JDK 1.8及以后版本中,HashMap采用了数组+链表+红黑树的混合结构,实现了高性能的同时解决了哈希冲突问题。数组作为基石确保了快速定位;链表则用于处理哈希冲突;而当链表长度达到一定阈值时,通过转换为红黑树进一步提升性能。此外,HashMap还具备动态扩容机制,当负载因子超过预设值时自动扩大容量并重新哈希,确保整体性能。通过对HashMap底层结构的深入了解,我们可以更好地利用其优势解决实际开发中的问题。
60 0
|
2月前
|
存储 Java 程序员
"揭秘HashMap底层实现:从数组到链表,再到红黑树,掌握高效数据结构的秘密武器!"
【8月更文挑战第21天】HashMap是Java中重要的数据结构,采用数组+链表/红黑树实现,确保高效查询与更新。构造方法初始化数组,默认容量16,负载因子0.75触发扩容。`put`操作通过计算`hashCode`定位元素,利用链表或红黑树处理冲突。`get`和`remove`操作类似地定位并返回或移除元素。JDK 1.8优化了链表转红黑树机制,提升性能。理解这些原理能帮助我们更高效地应用HashMap。
34 0
|
2月前
|
算法 索引
【初阶数据结构篇】单链表算法题进阶
深拷贝应该正好由 n 个全新节点组成,其中每个新节点的值都设为其对应的原节点的值。