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

数据结构01:链表

数据结构

链表

链表和数组的区别

1. 存储方式

  • 数组
    • 元素在内存中连续存储,占用一块连续的内存空间
    • 元素的地址可以通过索引计算(基地址 + 索引 × 元素大小)
    • 大小固定,在创建时需要指定容量
  • 链表
    • 元素(节点)在内存中分散存储,不要求连续
    • 每个节点包含数据和指向下一个(或上一个)节点的指针
    • 大小动态变化,可根据需要随时增减节点

2. 访问效率

  • 数组
    • 支持随机访问,通过索引可以直接访问任意元素,时间复杂度为 O (1)
    • 访问效率高,适合需要频繁随机访问的场景
  • 链表
    • 不支持随机访问,必须从表头(或表尾)开始依次遍历,时间复杂度为 O (n)
    • 访问效率低,不适合需要频繁随机访问的场景

3. 插入和删除操作

  • 数组
    • 插入 / 删除元素时,需要移动该位置后的所有元素,时间复杂度为 O (n)
    • 尤其在数组头部操作时效率极低
    • 动态扩容时需要重新分配内存并复制元素
  • 链表
    • 插入 / 删除元素时,只需修改相关节点的指针,时间复杂度为 O (1)(已知前驱节点时)
    • 不需要移动其他元素,操作效率高
    • 没有扩容问题,内存利用率更高

4. 内存占用

  • 数组
    • 可能存在内存浪费(预分配的容量可能大于实际需要)
    • 内存利用率较低
  • 链表
    • 每个节点需要额外存储指针信息,有一定内存开销
    • 但整体内存利用率更高,不会浪费空间

5. 适用场景

  • 数组
    • 适合需要频繁随机访问元素的场景(如查找操作多)
    • 元素数量固定或变化不大的情况
    • 例如:数据库索引、矩阵存储、缓存实现等
  • 链表
    • 适合需要频繁插入和删除元素的场景
    • 元素数量动态变化较大的情况
    • 例如:链表式队列 / 栈、哈希表链地址法冲突解决、邻接表等

总结对比表

特性数组链表
存储方式连续内存分散内存 + 指针
随机访问支持 (O (1))不支持 (O (n))
插入删除低效 (O (n))高效 (O (1))
内存效率可能浪费空间有指针开销但利用率高
大小固定动态
  • 数组中的数据我们称之为元素

  • 链表中的数据我们称之为节点

    每一个节点都是一个结构体,当前结构体包含两种信息

    1. 数据(每个节点中所存储的信息)
    2. 节点指针(保存下一个节点的信息)
    将节点插入链表:头插法/尾插法/中间插入

    eg:

                                                节点对应结构体
typedef struct Node 
{int num;		   /每个节点中存储的数据,可以有多个struct Node* pNext;   /用于保存下一个节点(结构体)的指针
} Node;函数功能:      创建一个节点int n --------当前节点的数据NODE*  head---------当前链表首节点地址返回类型:成功返回当前节点首地址,失败返回NULLNODE* createNode(int n,NODE* head)
{//创建一个新节点NODE* pNew = (NODE*)malloc(sizeof(NODE));if(pNew == NULL){printf("createNode %d fail:%s!\n",n,strerror(errno));return NULL;}//初始化新节点中的成员变量pNew -> num = n;pNew -> pNext = NULL;//返回当前节点的首地址return pNew;}函数功能:      删除整个链表NODE*  head---------当前链表首节点地址void distroyList(NODE* head){if(head == NULL){return;}NODE* P = head;while(p != NULL){head = p -> pNext;free(p);p = head;}}函数功能:    输出整个链表NODE*  head---------当前链表首节点地址返回类型:成功返回当前节点首地址,失败返回NULLvoid displayList(NODE* head){while(p != NULL){printf("%d",p->num);p = p->pNext;}}                                  void insert_head1(int n,NODE** head)
{//创建新节点NODE*  pNew = createNode(n);//如果是空链表if(*head == NULL){*head = pNew;return}//新节点指向原链表的首节点pNew -> pNext = *head;//将新节点的起始地址给*head*head = pNew;}NODE*	 insert_head2(int n,NODE* head)
{NODE*  pNew = createNode(n);//如果是空链表if(head == NULL){return pNew;}pNew -> pNext = *head;//将新节点的起始地址给*headreturn  pNew;}//插入到结尾NODE* insert_tail(int n, NODE* head)
{//创建节点NODE* pNew == createNode(n);if(pNew == NULL){return pNew;}//获取原链表尾节点的指针NODE* pTail = getTaiilNode(head);if(pTail) = getTaiilNode(head);{return pNew;}pTail ->P=pNext = pNew;return head;}NODE* insertNode(int n,NODE* head,int pos)
{}int main()
{// 用于记录当前链表中首节点的地址NODE* pHead = NULL;// 将节点插入链表中:头插法//insert_head1(5, &pHead);//insert_head1(4, &pHead);//insert_head1(3, &pHead);//insert_head1(2, &pHead);//insert_head1(1, &pHead);//pHead = insert_head2(-5, pHead);//pHead = insert_head2(-4, pHead);//pHead = insert_head2(-3, pHead);//pHead = insert_head2(-2, pHead);//pHead = insert_head2(-1, pHead);// 将节点插入链表中:尾插法//pHead = insert_tail(1, pHead);//pHead = insert_tail(2, pHead);//pHead = insert_tail(3, pHead);//pHead = insert_tail(4, pHead);// 将节点插入链表中:任意位置插入// 假设位置 0 代表头插pHead = insertNode(1, pHead, 3);displayList(pHead);distroyList(pHead);return 0;
}
http://www.dtcms.com/a/292965.html

相关文章:

  • FashionAI / 智尚衣橱 / TryFit / 智能时尚搭配平台
  • 面试150 N皇后Ⅱ
  • Docker环境搭建RabbitMq集群详解
  • 【CAN】2.帧格式
  • ReasonFlux:基于思维模板与分层强化学习的高效推理新范式
  • Python接口自动化实战 ( 第一阶段) - 封装接口请求类和异常处理
  • Ubuntu 虚拟机配置 与Windows互传文件
  • react19相关问题和解答
  • 【技术新闻】OpenAI发布GPT-5,AI编程助手迎来革命性突破
  • React集成百度【BMap Draw】教程(001):实现距离测量和面积测量
  • dubbo源码分析之请求调用异步化原理
  • Pandas核心数据结构详解
  • 第3章通用的服务可用性治理手段——3.2 重试
  • Kotlin 作用域函数 let 的实现原理
  • 大疆视觉算法面试30问全景精解
  • 基于Java+MySQL实现(Web)文件共享管理系统(仿照百度文库)
  • Java自动拆箱机制
  • 云祺容灾备份系统阿里云对象存储备份与恢复实操手册
  • List<UserInfo> list = new ArrayList<>();为什么要这样创建数组?
  • 智能文本抽取在法院卷宗管理应用剖析
  • 力扣-139.单词拆分
  • Qt 网络编程如何采用Http进行通信
  • 碳化硅缺陷分类与原因
  • C++的lambda表达式原理
  • 【RK3576】【Android14】MIC开发调试
  • 【iOS】SideTable
  • [学习] 笛卡尔坐标系的任意移动与旋转详解
  • 交叉编译opencv(Cpp)于arm64架构开发板上
  • AI 音频产品开发模板及流程(二)
  • 使用python中的pymysql库,并且转化为数组元组数据