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

数据结构:链表

链表是一种常见的数据结构,它由一系列节点(Node)组成,每个节点包含两个部分:数据域和指针域。数据域用于存储数据元素的值,而指针域则用于指向链表中的下一个节点。这种结构使得链表能够动态地进行插入和删除操作,具有较高的灵活性。

链表的主要特点包括:

  1. 动态分配:链表的大小可以在运行时动态地增长或缩小,不需要预先分配固定大小的空间。

  2. 插入和删除效率高:在已知某一节点位置的情况下,链表的插入和删除操作可以在常数时间内完成,无需像数组那样移动大量元素。

  3. 元素访问顺序性:链表中的元素是顺序访问的,从头节点开始,依次访问到尾节点。这种顺序性使得链表在处理需要按序处理的数据时非常有用。

链表的类型主要有以下几种:

  1. 单向链表:每个节点只有一个指针,指向下一个节点。单向链表只能从头节点开始,顺序访问到尾节点。

  2. 双向链表:每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点。双向链表可以从任意节点开始,向前或向后访问其他节点。

  3. 循环链表:在单向链表或双向链表的基础上,尾节点的指针指向头节点,形成一个环状结构。循环链表可以从任意节点开始,遍历整个链表。

在实际应用中,链表被广泛用于实现各种数据结构和算法,如栈、队列、哈希表等。同时,由于链表在插入和删除操作上的高效性,它也常被用于需要频繁进行这些操作的场景,如文本编辑器中的撤销/重做功能、操作系统的任务调度等。

然而,链表也有一些缺点,如需要额外的空间来存储指针、不能直接访问特定位置的元素(需要从头节点开始遍历)等。因此,在选择使用链表还是其他数据结构时,需要根据具体的应用场景和需求进行权衡。

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 -> (回到起点)

  链表结构在不同的应用场景中都有其独特的优势,选择合适的链表类型可以提高程序的效率和可读性。 

相关文章:

数据结构:链表

链表是一种常见的数据结构&#xff0c;它由一系列节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含两个部分&#xff1a;数据域和指针域。数据域用于存储数据元素的值&#xff0c;而指针域则用于指向链表中的下一个节点。这种结构使得链表能够动态地进行插入和删…...

领克Z20结合AI技术,革新自动驾驶辅助系统

眼瞅着&#xff0c;再有不到 5 个星期&#xff0c;春节就要热热闹闹地登场啦&#xff01;对于在外辛苦打拼了一整年的打工人而言&#xff0c;回家过年可不就是这一年里心心念念、最最期盼的高光时刻嘛。这不&#xff0c;这几天各地的高速公路愈发熙熙攘攘起来&#xff0c;川流不…...

vector快慢指针+例题详解

1.快慢指针 例题 给定一个链表&#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;我们使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;索引从…...

重温设计模式--1、组合模式

文章目录 1 、组合模式&#xff08;Composite Pattern&#xff09;概述2. 组合模式的结构3. C 代码示例4. C示例代码25 .应用场景 1 、组合模式&#xff08;Composite Pattern&#xff09;概述 定义&#xff1a;组合模式是一种结构型设计模式&#xff0c;它允许你将对象组合成…...

单片机:实现SYN6288语音播报(附带源码)

单片机实现SYN6288语音播报 SYN6288是一款广泛应用于语音合成的IC&#xff0c;可以通过串口与单片机&#xff08;如51系列、STM32等&#xff09;进行通信&#xff0c;实现场景化的语音播报。通过连接外部存储设备&#xff08;如SD卡&#xff09;存储语音文件或直接通过内部语音…...

cookie,session,token 的区别

解决什么问题?Cookie&#xff08;客户端存储&#xff09;问题来了 Session&#xff08;会话&#xff09;解决的问题问题来了 token(令牌)解决的问题问题:token是无状态的如何解决? 解决什么问题? 解决http无状态的问题,说简单点就是用户身份的验证 举个例子: 张三在银行里…...

基于OpenAI Whisper AI模型自动生成视频字幕:全面解析与实战指南

在数字化时代&#xff0c;视频内容已成为信息传播的重要载体。然而&#xff0c;为视频添加字幕却是一项繁琐且耗时的工作。幸运的是&#xff0c;随着人工智能技术的飞速发展&#xff0c;特别是OpenAI Whisper模型的推出&#xff0c;我们有了更加高效、智能的解决方案。 一、Op…...

物理学天空的两朵乌云——量子论与相对论

物理学天空的两朵乌云——量子论与相对论 爱因斯坦的青春与科学的辉煌起点 提到爱因斯坦&#xff0c;我们往往会联想到一个经典的形象——乱糟糟的头发&#xff0c;叼着烟斗&#xff0c;脸上满是岁月的皱纹。然而&#xff0c;这张深入人心的照片并不是他科学创造力的象征。实…...

聚类之轮廓系数

Silhouette Score&#xff08;轮廓系数&#xff09;是用于评估聚类质量的指标之一。它衡量了数据点与同簇内其他点的相似度以及与最近簇的相似度之间的对比。 公式 对于一个数据点 i&#xff1a; a(i): 数据点 i 到同簇内其他点的平均距离&#xff08;簇内不相似度&#xff…...

Jenkins 构建流水线

在 Linux 系统上安装 Jenkins 服务&#xff0c;以及配置自动化构建项目 前置准备环境&#xff1a;docker、docker-compose、jdk、maven 一、环境搭建 1. Jenkins 安装 &#xff08;1&#xff09;拉取镜像 # 安装镜像包&#xff0c;默认安装最新版本 docker pull jenkins/jen…...

RTK部分模糊度固定测量流程图

部分模糊度剔除常用测量&#xff1a; 周跳或失锁时间优先剔除&#xff1b;按俯仰角剔除&#xff1b;按浮点模糊度协方差大小剔除模糊度&#xff1b;按信号强度剔除卫星&#xff1b;...

力扣-数据结构-2【算法学习day.73】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;建议灵神的题单和代码随想录&#xff09;和记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关…...

操作系统导论读书笔记

目录 虚拟化抽象&#xff1a;进程抽象&#xff1a;进程概念 虚拟化 抽象&#xff1a;进程 本章讨论操作系统提供的基本的抽象—— 进程。进程的非正式定义非常简单&#xff1a;进程就是运行中的程序。程序本身是没有生命周期的&#xff0c;它只是存在磁盘上面的一些指令&…...

基于3D-Speaker进行区分说话人项目搭建过程报错记录 | 通话录音说话人区分以及语音识别 | 声纹识别以及语音识别 | pyannote-audio

0. 研究背景 在外呼系统中&#xff0c;我们的后台管理系统通常要对电话录音的内容进行提取和分析。那么说到分析&#xff0c;我们就要对录音中的两个人的对话进行分离&#xff0c;然后分别分析&#xff0c;比如分析客户是否有合作的意愿&#xff0c;分析客服讲的话术是否合理&…...

如何使用流式渲染技术提升用户体验

提示:记录工作中遇到的需求及解决办法 文章目录 什么是流式渲染?Node.js 实现简单流式渲染声明式 Shadow DOM,不依赖 javascript 实现react 实现流式渲染总结提示:以下是本篇文章正文内容,下面案例可供参考 什么是流式渲染? 流式渲染主要思想是将HTML文档分块(chunk)…...

【接口自动化连载】使用yaml配置文件自动生成接口case

直接上干货撸代码&#xff0c;有一些是通用的工具类代码&#xff0c;一次性封装永久使用&#xff0c;期待大家的关注&#xff0c;一起加油&#xff01;&#xff01;&#xff01; 配置文件 根据不同的业务需求进行配置&#xff0c;例如Goods服务、Order服务分开配置&#xff0…...

前端安全 常见的攻击类型及防御措施

1. 跨站脚本攻击&#xff08;XSS&#xff09; 描述&#xff1a;跨站脚本&#xff08;XSS&#xff1a;Cross-Site Scripting&#xff09;是一种安全漏洞&#xff0c;允许攻击者向网站注入恶意客户端代码。该代码由受害者执行从而让攻击者绕过访问控制并冒充用户。XSS攻击可以分…...

来道面试题——CopyOnWriteArrayList

原理 初始化时候&#xff0c;CopyOnWriteArrayList内部维护了一个可变数组&#xff0c;用于存储元素当执行数据变更操作的时候&#xff0c;会先创建一个原数组的副本&#xff0c;在副本上进行写操作&#xff0c;修改副本中的元素。写操作完成之后&#xff0c;把原数组的引用指…...

【Rust自学】5.1. 定义并实例化struct

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 5.1.1. 什么是struct struct的中文意思为结构体&#xff0c;它是一种自定义的数据类型&#xff0c;它允许程序为相关联的值命名和打包&am…...

React 生命周期完整指南

React 生命周期完整指南 1. 生命周期概述 1.1 React 16.3 之前的生命周期 初始化阶段 constructorcomponentWillMountrendercomponentDidMount 更新阶段 componentWillReceivePropsshouldComponentUpdatecomponentWillUpdaterendercomponentDidUpdate 卸载阶段 componentWil…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

TJCTF 2025

还以为是天津的。这个比较容易&#xff0c;虽然绕了点弯&#xff0c;可还是把CP AK了&#xff0c;不过我会的别人也会&#xff0c;还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...

深度解析云存储:概念、架构与应用实践

在数据爆炸式增长的时代&#xff0c;传统本地存储因容量限制、管理复杂等问题&#xff0c;已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性&#xff0c;成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理&#xff0c;云存储正重塑数据存储与…...

简约商务通用宣传年终总结12套PPT模版分享

IOS风格企业宣传PPT模版&#xff0c;年终工作总结PPT模版&#xff0c;简约精致扁平化商务通用动画PPT模版&#xff0c;素雅商务PPT模版 简约商务通用宣传年终总结12套PPT模版分享:商务通用年终总结类PPT模版https://pan.quark.cn/s/ece1e252d7df...

中国政务数据安全建设细化及市场需求分析

(基于新《政务数据共享条例》及相关法规) 一、引言 近年来,中国政府高度重视数字政府建设和数据要素市场化配置改革。《政务数据共享条例》(以下简称“《共享条例》”)的发布,与《中华人民共和国数据安全法》(以下简称“《数据安全法》”)、《中华人民共和国个人信息…...

持续交付的进化:从DevOps到AI驱动的IT新动能

文章目录 一、持续交付的本质&#xff1a;从手动到自动的交付飞跃关键特性案例&#xff1a;电商平台的高效部署 二、持续交付的演进&#xff1a;从CI到AI驱动的未来发展历程 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/101f72defaf3493ba0ba376bf09367a2.png)中国…...