深入浅出链表:从结构体到数组的两种实现方式

深入浅出链表:从结构体到数组的两种实现方式

深入浅出链表:从结构体到数组的两种实现方式

本文 Bilibili 视频地址

链表作为计算机科学中最基础也最重要的数据结构之一,其灵活性和动态性使其在各种场景下都有广泛应用。本文将带你深入探索链表的两种实现方式:经典的结构体实现和高效的数组实现。

一、链表的基本概念

链表是一种线性的、动态的数据结构,由一系列节点(Node)通过指针(或引用)连接而成。与数组不同,链表中的元素在内存中不是连续存储的,而是通过每个节点中的指针域来维护逻辑上的连续性。

链表的主要特点包括:

  • 动态大小:可以随时增加或删除节点,无需预先分配固定空间
  • 高效插入/删除:在已知位置插入或删除节点的时间复杂度为O(1)
  • 顺序访问:只能从头节点开始顺序访问,不支持随机访问

二、结构体实现链表

2.1 节点结构定义

在C/C++中,我们通常使用结构体来定义链表节点:

structNode{int data;// 数据域,存储节点值 Node* next;// 指针域,指向下一个节点};
类比说明:这个结构体定义类似于JavaScript中的类或Java中的对象。Node* next相当于Java中的引用,指向下一个节点对象。

2.2 链表构建与遍历

让我们构建一个包含四个节点(数据分别为1、2、3、4)的链表:

头节点

1

2

3

4

NULL

// 创建节点函数 Node*createNode(int value){ Node* newNode = new Node(); newNode->data = value; newNode->next = nullptr;return newNode;}// 构建链表 Node* head =createNode(1); head->next =createNode(2); head->next->next =createNode(3); head->next->next->next =createNode(4);// 遍历链表voidtraverseList(Node* head){ Node* p = head;while(p != nullptr){ cout << p->data <<" "; p = p->next;}}

遍历过程说明:

  1. 初始化指针p指向头节点
  2. p不为空时,输出当前节点数据
  3. p移动到下一个节点(p = p->next
  4. 重复步骤2-3直到链表末尾

2.3 结构体实现的优缺点

优点缺点
直观易懂,符合链表逻辑模型内存分配不连续,可能导致缓存不命中
动态内存分配,灵活性强频繁的内存分配/释放可能产生内存碎片
插入/删除操作高效每个节点需要额外空间存储指针

三、数组实现链表

3.1 实现原理

数组实现链表的核心思想是用数组下标代替内存地址,将链表拆分为两个数组:

  • data[]:存储节点的数据值
  • next[]:存储下一个节点的数组下标(相当于指针)

data: 0, next: 1

data: 1, next: 2

data: 2, next: 4

data: 100, next: 0

data: 3, next: 3

3.2 代码实现

constint MAX_SIZE =100;int data[MAX_SIZE];// 数据域int next[MAX_SIZE];// 指针域(存储下一个节点的下标)int head =3;// 头节点下标int freeIdx =0;// 当前空闲位置// 初始化voidinit(){for(int i =0; i < MAX_SIZE -1; i++){ next[i]= i +1;// 初始化空闲链表} next[MAX_SIZE -1]=0;// 0表示NULL}// 在index节点后插入值为value的节点voidinsertAfter(int index,int value){if(freeIdx ==0)return;// 空间已满int p = freeIdx;// 获取空闲位置 freeIdx = next[freeIdx];// 更新空闲链表头 data[p]= value;// 设置节点值 next[p]= next[index];// 新节点指向原后继 next[index]= p;// 前驱指向新节点}

3.3 构建与访问示例

构建一个链表,数据为0、1、2、3、100:

// 构建链表init();insertAfter(head,0);// 在头节点后插入0insertAfter(next[head],1);insertAfter(next[next[head]],2);insertAfter(next[next[next[head]]],3);insertAfter(next[next[head]],100);// 在2后面插入100// 遍历链表voidtraverse(){int p = head;while(p !=0){ cout << data[p]<<" "; p = next[p];}}

3.4 数组实现的性能特点

特点说明
内存连续数据存储在连续内存中,缓存友好
静态大小需要预先分配固定大小的数组
高效内存利用没有指针开销,适合内存受限环境
实现复杂需要手动管理空闲节点

四、两种实现方式对比

特性结构体实现数组实现
内存分配动态静态
内存连续性不连续连续
缓存性能较差较好
最大节点数理论上无限制受数组大小限制
适用场景通用场景内存受限/性能敏感场景

五、实际应用建议

  1. 常规开发:优先选择结构体实现,代码更直观,维护更方便
  2. 嵌入式/性能敏感:考虑数组实现,减少内存碎片,提高缓存命中率
  3. 竞赛编程:数组实现更常见,因为通常有明确的数据规模限制

结语

链表作为一种基础数据结构,其实现方式的选择往往取决于具体的应用场景和性能需求。理解这两种实现方式的原理和差异,能够帮助我们在实际开发中做出更合理的选择。无论是结构体实现的优雅直观,还是数组实现的高效紧凑,都体现了计算机科学中"同一个问题,多种解法"的精妙之处。

深入浅出链表:从结构体到数组的两种实现方式

希望本文能帮助你更深入地理解链表的本质,在未来的编程实践中灵活运用这两种实现方式!

Read more

【Linux 系列】Linux 命令/快捷键详解

【Linux 系列】Linux 命令/快捷键详解

🚀 欢迎来到我的ZEEKLOG博客:Optimistic _ chen ✨ 一名热爱技术与分享的全栈开发者,在这里记录成长,专注分享编程技术与实战经验,助力你的技术成长之路,与你共同进步! 🚀我的专栏推荐: 专栏内容特色适合人群🔥C语言从入门到精通系统讲解基础语法、指针、内存管理、项目实战零基础新手、考研党、复习🔥Java基础语法系统解释了基础语法、类与对象、继承Java初学者🔥Java核心技术面向对象、集合框架、多线程、网络编程、新特性解析有一定语法基础的开发者🔥Java EE 进阶实战Servlet、JSP、SpringBoot、MyBatis、项目案例拆解想快速入门Java Web开发的同学🔥Java数据结构与算法图解数据结构、LeetCode刷题解析、大厂面试算法题面试备战、算法爱好者、计算机专业学生 🚀我的承诺: ✅ 文章配套代码:每篇技术文章都提供完整的可运行代码示例 ✅ 持续更新:专栏内容定期更新,紧跟技术趋势 ✅ 答疑交流:欢迎在文章评论区留言讨论,我会及时回复(支持互粉) 🚀 关注我,解锁更多技术干货! ⏳ 每天进步一点点,

By Ne0inhk
Linux 进程间通信之管道基础解析 —— 匿名管道的原理与实现

Linux 进程间通信之管道基础解析 —— 匿名管道的原理与实现

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 一. 进程间通信基础认知 * 1.1 进程间通信的核心目的 * 1.2 进程间通信的发展与分类 * 二. 管道的基础概念 * 2.1 管道的定义 * 2.2 管道的核心特性(最后总结部分的图片里更全点,可以着重看那个) * 三. 匿名管道的创建与 API * 3.1 匿名管道的创建函数 * 3.2 匿名管道的简单使用示例 * 四. 基于 fork 的匿名管道跨进程通信 * 4.1 fork 共享管道的核心原理 * 4.2

By Ne0inhk
ARM Linux 驱动开发篇---GPIO子系统详解-- Ubuntu20.04

ARM Linux 驱动开发篇---GPIO子系统详解-- Ubuntu20.04

🎬 渡水无言:个人主页渡水无言 ❄专栏传送门: 《linux专栏》   《嵌入式linux驱动开发》《freertos专栏》 ⭐️流水不争先,争的是滔滔不绝  📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生 | 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生 在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连 目录 前言 一、GPIO 子系统核心定位 二、IMX6ULL 的 GPIO 子系统实战(设备树 + 驱动) 2.1、配置设备树中的 GPIO 2.1.1、pinctrl 配置 2.1.2、在设备节点中指定 GPIO 2.1.3、GPIO 控制器节点

By Ne0inhk
【Linux】Linux 安全实战:防火墙配置 + 漏洞修复,符合企业合规标准

【Linux】Linux 安全实战:防火墙配置 + 漏洞修复,符合企业合规标准

Linux 安全实战:防火墙配置 + 漏洞修复,符合企业合规标准 在数字化转型深化的当下,Linux系统凭借稳定性、开源性优势,广泛承载企业核心业务与敏感数据,成为企业IT架构的基石。然而,开源特性带来灵活性的同时,也使Linux系统面临端口暴露、权限滥用、漏洞攻击等多重安全挑战,恶意攻击、数据泄露等风险频发。 更重要的是,随着ISO 27001信息安全管理体系、GDPR通用数据保护条例、等保2.0(网络安全等级保护基本要求)等主流合规标准的落地实施,企业对Linux系统的安全管控不再是“可选项”,而是必须满足的合规底线与法律义务。 * Linux 安全实战:防火墙配置 + 漏洞修复,符合企业合规标准 * 一、防火墙配置实战:基于firewalld构建最小权限防护体系 * 1.1 基础环境初始化与安全基线配置 * 1.2 精准访问控制:限制核心服务访问范围 * 1.3 进阶安全策略:强化流量管控与日志审计 * 二、漏洞识别与修复流程:构建全生命周期漏洞管控

By Ne0inhk