数据结构:链表
链表是一种常见的数据结构,它由一系列节点(Node)组成,每个节点包含两个部分:数据域和指针域。数据域用于存储数据元素的值,而指针域则用于指向链表中的下一个节点。这种结构使得链表能够动态地进行插入和删除操作,具有较高的灵活性。
链表的主要特点包括:
-
动态分配:链表的大小可以在运行时动态地增长或缩小,不需要预先分配固定大小的空间。
-
插入和删除效率高:在已知某一节点位置的情况下,链表的插入和删除操作可以在常数时间内完成,无需像数组那样移动大量元素。
-
元素访问顺序性:链表中的元素是顺序访问的,从头节点开始,依次访问到尾节点。这种顺序性使得链表在处理需要按序处理的数据时非常有用。
链表的类型主要有以下几种:
-
单向链表:每个节点只有一个指针,指向下一个节点。单向链表只能从头节点开始,顺序访问到尾节点。
-
双向链表:每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点。双向链表可以从任意节点开始,向前或向后访问其他节点。
-
循环链表:在单向链表或双向链表的基础上,尾节点的指针指向头节点,形成一个环状结构。循环链表可以从任意节点开始,遍历整个链表。
在实际应用中,链表被广泛用于实现各种数据结构和算法,如栈、队列、哈希表等。同时,由于链表在插入和删除操作上的高效性,它也常被用于需要频繁进行这些操作的场景,如文本编辑器中的撤销/重做功能、操作系统的任务调度等。
然而,链表也有一些缺点,如需要额外的空间来存储指针、不能直接访问特定位置的元素(需要从头节点开始遍历)等。因此,在选择使用链表还是其他数据结构时,需要根据具体的应用场景和需求进行权衡。
1. 单向链表(Singly Linked List)
单向链表中的每个节点包含数据和指向下一个节点的指针。链表的头指针指向第一个节点,最后一个节点的指针指向NULL,表示链表的结束。
示例代码:
#include <stdio.h>
#include <stdlib.h>// 定义链表节点结构
struct Node {int data;struct Node* next;
};// 创建新节点
struct Node* createNode(int data) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));newNode->data = data;newNode->next = NULL;return newNode;
}// 在链表末尾插入节点
void append(struct Node** head, int data) {struct Node* newNode = createNode(data);if (*head == NULL) {*head = newNode;return;}struct Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;
}// 打印链表
void printList(struct Node* head) {struct Node* temp = head;while (temp != NULL) {printf("%d -> ", temp->data);temp = temp->next;}printf("NULL\n");
}int main() {struct Node* head = NULL;append(&head, 10);append(&head, 20);append(&head, 30);printList(head);return 0;
}
输出:
10 -> 20 -> 30 -> NULL
2. 双向链表(Doubly Linked List)
双向链表中的每个节点包含数据、指向下一个节点的指针和指向前一个节点的指针。这样可以方便地从任意节点向前或向后遍历链表。
示例代码:
#include <stdio.h>
#include <stdlib.h>// 定义双向链表节点结构
struct Node {int data;struct Node* prev;struct Node* next;
};// 创建新节点
struct Node* createNode(int data) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));newNode->data = data;newNode->prev = NULL;newNode->next = NULL;return newNode;
}// 在链表末尾插入节点
void append(struct Node** head, int data) {struct Node* newNode = createNode(data);if (*head == NULL) {*head = newNode;return;}struct Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;newNode->prev = temp;
}// 打印链表
void printList(struct Node* head) {struct Node* temp = head;while (temp != NULL) {printf("%d <-> ", temp->data);temp = temp->next;}printf("NULL\n");
}int main() {struct Node* head = NULL;append(&head, 10);append(&head, 20);append(&head, 30);printList(head);return 0;
}
输出:
10 <-> 20 <-> 30 <-> NULL
3. 循环链表(Circular Linked List)
循环链表可以是单向的也可以是双向的。在循环链表中,最后一个节点的指针指向链表的头节点,形成一个环。
示例代码:
#include <stdio.h>
#include <stdlib.h>// 定义循环链表节点结构
struct Node {int data;struct Node* next;
};// 创建新节点
struct Node* createNode(int data) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));newNode->data = data;newNode->next = NULL;return newNode;
}// 在循环链表末尾插入节点
void append(struct Node** head, int data) {struct Node* newNode = createNode(data);if (*head == NULL) {*head = newNode;newNode->next = *head; // 指向自身形成环return;}struct Node* temp = *head;while (temp->next != *head) {temp = temp->next;}temp->next = newNode;newNode->next = *head; // 新节点指向头节点
}// 打印循环链表
void printList(struct Node* head) {if (head == NULL) return;struct Node* temp = head;do {printf("%d -> ", temp->data);temp = temp->next;} while (temp != head);printf("(回到起点)\n");
}int main() {struct Node* head = NULL;append(&head, 10);append(&head, 20);append(&head, 30);printList(head);return 0;
}
输出:
10 -> 20 -> 30 -> (回到起点)
链表结构在不同的应用场景中都有其独特的优势,选择合适的链表类型可以提高程序的效率和可读性。
相关文章:
数据结构:链表
链表是一种常见的数据结构,它由一系列节点(Node)组成,每个节点包含两个部分:数据域和指针域。数据域用于存储数据元素的值,而指针域则用于指向链表中的下一个节点。这种结构使得链表能够动态地进行插入和删…...
领克Z20结合AI技术,革新自动驾驶辅助系统
眼瞅着,再有不到 5 个星期,春节就要热热闹闹地登场啦!对于在外辛苦打拼了一整年的打工人而言,回家过年可不就是这一年里心心念念、最最期盼的高光时刻嘛。这不,这几天各地的高速公路愈发熙熙攘攘起来,川流不…...
vector快慢指针+例题详解
1.快慢指针 例题 给定一个链表,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从…...
重温设计模式--1、组合模式
文章目录 1 、组合模式(Composite Pattern)概述2. 组合模式的结构3. C 代码示例4. C示例代码25 .应用场景 1 、组合模式(Composite Pattern)概述 定义:组合模式是一种结构型设计模式,它允许你将对象组合成…...
单片机:实现SYN6288语音播报(附带源码)
单片机实现SYN6288语音播报 SYN6288是一款广泛应用于语音合成的IC,可以通过串口与单片机(如51系列、STM32等)进行通信,实现场景化的语音播报。通过连接外部存储设备(如SD卡)存储语音文件或直接通过内部语音…...
cookie,session,token 的区别
解决什么问题?Cookie(客户端存储)问题来了 Session(会话)解决的问题问题来了 token(令牌)解决的问题问题:token是无状态的如何解决? 解决什么问题? 解决http无状态的问题,说简单点就是用户身份的验证 举个例子: 张三在银行里…...
基于OpenAI Whisper AI模型自动生成视频字幕:全面解析与实战指南
在数字化时代,视频内容已成为信息传播的重要载体。然而,为视频添加字幕却是一项繁琐且耗时的工作。幸运的是,随着人工智能技术的飞速发展,特别是OpenAI Whisper模型的推出,我们有了更加高效、智能的解决方案。 一、Op…...
物理学天空的两朵乌云——量子论与相对论
物理学天空的两朵乌云——量子论与相对论 爱因斯坦的青春与科学的辉煌起点 提到爱因斯坦,我们往往会联想到一个经典的形象——乱糟糟的头发,叼着烟斗,脸上满是岁月的皱纹。然而,这张深入人心的照片并不是他科学创造力的象征。实…...
聚类之轮廓系数
Silhouette Score(轮廓系数)是用于评估聚类质量的指标之一。它衡量了数据点与同簇内其他点的相似度以及与最近簇的相似度之间的对比。 公式 对于一个数据点 i: a(i): 数据点 i 到同簇内其他点的平均距离(簇内不相似度ÿ…...
Jenkins 构建流水线
在 Linux 系统上安装 Jenkins 服务,以及配置自动化构建项目 前置准备环境:docker、docker-compose、jdk、maven 一、环境搭建 1. Jenkins 安装 (1)拉取镜像 # 安装镜像包,默认安装最新版本 docker pull jenkins/jen…...
RTK部分模糊度固定测量流程图
部分模糊度剔除常用测量: 周跳或失锁时间优先剔除;按俯仰角剔除;按浮点模糊度协方差大小剔除模糊度;按信号强度剔除卫星;...
力扣-数据结构-2【算法学习day.73】
前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?建议灵神的题单和代码随想录)和记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关…...
操作系统导论读书笔记
目录 虚拟化抽象:进程抽象:进程概念 虚拟化 抽象:进程 本章讨论操作系统提供的基本的抽象—— 进程。进程的非正式定义非常简单:进程就是运行中的程序。程序本身是没有生命周期的,它只是存在磁盘上面的一些指令&…...
基于3D-Speaker进行区分说话人项目搭建过程报错记录 | 通话录音说话人区分以及语音识别 | 声纹识别以及语音识别 | pyannote-audio
0. 研究背景 在外呼系统中,我们的后台管理系统通常要对电话录音的内容进行提取和分析。那么说到分析,我们就要对录音中的两个人的对话进行分离,然后分别分析,比如分析客户是否有合作的意愿,分析客服讲的话术是否合理&…...
如何使用流式渲染技术提升用户体验
提示:记录工作中遇到的需求及解决办法 文章目录 什么是流式渲染?Node.js 实现简单流式渲染声明式 Shadow DOM,不依赖 javascript 实现react 实现流式渲染总结提示:以下是本篇文章正文内容,下面案例可供参考 什么是流式渲染? 流式渲染主要思想是将HTML文档分块(chunk)…...
【接口自动化连载】使用yaml配置文件自动生成接口case
直接上干货撸代码,有一些是通用的工具类代码,一次性封装永久使用,期待大家的关注,一起加油!!! 配置文件 根据不同的业务需求进行配置,例如Goods服务、Order服务分开配置࿰…...
前端安全 常见的攻击类型及防御措施
1. 跨站脚本攻击(XSS) 描述:跨站脚本(XSS:Cross-Site Scripting)是一种安全漏洞,允许攻击者向网站注入恶意客户端代码。该代码由受害者执行从而让攻击者绕过访问控制并冒充用户。XSS攻击可以分…...
来道面试题——CopyOnWriteArrayList
原理 初始化时候,CopyOnWriteArrayList内部维护了一个可变数组,用于存储元素当执行数据变更操作的时候,会先创建一个原数组的副本,在副本上进行写操作,修改副本中的元素。写操作完成之后,把原数组的引用指…...
【Rust自学】5.1. 定义并实例化struct
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 5.1.1. 什么是struct struct的中文意思为结构体,它是一种自定义的数据类型,它允许程序为相关联的值命名和打包&am…...
React 生命周期完整指南
React 生命周期完整指南 1. 生命周期概述 1.1 React 16.3 之前的生命周期 初始化阶段 constructorcomponentWillMountrendercomponentDidMount 更新阶段 componentWillReceivePropsshouldComponentUpdatecomponentWillUpdaterendercomponentDidUpdate 卸载阶段 componentWil…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
