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

【数据结构与算法学习笔记】数组与链表

前言

本文为个人学习的算法学习笔记,学习笔记,学习笔记不是经验分享与教学,不是经验分享与教学,不是经验分享与教学,若有错误各位大佬轻喷(T^T)。主要使用编程语言为Python3,各类资料题目源于网络,主要自学途径为博学谷,侵权即删。

1. 数组(Array)

1.1 定义与 Python 特性

数组是 “定义了如何组织、存储和管理数据” 的线性结构,核心特征是连续内存空间存储相同类型数据长度固定(创建后不可改)通过下标 / 索引操作数据<RichMediaReference>。Python 中无原生 “固定长度数组”,但可通过list(列表)模拟数组的核心行为(注意:list支持动态扩容,需手动限制以贴合数组 “长度固定” 特性),且list的元素访问逻辑与数组一致 —— 通过下标快速定位。

1.2 核心操作(Python 示例)

(1)查询 / 访问:O (1)(已知下标)、O (n)(未知下标)
  • 随机访问(已知下标):直接通过列表[下标]获取元素,无需遍历,时间复杂度 O (1),对应数组 “通过下标操作数据” 的特性<RichMediaReference>。示例:

    # 模拟数组(限定元素类型为int,手动固定长度)
    arr = [4, 5, 1, 3]  # 基地址可理解为列表在内存中的起始位置(Python无需手动管理地址)
    # 访问下标2的元素(O(1))
    print(arr[2])  # 输出:1,对应公式a[i]_addr = 基地址 + i×数据类型大小<RichMediaReference>
    
  • 顺序查找(未知下标):需从第一个元素遍历至目标元素,最坏情况遍历全部元素,时间复杂度 O (n)<RichMediaReference>。示例:

    def linear_search(arr, target):for i in range(len(arr)):if arr[i] == target:return i  # 返回目标下标return -1  # 未找到arr = [4, 5, 1, 3]
    print(linear_search(arr, 5))  # 输出:1(遍历2次找到)
    print(linear_search(arr, 6))  # 输出:-1(遍历4次,O(n))
    
(2)插入:O (1)(替换)、O (n)(中间 / 开头插入)
  • 替换(已知下标):直接覆盖目标下标元素,无需移动其他数据,时间复杂度 O (1)<RichMediaReference>。示例:

    arr = [4, 5, 1, 3]
    arr[2] = 8  # 替换下标2的元素为8(O(1))
    print(arr)  # 输出:[4, 5, 8, 3]
    
  • 中间 / 开头插入(需移动元素):Pythonlist.insert(下标, 元素)底层会移动插入位置及后续元素,腾出空间,时间复杂度 O (n)<RichMediaReference>。示例:

    arr = [4, 5, 1, 3]
    # 在下标2插入8(需移动1、3至后一位,O(n))
    arr.insert(2, 8)
    print(arr)  # 输出:[4, 5, 8, 1, 3]
    
(3)删除:O (n)(需保持连续)

Pythonlist.pop(下标)会删除目标元素,并将后续元素向前移动以保持连续,最坏情况移动 n 个元素,时间复杂度 O (n)<RichMediaReference>。示例:

arr = [4, 5, 8, 1, 3]
# 删除下标1的元素(5),需移动8、1、3至前一位(O(n))
arr.pop(1)
print(arr)  # 输出:[4, 8, 1, 3]

2. 链表(Linked List)

2.1 定义与节点结构

链表是 “占用非连续内存空间、节点之间通过指针连接、天然支持扩容” 的线性结构,每个节点包含数据域(data) 和指针域(next,指向后续节点),链表两端分别为头节点(head)和尾节点(tail,tail.next = None)。Python 中通过定义节点,通过next属性模拟指针连接。

2.2 核心操作(Python 示例)

(1)节点定义
class Node:def __init__(self, data):self.data = data  # 数据域:存储元素值self.next = None  # 指针域:初始指向None(无后续节点)
(2)遍历:O (n)

需从head开始,通过next指针依次访问每个节点,直到next为 None,时间复杂度 O (n)。示例:

# 构建链表:head → 2 → 3 → 1 → 7 → tail(tail.next = None)
head = Node(2)
node2 = Node(3)
node3 = Node(1)
node4 = Node(7)
head.next = node2
node2.next = node3
node3.next = node4
tail = node4# 遍历链表
def traverse_linked_list(head):current = headwhile current is not None:  # 直到current为None(遍历结束)print(current.data, end=" → ")current = current.nextprint("None")traverse_linked_list(head)  # 输出:2 → 3 → 1 → 7 → None
(3)插入:O (1)(已知前驱节点)

插入的核心是 “修改next指针”,无需移动元素,若已知前驱节点,时间复杂度 O (1)。常见插入场景:

  1. 尾部插入:直接修改尾节点next指向新节点,更新尾节点。示例:

    # 在尾节点7后插入新节点6
    new_node = Node(6)
    tail.next = new_node  # 原尾节点(7)的next指向6
    tail = new_node       # 更新尾节点为6
    tail.next = None      # 确保尾节点next为None
    traverse_linked_list(head)  # 输出:2 → 3 → 1 → 7 → 6 → None
    
  2. 中间插入(已知前驱节点):假设在节点node2(值 3)后插入新节点5。示例:

    new_node = Node(5)
    # 步骤1:新节点next指向前驱节点的原后续节点(node3)
    new_node.next = node2.next
    # 步骤2:前驱节点next指向新节点
    node2.next = new_node
    traverse_linked_list(head)  # 输出:2 → 3 → 5 → 1 → 7 → 6 → None
    
(4)删除:O (1)(已知前驱节点)

删除的核心是 “跳过待删除节点,修改前驱节点next”,无需移动元素,时间复杂度 O (1)。示例:删除中间节点node3(值 1,前驱节点为new_node(值 5)):

# 步骤1:找到前驱节点(pre_node = new_node,待删除节点 = pre_node.next)
pre_node = new_node
del_node = pre_node.next
# 步骤2:前驱节点next指向待删除节点的后续节点(node4)
pre_node.next = del_node.next
# 步骤3:待删除节点next置为None(Python会自动回收内存)
del_node.next = None
traverse_linked_list(head)  # 输出:2 → 3 → 5 → 7 → 6 → None
(5)查询:O (n)

需从head遍历链表,逐一比对data,最坏情况遍历全部节点,时间复杂度 O (n)。示例:查找值为 7 的节点:

def search_linked_list(head, target):current = headindex = 0while current is not None:if current.data == target:return f"目标值{target}在链表中,位置(从0开始):{index}"current = current.nextindex += 1return f"目标值{target}不在链表中"print(search_linked_list(head, 7))  # 输出:目标值7在链表中,位置(从0开始):3
print(search_linked_list(head, 9))  # 输出:目标值9不在链表中

3. 数组与链表核心对比(Python 视角)

对比维度数组(Python list 模拟)链表(Python 类实现)文档依据
内存存储连续内存(list 底层实现)非连续内存(节点分散存储)
长度特性支持动态扩容(需手动限制)天然动态扩容(新增节点即可)
访问效率下标访问 O (1);查找 O (n)遍历 / 查找均 O (n)
插入删除效率中间操作 O (n)(移动元素)已知前驱节点 O (1)(改指针)
Python 适用场景频繁访问(如成绩查询、数据统计)频繁插入删除(如消息队列、任务调度)

关键结论

  • 若需频繁通过下标访问数据,优先用数组(Python list);
  • 若需频繁在中间插入 / 删除数据,优先用链表(Python 类实现),二者选择需贴合文档中 “数据结构与算法相辅相成” 的核心逻辑。
http://www.dtcms.com/a/431229.html

相关文章:

  • [创业之路-644]:通信行业产业链 - 手机端的BP和AP
  • 无锡网站建设方案优化python网站开发用什么
  • 怎样做seo网站链接中国建设银行河北省分行官方网站
  • 网站建设费用表有哪些做壁纸的网站好
  • CentOS7二进制安装包方式部署K8S集群之CA根证书生成
  • 国外网站阻止国内访问怎么做学的网络工程
  • 《UE5_C++多人TPS完整教程》学习笔记60 ——《P61 开火蒙太奇(Fire Montage)》
  • 在wordpress主题后台安装了多说插件但网站上显示不出评论模块wordpress自定义html5
  • 构建AI安全防线:基于越狱检测的智能客服守护系统
  • 树莓派4B下载ubuntu 2504镜像
  • 河北省建设银行网站wordpres做影视网站
  • 电子商务网站建设与管理相关文献wordpress显示最新评论
  • python模块导入冲突问题笔记
  • 红黑树的实现(巨详细!!!)
  • 福州贸易公司网站制作小视频制作
  • 漳州做网站多少钱官方网站后台怎样做超链接
  • 【双指针专题】之移动零
  • 图书馆网站建设教程android studio手机版
  • 网站建设合同报价花果园营销型网站建设
  • 最小二乘问题详解2:线性最小二乘求解
  • Multi-Arith数据集:数学推理评估的关键基准与挑战
  • 基于 Spring Security OAuth2 + JWT 实现 SSO
  • 数智经济时代医疗领域医学影像系统现状与趋势研究:多模态融合技术方向
  • 解读 2025 《高质量数据集 分类指南》
  • 为什么说这个是6dB de-emphasis”(即“6dB去加重”)--Con‘t
  • Eclipse 快捷键
  • 樟木头网站网络安全维护公司
  • 【EE初阶 - 网络原理】网络通信
  • 方案网站有哪些盗用别的公司网站模块
  • 做网站是否要去工商备案做网站群