双向链表代码(带哨兵位循环/不带哨兵位不循环
以下代码全为本人所写,如有错误,很正常,还请指出,
目录
带哨兵位循环
test.c
DLList.c
DLList.h
不带哨兵位不循环
test.c
DLList.c
DLList.h
带哨兵位循环
test.c
#define _CRT_SECURE_NO_WARNINGS#include"DLlist.h"int main()
{//初始化链表DL* DLList = DLListInit();//因为带哨兵位,不需要修改头节点,修改的是头节点指向的结构体的内容//传值就行,传的是DLList这个指针存的地址SLPushBack(DLList,8);SLPushFront(DLList, 5);SLPushFront(DLList, 6);SLPushBack(DLList,7);SLprint(DLList);//6->5->8->7SLPopFrpnt(DLList);SLPopBack(DLList);SLPushBack(DLList, 7);SLprint(DLList);//5->8->7DL* pos=SLFind(DLList,8);SLInsertBack(DLList,pos,9);//后插 5->8->9->7SLprint(DLList);pos = SLFind(DLList, 8);SLInsertFront(DLList, pos, 10); //前插 5->10->8->9->7SLprint(DLList);SLErase(DLList,pos);//删除 5->10->9->7SLprint(DLList);DListDestory(DLList);return 0;
}
DLList.c
#define _CRT_SECURE_NO_WARNINGS#include"DLlist.h"DL* BuyDLNode()
{DL* newcode = (DL*)malloc(sizeof(DL));return newcode;//返回的是这个指针存的地址
}DL* DLListInit()
{DL* newcode = BuyDLNode();//存的是malloc开辟空间的地址newcode->val = -1;newcode->next = newcode;newcode->prev = newcode;return newcode;
}void SLPushFront(DL* pphead, SLdatatype x)
{assert(pphead);DL* newcode = BuyDLNode();newcode->prev = pphead;newcode->next = pphead->next;newcode->val = x;DL* first = pphead->next;pphead->next = newcode;first->prev = newcode;
}void SLPushBack(DL* pphead, SLdatatype x)
{assert(pphead);DL* newcode = BuyDLNode();newcode->next = pphead;newcode->prev = pphead->prev;newcode->val = x;DL* end = pphead->prev;pphead->prev = newcode;end->next = newcode;
}void SLPopFrpnt(DL* pphead)
{assert(pphead);DL* first = pphead->next;DL* second = pphead->next->next;free(first);pphead->next = second;second->prev = pphead;
}void SLPopBack(DL* pphead)
{assert(pphead);DL* end = pphead->prev;DL* end_second = pphead->prev->prev;free(end);pphead->prev = end_second;end_second->next = pphead;
}DL* SLFind(DL* pphead, SLdatatype x)
{assert(pphead);DL* tail = pphead->next;while (tail->val != x){tail = tail->next;if (tail == pphead){printf("该链表内不存在该数据\n");return NULL;}}return tail;
}void SLInsertBack(DL* pphead, DL* pos, SLdatatype x)
{assert(pphead);assert(pos);DL* tail = pphead->next;while (tail != pos)//tail找到对应的节点 后插{tail = tail->next;}DL* newcode = BuyDLNode();newcode->val = x;newcode->next = tail->next;newcode->prev = tail;DL* Back = tail->next;Back->prev = newcode;tail->next = newcode;
}void SLInsertFront(DL* pphead, DL* pos, SLdatatype x)
{assert(pphead);assert(pos);DL* tail = pphead->next;while (tail != pos)//tail找到对应的节点 前插{tail = tail->next;}DL* newcode = BuyDLNode();newcode->val = x;newcode->next = tail;newcode->prev = tail->prev;DL* Front = tail->prev;Front->next = newcode;tail->prev = newcode;
}void SLErase(DL* pphead, DL* pos)
{assert(pphead);assert(pos);DL* tail = pphead->next;while (tail != pos)//tail找到对应的节点 要删除的节点{tail = tail->next;}DL* Front = tail->prev;DL* Back = tail->next;free(tail);Front->next = Back;Back->prev = Front;
}void SLprint(DL* pphead)
{DL* tail = pphead->next;printf("Sentinel->");while (tail != pphead){printf("%d->", tail->val);tail = tail->next;}printf("NULL\n");
}void DListDestory(DL* pphead)
{assert(pphead);DL* tail = pphead->next;while (tail != pphead){//先保存DL* tmp = tail->next;free(tail);tail = tmp;}free(pphead);
}
DLList.h
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>typedef int SLdatatype;typedef struct ListNode
{SLdatatype val;struct ListNode* next;struct ListNode* prev;
}DL;DL* BuyDLNode();DL* DLListInit();void SLPushFront(DL* pphead, SLdatatype x);void SLPushBack(DL* pphead, SLdatatype x);void SLPopFrpnt(DL* pphead);void SLPopBack(DL* pphead);DL* SLFind(DL* pphead, SLdatatype x);void SLInsertBack(DL* pphead, DL* pos, SLdatatype x);void SLInsertFront(DL* pphead, DL* pos, SLdatatype x);void SLErase(DL* pphead, DL* pos);void SLprint(DL* pphead);void DListDestory(DL* pphead);
不带哨兵位不循环
test.c
#define _CRT_SECURE_NO_WARNINGS#include"DLList.h"int main()
{DL* DLList = NULL;DLPushFront(&DLList, 6);DLPushFront(&DLList, 5);DLPushBack(&DLList, 7);DLPushBack(&DLList, 8);DLprint(DLList);DLPopFront(&DLList);DLprint(DLList);DLPopBack(&DLList);DLprint(DLList);DLPushBack(&DLList, 10);DLPushBack(&DLList, 11);DLprint(DLList);DL* pos= DListFind(DLList, 10);DLEarse(&DLList, pos);DLprint(DLList);pos = DListFind(DLList, 7);DLInsertBack(&DLList, pos, 12);//任意位置后插DLprint(DLList);DLInsertFront(&DLList, pos, 13);//任意位置前插DLprint(DLList);pos = DListFind(DLList, 6);Modify(&DLList,pos,20);DLprint(DLList);//释放链表DListDestory(&DLList);return 0;
}
DLList.c
#define _CRT_SECURE_NO_WARNINGS#include"DLList.h"void DLPushFront(DL** pphead, SLdatatype x)
{assert(pphead);DL* newcode = (DL*)malloc(sizeof(DL));DL* tail = *pphead;if (newcode == NULL){perror("malloc error\n");return;}//if (*pphead == NULL)//{//赋值newcode->val = x;newcode->prev = NULL;newcode->next = *pphead;//更换头节点*pphead = newcode;return;// }return;
}void DLPushBack(DL** pphead, SLdatatype x)
{assert(pphead);DL* newcode = (DL*)malloc(sizeof(DL));if (newcode == NULL){perror("malloc error\n");return;}if (*pphead == NULL){*pphead = newcode;(*pphead)->val = x;(*pphead)->next = NULL;(*pphead)->next = NULL;return;}DL* tail = *pphead;while (tail->next)//找到最后一个节点{tail = tail->next;}tail->next = newcode;newcode->val = x;newcode->prev = tail;newcode->next = NULL;return;
}void DLPopFront(DL** pphead)
{assert(pphead);assert(*pphead);DL* tail = *pphead;*pphead = (*pphead)->next;//释放第一个节点free(tail);//更换(*pphead)->prev = NULL;return;
}void DLPopBack(DL** pphead)
{assert(pphead);assert(*pphead);DL* tail = *pphead;//而且还要找到倒数第二个节点,//改变其的next NULL//但如果只有一个节点if (tail->next == NULL){free(pphead);
// *pphead = NULL;return;}while (tail->next->next)//找到最后二个节点{tail = tail->next;}DL* back = tail->next;//找到最后一个节点free(back);tail->next = NULL;//修改倒数第二个节点return;
}DL* DListFind(DL* plist, SLdatatype x)
{assert(plist);DL* tail = plist;while (tail){if (tail->val == x)//判断{return tail;}//迭代tail = tail->next;}printf("该信息在该链表内不存在\n");return NULL;
}void DLEarse(DL** pphead, DL* pos)
{assert(pphead);assert(*pphead);assert(pos);DL* tail = *pphead;//但是还需要找到下一个节点 修改prev 改为上一节点//上一节点 修改next 改为下一节点while (tail != pos)//找到对应要删除的节点{tail = tail->next;}if (tail->next==NULL)//尾节点{DLPopBack(pphead);return;}else if (tail->prev == NULL)//头节点{DLPopFront(pphead);return;}DL* Front = tail->prev;DL* Back = tail->next;free(tail);Front->next = Back;Back->prev = Front;return;
}void DLInsertBack(DL** pphead, DL* pos, SLdatatype x)
{assert(pphead);assert(pos);DL* tail = *pphead;while (tail != pos)//找到对应节点{tail = tail->next;}if (tail->next == NULL)//尾节点{DLPushBack(pphead,x);return;}else if (tail->prev == NULL)//头节点{DLPushFront(pphead,x);return;}//先malloc//修改该节点的next 指向新添加的节点//修改本来节点的下一个节点 修改prev 改为指向新添加的节点DL* newcode = (DL*)malloc(sizeof(DL));if (newcode == NULL){perror("malloc error\n");}newcode->val = x;newcode->next = tail->next;newcode->prev = tail;DL* Back = tail->next;//原本链表下一个节点tail->next = newcode;//修改原本节点的next指向新添加的Back->prev = newcode;//修改原本节点下一个节点的prevreturn;
}void DLInsertFront(DL** pphead, DL* pos, SLdatatype x)//前插
{assert(pphead);assert(pos);DL* tail = *pphead;while (tail != pos)//找到对应节点{tail = tail->next;}if (tail->next == NULL)//尾节点{DLPushBack(pphead, x);return;}else if (tail->prev == NULL)//头节点{DLPushFront(pphead, x);return;}//先malloc//修改该节点的next 指向新添加的节点//修改本来节点的下一个节点 修改prev 改为指向新添加的节点DL* newcode = (DL*)malloc(sizeof(DL));if (newcode == NULL){perror("malloc error\n");}newcode->val = x;newcode->next = tail;newcode->prev = tail->prev;DL* Front = tail->prev;//原本链表下一个节点tail->prev = newcode;//修改原本节点的prev指向新添加的Front->next = newcode;//修改原本节点上一个节点的nextreturn;
}void Modify(DL** pphead, DL* pos, SLdatatype x)
{assert(pphead);assert(pos);DL* tail = *pphead;while (tail != pos)//找到对应节点{tail = tail->next;}tail->val = x;return;
}void DLprint(DL* pphead)
{DL* tail = pphead;while (tail != NULL){printf("%d->", tail->val);tail = tail->next;}printf("NULL\n");
}void DListDestory(DL** pphead)
{DL* tmp = *pphead;while (*pphead != NULL){//先保存该节点指向的地址tmp = *pphead;*pphead = (*pphead)->next;free(tmp);tmp = NULL;}return;
}
DLList.h
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>typedef int SLdatatype;typedef struct ListNode
{SLdatatype val;struct ListNode* next;struct ListNode* prev;
}DL;void DLPushFront(DL** pphead, SLdatatype x);void DLPushBack(DL** pphead, SLdatatype x);void DLPopFront(DL** pphead);void DLPopBack(DL** pphead);DL* DListFind(DL* plist, SLdatatype x);void DLEarse(DL** pphead,DL* pos);void DLInsertBack(DL** pphead, DL* pos, SLdatatype x);void DLInsertFront(DL** pphead, DL* pos, SLdatatype x);void Modify(DL** pphead, DL* pos, SLdatatype x);void DLprint(DL* pphead);void DListDestory(DL** pphead);
相关文章:
双向链表代码(带哨兵位循环/不带哨兵位不循环
以下代码全为本人所写,如有错误,很正常,还请指出, 目录 带哨兵位循环 test.c DLList.c DLList.h 不带哨兵位不循环 test.c DLList.c DLList.h 带哨兵位循环 test.c #define _CRT_SECURE_NO_WARNINGS#include"DLlist.h&…...
C语言自学笔记13----C语言指针与函数
C 语言指针与函数 在C语言编程中,也可以将地址作为参数传递给函数。 要在函数定义中接受这些地址,我们可以使用指针。这是因为指针用于存储地址。让我们举个实例: 示例:通过引用致电 #include <stdio.h> void swap(int n1, …...

每日五道java面试题之mybatis篇(一)
目录: 第一题. MyBatis是什么?第二题. ORM是什么?第三题. 为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?第四题. 传统JDBC开发存在的问题第五题. JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的…...
一文解读ISO26262安全标准:概念阶段
一文解读ISO26262安全标准:概念阶段 1 相关项定义2 安全生命周期启动3 危害分析和风险评估 HaRa4 功能安全概念 由上一篇文章知道,安全生命周期包含概念阶段、产品开发阶段、生产发布后续阶段。本文详细解读概念阶段要进行的安全活动。 本部分规定了车辆…...

微信小程序调用百度智能云API(菜品识别)
一、注册后生成应用列表创建应用 二、找到当前所需使用的api菜品识别文档 三、点链接看实例代码 这里需要使用到如下几个参数(如下),其他的参数可以不管 client_id : 就是创建应用后的API Keyclient_secret: 就是创建…...

idea项目mapper.xml中的SQL语句黄色下划线去除
问题描述 当我们使用idea开发java项目时,经常会与数据库打交道,一般在使用mybatis的时候需要写一大堆的mapper.xml以及SQL语句,每当写完SQL语句的时候总是有黄色下划线,看着很不舒服。 解决方案: 修改idea的配置 Edi…...

es 聚合操作(二)
书接上文,示例数据在上一篇,这里就不展示了 一、Pipeline Aggregation 支持对聚合分析的结果,再次进行聚合分析。 Pipeline 的分析结果会输出到原结果中,根据位置的不同,分为两类: Sibling - 结果和现有…...

【vue.js】文档解读【day 5】| ref模板引用
如果阅读有疑问的话,欢迎评论或私信!! 本人会很热心的阐述自己的想法!谢谢!!! 文章目录 模板引用前言访问模板引用模板引用与v-if、v-show的结合v-for中的模板引用函数模板引用 模板引用 前言 …...
算法简单小技巧
主页:xiaocr_blog 1.最小公倍数和最大公约数 #include<iostream> using namespace std; int main(){int a,b;cin>>a>>b;int r a%b;while (r!0){a b;b r;r a%b;}cout<<b<<endl;return 0 ; } #include<iostream> using nam…...

前端入职配置新电脑!!!
前端岗位入职第一天到底应该做些什么呢?又该怎样高效的认识、融入团队?并快速进入工作状态呢?这篇文章就来分享一下,希望对即将走向或初入前端职场的你,能够有所帮助。内含大量链接,欢迎点赞收藏࿰…...
Java面试题总结15之简述你对RPC,RMI的理解
RPC:在本地调用远程的函数,远程过程调用,可以跨语言实现,httpClient RMI:远程方法调用,Java中用于实现RPC的一种机制,RPC的Java版本是J2EE的网络调用机制,跨JVM调用对象的方法&…...

内网穿透利器 n2n 搭建指南
1. n2n 简介 上文实验分析了 FRP 和 Zerotier 的利弊,本文再介绍另一种内网穿透方案,n2n。 n2n 是 C/S 架构的内网穿透服务,不同于 FRP 的 反向代理,它的原理是类似 Zerotier 的先打孔,打孔失败再尝试转发。关于打孔本…...

phpcms头像上传漏洞引发的故事
目录 关键代码 第一次防御 第一次绕过 第二次防御 第二次绕过 第三次防御 第三次绕过 如何构造一个出错的压缩包 第四次防御 第四次绕过 本篇文章是参考某位大佬与开发人员对于文件包含漏洞的较量记录下的故事,因为要学习文件包含漏洞,就将大佬…...

二叉树|二叉树理论基础、二叉树的递归遍历
代码随想录 (programmercarl.com) 树和二叉树 1.树的基本概念 1.1树的定义 1.2树的逻辑表示方法 1.3树的基本术语 1.4树的性质 1.5树的基本运算 1.6树的存储结构 2.二叉树的概念和性质 2.1二叉树的定义 2.2二叉树的性质 2.3二叉树与树、森林之间的转换 3.二叉树的…...
JavaScript 语法-对象
对象 JavaScript 中的对象是一组键值对的集合,其中每个键都是字符串,每个值可以是任意类型。 对象是由一些属性和方法组成的集合,属性可以用来存储数据,方法可以用来操作数据。 属性和方法使用“.”来访问 // 创建一个对象 let …...
代码随想录阅读笔记-哈希表【四数之和】
题目 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a b c d 的值与 target 相等?找出所有满足条件且不重复的四元组。 注意:答案中不可以包…...
JVM学习——双亲委派机制
简而言之就是为了防止与Java固有全类名重复,而导致系统崩坏所设立的机制。 当类加载器接收到加载类的任务时,首先会向上请求,一直请求到引导类加载器,如果引导类加载器无法加载,就会逐层返回让类加载器自己执行&#…...

【Paper Reading】6.RLHF-V 提出用RLHF的1.4k的数据微调显著降低MLLM的虚幻问题
分类 内容 论文题目 RLHF-V: Towards Trustworthy MLLMs via Behavior Alignment from Fine-grained Correctional Human Feedback 作者 作者团队:由来自清华大学和新加坡国立大学的研究者组成,包括Tianyu Yu, Yuan Yao, Haoye Zhang, Taiwen He, Y…...
Aloudata 倾力打造,《Data Fabric 白皮书 2.0》正式发布
数字经济时代,越来越多企业开始寻求全新的数据管理范式,以更有效地管理、利用不断增长的数据资产。在此背景下,Data Fabric 的概念应运而生,被视为面向未来的数据管理解决方案。 距离第一版白皮书问世已经过去一年多时间ÿ…...
docker内部无法使用ping等网络工具解决方案
通常docker内部没有网络,所以我们先离线安装需要的依赖包,然后再使用sh脚本容器内部访问宿主机同网络端其他服务器ip,实现监测远程ip telnet包依赖于netbase包,但是netbase包没有安装。你需要先安装netbase包,然后再尝试安装teln…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...