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

顺序表VS单链表

1. 顺序表与链表的应用场景

在数据结构中,顺序表和单链表是两种最基础的线性存储结构,它们的实现方式和适用场景截然不同:

  • 顺序表:适合频繁查询尾部操作的场景。

  • 单链表:适合频繁插入/删除且数据量动态变化的场景。

2. 概念对比 

特性顺序表单链表
存储方式连续内存空间(数组)非连续内存空间(节点通过指针链接)
随机访问支持,时间复杂度 O(1)不支持,需遍历,时间复杂度 O(n)
动态扩容需重新分配内存并拷贝数据按需动态分配,无需扩容
内存占用空间预分配,可能存在浪费按需分配,无额外空间浪费
缓存友好性高(内存连续,缓存命中率高)低(内存分散,缓存局部性差)

 3. 存储结构与内存管理

(1) 顺序表的存储结构

typedef struct SeqList {SLDataType* arr;    // 动态数组指针int capacity;       // 总容量int size;           // 当前元素个数
} SL;
  • 特点:内存连续,通过数组索引直接访问元素。

  • 扩容机制:容量不足时按倍数(如2倍)扩容,涉及内存拷贝(realloc)。

 (2) 单链表的存储结构

typedef struct SListNode {SLTDataType data;    // 数据域struct SListNode* next; // 指针域
} SLTNode;
  • 特点:每个节点独立分配内存,通过指针链接。

  • 内存管理:插入时动态分配节点(malloc),删除时释放节点(free)。

4. 基本操作的实现与时间复杂度 

(1) 插入操作

操作顺序表单链表
头部插入O(n),需移动所有元素O(1),修改头指针
尾部插入O(1)(不考虑扩容)O(n),需遍历到尾部
指定位置插入O(n),平均移动 n/2 个元素O(n),需遍历到前驱节点
// 顺序表尾部插入
void SLPushBack(SL* ps, SLDataType x) {SLCheckCapacity(ps); // 检查扩容ps->arr[ps->size++] = x;
}// 单链表头部插入
void SLTPushFront(SLTNode** pphead, SLTDataType x) {SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;*pphead = newnode; // 直接修改头指针
}

(2) 删除操作

操作顺序表单链表
头部删除O(n),需移动所有元素O(1),修改头指针
尾部删除O(1),直接减少sizeO(n),需遍历到倒数第二个节点
指定位置删除O(n),平均移动 n/2 个元素O(n),需遍历到前驱节点
// 顺序表尾部删除
void SLPopBack(SL* ps) {assert(ps->size > 0);ps->size--; // 逻辑删除
}// 单链表头部删除
void SLTPopFront(SLTNode** pphead) {SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next; // 更新头指针
}

(3) 查找操作

  • 顺序表:直接通过下标访问(O(1))。

  • 单链表:需从头节点遍历(O(n))。

(4) 指针使用的区别

场景顺序表单链表
头指针操作通过结构体指针直接操作数组(SL* ps)。需使用双重指针(SLTNode** pphead)修改头指针。
节点访问通过下标直接访问(arr[i])。需遍历指针链(pcur = pcur->next)。

 关键点解释:
单链表中若需修改头指针(如头部插入/删除),必须传递头指针的地址(SLTNode**),否则函数内部修改的是局部变量副本,无法影响外部指针。

 5. 优缺点总结

顺序表的优缺点

  • 优点

  1. 随机访问速度快。
  2. 内存连续,缓存命中率高。
  • 缺点

  1. 插入/删除效率低。
  2. 扩容成本高,可能浪费内存。

单链表的优缺点

  • 优点

  1. 插入/删除灵活,无需移动元素。
  2. 内存按需分配,无空间浪费。
  • 缺点

  1. 不支持随机访问。
  2. 指针占用额外内存(每个节点多一个指针空间)。

6. 实际应用中的选择建议

  • 选择顺序表

  1. 需要频繁随机访问(如数组排序、二分查找)。
  2. 数据量相对固定,尾部操作频繁。
  • 选择单链表

  1. 需要频繁插入/删除(如实现队列、撤销操作栈)。
  2. 数据量动态变化且不可预测。
http://www.xdnf.cn/news/8070.html

相关文章:

  • RuntimeError: Cannot find sufficient samples, consider increasing dataset size.
  • 【Tauri2】047——Image
  • gcc还会有自己的头文件呢?
  • CMake 跨平台构建系统详解
  • 友达15.6寸G156HAN02.3工业显示模组
  • 在Linux系统上备份另一个系统的做法
  • 数据库主从集群 + GTID 实现高可用
  • inlier_outlier
  • 视觉大模型学习总结
  • 通过 curl 精准定位问题
  • 从零开始的嵌入式学习day25
  • Java SSM与SpringBoot面试题全面解析:从基础到源码
  • 线性表数据结构-队列
  • 8:点云处理—常见的四种3D相机
  • 今日行情明日机会——20250521
  • 探索Puter:一个基于Web的轻量级“云操作系统”
  • Java基础 5.21
  • 重磅升级!Google Play商店改版上线
  • Web服务器
  • C++语言的跨平台挑战和应对策略
  • centos7 p8p1使用ip addr查看时有的时候有两个ip,有的时候只有一个ip,有一个ip快,有一个ip慢
  • 如何在 Windows 10 或 11 上使用命令提示符安装 Angular
  • Vue Router动态路由与导航守卫实战
  • RESTful风格
  • 从零基础到最佳实践:Vue.js 系列(6/10):《Composition API(组合式 API)》
  • 论文篇目录-研究生如何阅读编写论文
  • Linux系统编程-DAY02
  • 直播美颜SDK技术解析:滤镜渲染与动态贴纸引擎融合的底层实现
  • 机器学习第二十讲:网格搜索 → 像尝试所有密码组合找最佳解锁方式
  • Python爬虫实战:获取天气网最近一周北京的天气数据,为日常出行做参考