深入理解数据结构:数组、链表与列表

devtools/2024/12/21 19:39:45/

概述: 在编程的世界里,数据结构如同构建高楼大厦的基石,其中数组、链表和列表是最为常见且基础的数据结构。本文将深入探讨这三种数据结构的定义、基本概念、常用操作、常见类型、优点和局限性以及它们在实际编程中的应用。通过详细的解释和 Python 代码示例,帮助读者更好地理解和掌握这些重要的数据结构

一、数组

定义与基本概念

  • 数组是一种线性数据结构,它由一系列相同类型的元素组成,并按照一定的顺序存储在连续的内存空间中。可以通过索引快速访问数组中的元素,索引从 0 开始。
  • 常用操作

  • 访问元素

    目录

    一、数组

    定义与基本概念

    常用操作

    访问元素

    修改元素

    插入元素

    删除元素

    常见类型

    优点

    局限性

    应用

    二、链表

    定义与基本概念

    常用操作

    初始化及实现

    访问元素

    修改元素

    插入元素

    删除元素

    常见类型

    优点

    局限性

    应用

    三、列表

    定义与基本概念

    常用操作

    访问元素

    修改元素

    插入元素

    删除元素

    常见类型

    优点

    局限性

    应用

    数组VS链表VS列表

    总结

    结束语


  • 通过索引可以在常数时间内访问数组中的特定元素。
  • python"># 创建一个整数数组
    arr = [1, 2, 3, 4, 5]
    # 访问索引为 2 的元素
    print(arr[2])  # 输出 3

修改元素

可以直接通过索引修改数组中的元素值。

python">arr = [1, 2, 3, 4, 5]
# 修改索引为 2 的元素为 6
arr[2] = 6
print(arr)  # 输出 [1, 2, 6, 4, 5]

插入元素

在数组中插入元素可能需要移动其他元素以腾出空间,时间复杂度取决于插入的位置。

python">arr = [1, 2, 3, 4, 5]
# 在索引为 2 的位置插入元素 7
arr.insert(2, 7)
print(arr)  # 输出 [1, 2, 7, 3, 4, 5]

删除元素

删除元素也可能需要移动其他元素来填补空缺,时间复杂度同样取决于删除的位置。

python">arr = [1, 2, 3, 4, 5]
# 删除索引为 2 的元素
del arr[2]
print(arr)  # 输出 [1, 2, 4, 5]

常见类型

  • 一维数组:存储一系列相同类型的元素,是最基本的数组类型。
  • 多维数组:例如二维数组可以表示矩阵等结构。

优点

  • 随机访问速度快,可以在常数时间内通过索引访问元素;
  • 存储效率高,因为元素在内存中是连续存储的;
  • 缓存局部性

局限性

  • 大小固定,在创建数组时需要预先指定大小,一旦确定后难以更改。

  • 插入和删除元素可能需要移动大量元素,时间复杂度较高。

  • 插入与删除效率低

  • 长度不可变

  • 空间浪费

应用

  • 随机访问
  • 排序和搜索
  • 查找表
  • 机器学习--神经网络
  • 数据结构实现--可通过组合实现其他数据结构

二、链表

定义与基本概念

  • 链表是一种线性数据结构,由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
  • 链表中的元素可以不连续地存储在内存中。

常用操作

初始化及实现

可以通过定义节点类来实现链表。每个节点包含数据和指向下一个节点的指针。链表的初始化通常是创建一个空链表,即头节点为 None。
插入节点时,根据插入的位置,修改相应节点的指针,使其指向新节点,新节点再指向下一个节点。
删除节点时,找到要删除的节点,将其前一个节点的指针指向其后一个节点,从而将该节点从链表中移除。

python">class ListNode:def __init__(self, value=0, next=None):self.value = valueself.next = next# 创建链表
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node1.next = node2
node2.next = node3


访问元素

需要从头节点开始遍历链表,直到找到目标节点,时间复杂度为 O (n)。

python"># 访问元素
current = node1
while current:print(current.value)current = current.next

修改元素

找到目标节点后可以直接修改其数据值。

python">current = node1
while current.value!= 2:current = current.next
current.value = 6

插入元素

可以在链表的任意位置插入新节点,只需修改相应节点的指针,时间复杂度为 O (1)(在已知插入位置的情况下)。

python">new_node = ListNode(4)
new_node.next = node2
node1.next = new_node

删除元素

删除节点也只需修改相应节点的指针,时间复杂度为 O (1)(在已知删除位置的情况下)。

python">current = node1
while current.next.value!= 6:current = current.next
current.next = current.next.next

常见类型

  • 链表:每个节点只有一个指向下一个节点的指针。
  • 双向链表:每个节点有两个指针,分别指向前一个节点和下一个节点。
  • 循环链表:最后一个节点的指针指向头节点,形成一个循环。

优点

  • 灵活扩展,,动态大小,可以根据需要随时添加或删除节点。

  • 分散存储

  • 插入和删除元素的时间复杂度低,不需要移动大量元素。

局限性

  • 随机访问速度慢,需要遍历链表才能访问特定元素。

  • 占用额外的内存空间来存储指针。

应用

  • 实现栈和队列。

  • 用于处理动态数据集合,如文件系统中的目录结构。

三、列表

定义与基本概念

  • 在 Python 中,列表是一种可变序列数据类型,可以存储任意类型的元素。

  • 列表内部实现可以是数组或链表,具体取决于实现方式和操作的特点。

常用操作

访问元素

可以通过索引快速访问列表中的元素。

python">lst = [1, 'two', 3.0] # 初始化
# 访问索引为 1 的元素
print(lst[1])  # 输出 'two'

修改元素

可以直接通过索引修改列表中的元素值。

python">lst = [1, 'two', 3.0]
# 修改索引为 1 的元素
lst[1] = 'two changed'
print(lst)  # 输出 [1, 'two changed', 3.0]

插入元素

可以在列表的任意位置插入元素,时间复杂度取决于插入的位置和列表的实现方式。

python">lst = [1, 'two', 3.0]
# 在索引为 1 的位置插入元素 'inserted'
lst.insert(1, 'inserted')
print(lst)  # 输出 [1, 'inserted', 'two', 3.0]

删除元素

可以删除列表中的特定元素,时间复杂度同样取决于删除的位置和实现方式。

python">lst = [1, 'two', 3.0]
# 删除元素 'two'
lst.remove('two')
print(lst)  # 输出 [1, 3.0]

常见类型

  • 普通列表:可以存储任意类型的元素。
  • 嵌套列表:列表中可以包含其他列表。

优点

  • 灵活多变,可以存储不同类型的元素。
  • 提供了丰富的内置方法,方便进行各种操作。

局限性

  • 对于大量数据的操作,性能可能不如专门的数据结构
  • 存储不同类型的元素可能导致类型检查和处理的复杂性增加。

应用

  • 存储和处理各种类型的数据集合。
  • 作为函数的参数和返回值,传递一组数据。

数组VS链表VS列表

数据结构

初始化方式

随机访问

插入 / 删除(特定位置)

动态大小

存储方式

数组

指定大小创建

快(O (1))

慢(可能需要移动大量元素)

固定大小

连续内存空间

链表

创建头节点为 None 的链表

慢(O (n))

快(O (1),已知位置)

动态大小

非连续内存空间,通过指针连接

列表

直接使用方括号创建

较快(取决于实现方式)

较快(取决于实现方式)

动态大小

内部实现可能是数组或链表

总结

数组、链表和列表是编程中非常基础且重要的数据结构。数组适合需要快速随机访问的场景,但大小固定且插入删除操作成本较高。链表则在动态大小和高效的插入删除操作方面具有优势,但随机访问速度较慢。列表在 Python 中提供了极大的灵活性,可以存储不同类型的元素,但在性能上可能有所牺牲。了解这些数据结构的特点和应用场景,能够帮助我们在编程中选择合适的数据结构来解决问题,提高程序的效率和性能。

结束语

希望本文对数组、链表和列表的深入探讨能为你在编程之路上提供有力的支持。数据结构的选择往往决定了程序的性能和可维护性,通过不断地学习和实践,我们可以更好地掌握各种数据结构的特点,从而编写出更加高效、优雅的代码。如果你对本文中的内容有任何疑问或建议,欢迎在评论区留言交流。


http://www.ppmy.cn/devtools/144162.html

相关文章

15.3、陷阱技术 入侵容忍 隐私保护技术

目录 网络攻击陷阱技术与应用蜜罐主机技术陷阱网络技术三代陷阱网络网络攻击陷阱技术应用入侵容忍及系统生存技术入侵容忍及系统生存技术应用隐私保护技术网络安全的前沿技术发展动向 网络攻击陷阱技术与应用 攻击陷阱技术也叫诱骗技术,它是一种主动防御的方法&…

Gunicorn启动Django服务

使用 Gunicorn 来运行 Django 项目可以提升性能,特别是在生产环境中。Gunicorn 是一个 Python WSGI HTTP 服务器,适合用于在多个工作进程中运行 Python 的 Web 应用。以下是如何在本地使用 Gunicorn 启动 Django 项目的步骤: 步骤 1: 安装 G…

项目管理工具Maven(一)

Maven的概念 什么是Maven 翻译为“专家”,“内行”Maven是跨平台的项目管理工具。主要服务于基于Java平台的项目构建,依赖管理和项目信息管理。什么是理想的项目构建? 高度自动化,跨平台,可重用的组件,标准…

谷歌发布首个 AI 推理模型欲挑战 OpenAI o1,AI 领域将展开新的竞争

简介 在人工智能领域,创新的浪潮从未停止。2024年12月20日凌晨谷歌推出首个 AI 推理模型 Gemini 2.0 Flash Thinking,正式向 OpenAI o1 模型发起挑战。这一事件无疑为 AI 领域的竞争注入了新的活力,也让我们对未来的人工智能发展充满了期待。…

MCP技术与Cline集成指南:打造智能AI助手的数据连接解决方案

引言 Model Context Protocol(MCP)是由Anthropic推出的一种全新开放标准,旨在为AI助手提供与数据源之间的安全连接能力。通过MCP技术,开发者可以实现AI助手与内容存储库、业务工具和开发环境的无缝集成,从而帮助前沿模…

从 Promise 到 Axios:轻松解锁异步编程

如果你正在开发中处理异步任务,比如网络请求、文件操作,或者用户交互的处理,那么你一定接触过 Promise 和 Async/Await。它们是现代 JavaScript 异步编程的基石。本文将带你一步步深入了解,帮助你弄清它们的背景、解决的问题以及实…

应该连续学一个科目,还是多学科切换?

https://www.zhihu.com/question/333420829https://www.zhihu.com/question/333420829

初学stm32 --- 系统时钟配置

众所周知,时钟系统是 CPU 的脉搏,就像人的心跳一样。所以时钟系统的重要性就不言而喻了。 STM32 的时钟系统比较复杂,不像简单的 51 单片机一个系统时钟就可以解决一切。于是有人要问,采用一个系统时钟不是很简单吗?为…