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

第3章现象表:比较顺序表和链表

3.7 比较顺序表和链表

顺序表和链表都是表示线性表的存储结构,本节从不同角度对二者进行比较。

1. 存储结构

  • 顺序表存储结构
#define MAXSIZE 100
typedef struct{ElemType *elem;    //存储空间的基地址int length;        //当前长度
}SqList;               //顺序表的结构类型为 SqList
  • 单链表存储结构
typedef struct LNode{ElemType data;  //结点的数据域struct LNode * next; //结点的指针域
}LNode, *LinkList;  //LinkList 为指向结构体 LNode 的指针类型
  • 双向链表存储结构
typedef struct DuLNode{ElemType data;  //数据域struct DuLNode *prior;  //直接前驱struct DuLNode *next;   //直接后继
}DuLNode, *DuLinkList;

2. 空间性能比较

(1)存储空间的分配

  • 顺序表的存储空间必须预先分配,元素个数扩充受一定限制,易造成存储空间浪费或空间溢出现象

  • 链表不需要为其预先分配空间,只要内存空间允许,链表中的元素个数就没有限制。

当线性表的长度变化较大,难以预估存储规模时,宜采用链表作为存储结构。

(2)存储密度的大小

  • 存储密度是指数据元素本身所占用的存储量和整个结点结构所占用的存储量之比,即:
    存储密度=数据元素本身占用的存储量结点结构占用的存储量 \text{存储密度}=\frac{\text{数据元素本身占用的存储量}}{\text{结点结构占用的存储量}} 存储密度=结点结构占用的存储量数据元素本身占用的存储量
    存储密度越大,存储空间的利用率就越高。

  • 链表的每个结点除了设置数据域用来存储数据元素之外,还要额外设置指针域,用来存储指示元素之间逻辑关系的指针。

  • 顺序表的存储密度为 1(不考虑顺序表的空闲区)。

  • 链表的存储密度小于 1。例如单链表,若结点的数据为整数,指针所占用的空间和整型量相同,则单链表的存储密度为 0.5 。

当线性表的长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表作为存储结构。

角度顺序表链表
存储方式连续内存空间离散内存空间(节点通过指针连接)
存储密度高(仅存储数据)低(需额外存储指针)
动态扩容需重新分配内存(可能复制数据)动态申请节点,无需整体扩容

3. 时间性能比较

(1)存取元素的效率

  • 顺序表是用数组实现的,它是一种随机存取结构,指定任意一个位置序号 iii ,都可以在 O(1)O(1)O(1) 时间内直接存取该位置上的元素,即取值操作的效率高。

  • 链表是一种顺序存取结构,按位置访问链表中第 iii 个元素时,只能从表头开始依次向后遍历链表,直到找到第 iii 个位置上的元素,时间复杂度为 O(n)O(n)O(n) ,即取值操作的效率低。

若线性表的主要操作是和元素位置紧密相关的这类取值操作,很少做插入或删除时宜采用顺序表作为存储结构。

角度顺序表链表
随机访问O(1)O(1)O(1)(直接通过下标访问)O(n)O(n)O(n)(需从头遍历)
顺序访问O(n)O(n)O(n)O(n)O(n)O(n)

(2)插入和删除操作的效率

  • 对于链表,在确定插入或删除的位置后,插入或删除操作无需移动数据,只需要修改指针,时间复杂度为 O(1)O(1)O(1)
  • 对于顺序表,进行插入或删除时,需要移动表中的结点,时间复杂度为 O(n)O(n)O(n)。尤其是当每个结点的信息量较大时,移动结点的时间开销就相当可观。

对于频繁进行插入或删除操作的线性表,宜采用链表作为存储结构。

角度顺序表链表
头部插入/删除O(n)O(n)O(n)(需移动所有元素)O(1)O(1)O(1)(修改指针)
尾部插入/删除O(1)O(1)O(1)(若空间足够)O(1)O(1)O(1)(需维护尾指针)
中间插入/删除O(n)O(n)O(n)(需移动部分元素)O(n)O(n)O(n)(需先遍历到位置)

4. 适用场景

场景顺序表链表
频繁查询✔️(随机访问快)❌(需遍历)
频繁增删❌(移动元素开销大)✔️(指针修改快)
数据规模固定✔️(无需扩容)❌(指针额外开销)
数据规模变化大❌(扩容成本高)✔️(动态增长)
缓存友好性✔️(局部性好)❌(指针跳转不连续)

说明:

  • 顺序表适用:
    • 数据量固定或变化小。
    • 需要高效随机访问(如数组、矩阵运算)。
  • 链表适用:
    • 数据频繁增删(如队列、栈、动态列表)。
    • 数据规模变化大(如内存池管理)。
http://www.xdnf.cn/news/18147.html

相关文章:

  • 记录 GMS 认证相关条件
  • Leetcode 14 java
  • A*寻路算法:原理、实现与优化指南
  • 【Java笔记】synchronized
  • SpringBoot学习日记(九)
  • 游戏客户端性能测试总结
  • 【渗透实战】无下载器环境(curl/wget)下玩转 Metasploit 自动利用
  • [创业之路-550]:公司半年度经营分析会 - 解决方案汇总
  • “preinstall“: “npx only-allow pnpm“
  • WrenAI部署,解决发送消息报错:failed to create asking task
  • Day15 Docker
  • Java设计模式详细解读
  • uv - 基本使用
  • 三天速通 Vue+Flask+SQLite 项目+阿里云轻量应用级服务器【宝塔面板】②
  • autofit.js: 自动调整HTML元素大小的JavaScript库
  • 神经网络 常见分类
  • Java Stream sort算子实现:SortedOps
  • 《设计模式》装饰模式
  • AI可行性分析:数据×算法×反馈=成功
  • 基于GIS的无人机模拟飞行控制系统设计与实现
  • K8S的ingress
  • 模式组合应用-桥接模式(一)
  • VS Code配置MinGW64编译GLPK(GNU Linear Programming Kit)开源库
  • 一键检测接口是否存活:用 Python/Shell 写个轻量级监控脚本
  • 《MySQL 数据库备份与视图创建全流程:从数据迁移到高效查询实战》
  • 【AI论文】NextStep-1:迈向大规模连续令牌自回归图像生成
  • 2020/12 JLPT听力原文 问题二 2番
  • HackMyVM-Uvalde
  • 高等数学 8.4 空间直线及其方程
  • macOS 中查看当前生效 shell 及配置文件的方法