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

数据结构——链表详解

链表

文章目录

  • 链表
    • 前言
    • 认识链表
        • 单链表结构图
        • 带头单循环链表结构图
        • 双向循环链表结构图
        • 带头双向循环链表结构图
      • 链表特点
    • 链表实现(带头双向循环链表实现)
        • 链表结构体
        • (1) 新建头节点
        • (2) 建立新节点
        • (3)尾部插入节点
        • (4)删除节点
        • (5)头部插入节点
        • (6) 头删节点
        • (7) 寻找节点
        • (8) pos位置插入节点
        • (9) 删除pos位置节点
        • (10) 打印链表
        • 测试用例

前言

new一个奶黄包:没关系,这条路我陪你走到底

在这里插入图片描述

认识链表

单链表结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CAU6jKY6-1692328909256)(https://flowus.cn/preview/624afaec-e422-4877-8061-cb639a1325b7)]

带头单循环链表结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4euIvGQg-1692328833369)(链表+2506bbec-fbf0-438b-8319-a4e748b4a543/image.png)]

双向循环链表结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1uetT2ky-1692328833370)(链表+2506bbec-fbf0-438b-8319-a4e748b4a543/image 1.png)]

带头双向循环链表结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ITJxFGxY-1692328833370)(链表+2506bbec-fbf0-438b-8319-a4e748b4a543/image 2.png)]

链表特点

  • 单链表在内存中,并不是连续存储的(逻辑上连续)。

  • 不支持随机访问

  • 插入时只需要改变指针指向

  • 没有容量的概念

  • 可以高效的在任意位置插入&&删除

  • 缓存利用率低

链表实现(带头双向循环链表实现)

链表结构体

typedef int LTDataType;
typedef struct ListNode
{LTDataType data;struct ListNode* next;struct ListNode* prev;
}LTNode;

(1) 新建头节点

LTNode* ListInit()//建立头节点
{LTNode* phead = buyListNode(-1); //建立一个带头节点phead->next = phead;      phead->prev = phead;return phead;
}

(2) 建立新节点

LTNode* buyListNode(LTDataType x)//创建内存初始化数据  
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode)); //if (newnode == NULL){perror("malloc fail");exit(-1);}// 初始化:注意所对的结构来初始化newnode->next = NULL;newnode->prev = NULL;newnode->data = x;return newnode;
}

(3)尾部插入节点

void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = buyListNode(x);LTNode* tail = phead->prev;tail->next = newnode;newnode->prev = tail;newnode->next = phead;phead->prev = newnode;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uzvehYMH-1692328833370)(链表+2506bbec-fbf0-438b-8319-a4e748b4a543/image 3.png)]

(4)删除节点

void LTPopBack(LTNode* phead)
{assert(phead);LTNode* tail = phead->prev;  //记录上一个节点LTNode* tailmove =tail->prev;  //记录上一个节点的上一个节点tailmove->next = phead;    phead->prev = tailmove;free(tail);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hCUDDN9I-1692328833371)(链表+2506bbec-fbf0-438b-8319-a4e748b4a543/image 4.png)]

(5)头部插入节点

void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = buyListNode(x); LTNode* first = phead->next;newnode->next = first;first->prev = newnode;first->next = phead;phead->prev = first;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vx0P45G2-1692328833371)(链表+2506bbec-fbf0-438b-8319-a4e748b4a543/image 5.png)]

(6) 头删节点

void LTPopFront(LTNode* phead)
{assert(phead);  //判断是否有头节点assert(phead->next != NULL);  //判断第一个节点是否存在LTNode* tail = phead->next;LTNode* tailmove = tail->next;tailmove->prev = phead;phead->next = tailmove;tailmove->next = phead;phead->prev = tailmove;free(tail);
}

在这里插入图片描述

(7) 寻找节点

LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){if (cur->data == x){//printf("找到了");return cur;//返回指针}cur=cur->next; //每次都走到下一个节点直到phead}//printf("找不到");return NULL;
}

(8) pos位置插入节点

void LTInsert(LTNode* pos, LTDataType x)//头插尾插都可以调用这个函数 
{assert(pos);LTNode* newnode = buyListNode(x); //新建一个节点LTNode* prev = pos->prev;   //记录pos位置的前一个节点newnode->next = pos;   //新节点的下一个节点就是pospos->prev = newnode;   //pos位置节点prve就链接后面newnode->prev = prev;prev->next = newnode;
}

在这里插入图片描述

(9) 删除pos位置节点

void LTErase(LTNode* pos)  //删除节点
{assert(pos);LTNode* prve = pos->prev;LTNode* next = pos->next;prve->next = next;next->prev = prve;free(pos);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1IWfpl22-1692328833371)(链表+2506bbec-fbf0-438b-8319-a4e748b4a543/image 7.png)]

(10) 打印链表

void LTPrint(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur!= phead){printf("-> %d ",cur->data );cur = cur->next;}}

测试用例

void test1()
{LTNode* ptail = ListInit();LTPushBack(ptail, 1);LTPushBack(ptail, 3);LTPushBack(ptail, 2);LTPushBack(ptail, 4);LTPushBack(ptail, 5);LTPopBack(ptail);LTPrint(ptail);
}

相关文章:

数据结构——链表详解

链表 文章目录 链表前言认识链表单链表结构图带头单循环链表结构图双向循环链表结构图带头双向循环链表结构图 链表特点 链表实现(带头双向循环链表实现)链表结构体(1) 新建头节点(2) 建立新节点(3)尾部插入节点(4)删除节点(5)头部插入节点(6) 头删节点(7) 寻找节点(8) pos位置…...

(学习笔记-进程管理)什么是悲观锁、乐观锁?

互斥锁与自旋锁 最底层的两种就是 [互斥锁和自旋锁],有很多高级的锁都是基于它们实现的。可以认为它们是各种锁的地基,所以我们必须清楚它们之间的区别和应用。 加锁的目的就是保证共享资源在任意时间内,只有一个线程访问,这样就…...

actuator/prometheus使用pushgateway上传jvm监控数据

场景 准备 prometheus已经部署pushgateway服务&#xff0c;访问{pushgateway.server:9091}可以看到面板 实现 基于springboot引入支持组件&#xff0c;版本可以 <!--监控检查--><dependency><groupId>org.springframework.boot</groupId><artifa…...

Linux设置临时目录路径的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

19-普通组件的注册使用

普通组件的注册使用-局部注册 一. 组件注册的两种方式:1.局部注册:只能在注册的组件内使用 (1) 创建 vue 文件(单文件组件) (2) 在使用的组件内导入,并注册 components:{ 组件名: 组件对象 } // 导入需要注册的组件 import 组件对象 from.vue文件路径 import HmHeader from ./…...

Java基础篇:抽象类与接口

1、抽象类和接口的定义&#xff1a; &#xff08;1&#xff09;抽象类主要用来抽取子类的通用特性&#xff0c;作为子类的模板&#xff0c;它不能被实例化&#xff0c;只能被用作为子类的超类。 &#xff08;2&#xff09;接口是抽象方法的集合&#xff0c;声明了一系列的方法…...

面对对象编程范式

本文是阅读《设计模式之美》的总结和心得&#xff0c;跳过了书中对面试和工作用处不大或不多的知识点&#xff0c;总结总共分为三章&#xff0c;分别是面对对象编程范式、设计原则和设计模式 现如今&#xff0c;编程范式存在三种&#xff0c;它们分别是面向对象编程、面向过程编…...

“深度学习”学习日记:Tensorflow实现VGG每一个卷积层的可视化

2023.8.19 深度学习的卷积对于初学者是非常抽象&#xff0c;当时在入门学习的时候直接劝退一大班人&#xff0c;还好我坚持了下来。可视化时用到的图片&#xff08;我们学校的一角&#xff01;&#xff01;&#xff01;&#xff09;以下展示了一个卷积和一次Relu的变化 作者使…...

146. LRU 缓存

题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否…...

Unity框架学习--场景切换管理器

活动场景 用脚本实例化的游戏对象都会生成在活动场景中。 哪个场景是活动场景&#xff0c;则当前的天空盒就会使用该场景的天空盒。 只能有一个场景是活动场景。 在Hierarchy右击一个场景&#xff0c;点击“Set Active Scene”可以手动把这个场景设置为活动场景。也可以使用…...

Kotlin Lambda和高阶函数

Lambda和高阶函数 本文链接&#xff1a; 文章目录 Lambda和高阶函数 lambda输出&#xff08;返回类型&#xff09;深入探究泛型 inline原理探究 高阶函数集合、泛型自己实现Kotlin内置函数 扩展函数原理companion object 原理 > 静态内部类函数式编程 lambda 1、lambda的由…...

ELKstack-Elasticsearch配置与使用

一. 部署前准备 最小化安装 Centos 7.x/Ubuntu x86_64 操作系统的虚拟机&#xff0c;vcpu 2&#xff0c;内存 4G 或更多&#xff0c; 操作系统盘 50G&#xff0c;主机名设置规则为 es-server-nodeX &#xff0c; 额外添加一块单独的数据磁盘 大小为 50G 并格式化挂载到/data/e…...

Kotlin 基础教程二

constructor 构造器一般情况下可以简化为主构造器 即: class A constructor(参数) : 父类 (参数) 也可以在构造器上直接声明属性constructor ( var name) 这样可以全局访问 init { } 将和成员变量一起初始化 susped 挂起 data class 可以简化一些bean类 比如get / set ,自动…...

K8S deployment挂载

挂载到emptyDir 挂载在如下目录&#xff0c;此目录是pod所在的node节点主机的目录&#xff0c;此目录下的data即对应容器里的/usr/share/nginx/html&#xff0c;实现目录挂载&#xff1b;图1红框里的号对应docker 的name中的编号&#xff0c;如下俩个图 apiVersion: apps/v1 k…...

类之间的比较

作者简介&#xff1a; zoro-1&#xff0c;目前大一&#xff0c;正在学习Java&#xff0c;数据结构等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; 类之间的比较 固定需求式比较器 固定需求式 通过…...

设计模式之备忘录模式(Memento)的C++实现

1、备忘录模式的提出 在软件功能开发过程中&#xff0c;某些对象的状态在转换过程中&#xff0c;由于业务场景需要&#xff0c;要求对象能够回溯到对象之前某个点的状态。如果使用一些共有接口来让其他对象得到对象的状态&#xff0c;便会暴露对象的实现细节。备忘录模式是在不…...

学习笔记230804---restful风格的接口,delete的传参方式问题

如果后端提供的删除接口是restful风格&#xff0c;那么使用地址栏拼接的方式发送请求&#xff0c;数据放在主体中&#xff0c;后端接受不到&#xff0c;当然也还有一种可能&#xff0c;后端在这个接口的接参设置上是req.query接参。 问题描述 今天遇到的问题是&#xff0c;de…...

STM32使用IIC通信的引脚配置问题

STM32使用IIC通信的引脚配置问题 在使用IIC通信时&#xff0c;遇到引脚配置问题&#xff0c;记录一下&#xff1a; IIC的两个引脚SDA和SCL都要求既能输入又能输出。 问题&#xff1a; SDA线是由不同的器件分时控制的&#xff0c;这样就会有一个问题&#xff1a;当一个器件主动…...

题解 | #K.First Last# 2023牛客暑期多校10

K.First Last 签到题 题目大意 n n n 个人参加 m m m 场比赛&#xff0c;每场比赛中获得名次得概率均等 问针对某一人&#xff0c;他在所有场次比赛中都获得第一或倒数第一的概率 解题思路 如果人数 n > 1 n>1 n>1 &#xff0c;每场比赛的概率是 p 2 n p\dfra…...

Python 程序设计入门(025)—— 使用 os 模块操作文件与目录

Python 程序设计入门&#xff08;025&#xff09;—— 使用 os 模块操作文件与目录 目录 Python 程序设计入门&#xff08;025&#xff09;—— 使用 os 模块操作文件与目录一、操作目录的常用函数1、os 模块提供的操作目录的函数2、os.path 模块提供的操作目录的函数 二、相对…...

Hive 数据库 增删改 完整操作指南

Hive 是基于 Hadoop 的数据仓库&#xff0c;不支持传统数据库的行级事务&#xff08;标准 Hive&#xff09;&#xff0c;核心用于离线数据分析。Hive 对数据库&#xff08;Database&#xff09; 的操作只有 CREATE&#xff08;增&#xff09;、DROP&#xff08;删&#xff09;、…...

Steam Deck Windows控制器驱动终极配置指南:5步实现完美游戏体验

Steam Deck Windows控制器驱动终极配置指南&#xff1a;5步实现完美游戏体验 【免费下载链接】steam-deck-windows-usermode-driver A windows usermode controller driver for the steam deck internal controller. 项目地址: https://gitcode.com/gh_mirrors/st/steam-deck…...

OLAP引擎全景图鉴:从架构原理到场景适配,深度解析Impala/Druid/Presto/Kylin/ClickHouse的选型之道

1. OLAP技术全景解析&#xff1a;从基础概念到架构分类 当你打开手机查看每日步数统计&#xff0c;或是浏览电商平台的年度消费报告时&#xff0c;背后支撑这些数据分析的正是OLAP技术。OLAP&#xff08;在线分析处理&#xff09;就像一位不知疲倦的数据分析师&#xff0c;能够…...

使用 Taotoken 后 API 调用延迟与稳定性体验分享

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 使用 Taotoken 后 API 调用延迟与稳定性体验分享 作为一名日常需要频繁调用大模型 API 的开发者&#xff0c;服务的稳定性和响应速…...

Compose-Skill:为Jetpack Compose应用注入AI能力的组件化技能库

1. 项目概述&#xff1a;一个为Compose应用注入AI能力的技能库最近在折腾Jetpack Compose项目时&#xff0c;我一直在想&#xff0c;能不能让UI开发也“智能”一点&#xff1f;比如&#xff0c;用户输入一段模糊的描述&#xff0c;界面就能自动生成对应的组件布局&#xff1b;或…...

Vigil与其他监控工具集成:构建全方位监控体系的3种方案

Vigil与其他监控工具集成&#xff1a;构建全方位监控体系的3种方案 【免费下载链接】vigil &#x1f6a6; Microservices Status Page. Monitors a distributed infrastructure and sends alerts (Slack, SMS, etc.). 项目地址: https://gitcode.com/gh_mirrors/vig/vigil …...

鲲鹏超节点系统应用创新竞争力

鲲鹏超节点通过灵衢互联&#xff0c;打破传统的服务器边界&#xff0c;实现以数据为中心的全互联架构&#xff0c;为AI infra而生&#xff0c;具备大带宽、低时延、统一编址、内存语义、内存借用、内存共享、对等互联等关键能力&#xff0c;灵衢软件全面开源开放&#xff0c;让…...

从2018到2023:Unity WebGL内存管理变迁史与你的2G内存墙突破指南

Unity WebGL内存管理演进与2G内存墙突破实战 引言 2018年的某个深夜&#xff0c;当我第一次在Chrome控制台看到"Out of Memory"的红色警告时&#xff0c;完全没意识到这会成为接下来五年与Unity WebGL缠斗的开端。那个使用Unity 2017.3构建的医疗可视化项目&#xff…...

TDAD时间序列异常检测实战:从算法原理到生产部署

1. 项目概述&#xff1a;从零开始理解TDAD最近在GitHub上看到一个名为“TDAD”的项目&#xff0c;仓库地址是zd8899/TDAD。乍一看这个缩写&#xff0c;很多朋友可能会有点懵&#xff0c;这到底是做什么的&#xff1f;是某个新框架&#xff0c;还是一个数据处理工具&#xff1f;…...

开源本地AI API网关:统一管理Ollama等模型,简化LLM应用开发

1. 项目概述&#xff1a;一个开源的本地AI API网关最近在折腾本地大语言模型&#xff08;LLM&#xff09;的朋友&#xff0c;估计都遇到过类似的烦恼&#xff1a;模型装好了&#xff0c;界面也跑起来了&#xff0c;但想把它集成到自己的应用里&#xff0c;或者想用一套统一的接…...