2024.11.29(单链表)
思维导图


声明文件
#ifndef __LINKLIST_H__
#define __LINKLIST_H__#include <myhead.h>typedef char datatype; //数据元素类型
//定义节点类型
typedef struct Node
{union{int len; //头节点数据域datatype data; //普通节点数据域};struct Node *next; //指针域}Node ,*Node_ptr;//创建链表
Node_ptr list_create();//链表判空操作
int list_empty(Node_ptr L);//定义申请节点封装数据函数
static Node_ptr node_apply(datatype e);//单向链表头插
int list_insert_head(Node_ptr L,datatype e);//单向链表的按位置查找返回节点
Node_ptr list_find_node(Node_ptr L,int pos);//单链表遍历
void list_show(Node_ptr L);//单向链表任意位置插入
int list_insert_anypos(Node_ptr L,int pos,datatype e);//单链表头删
int list_head_delete(Node_ptr L);//任意位置删除
int list_delete_anywhere(Node_ptr L,int pos);//按位置进行修改
int list_update_pos(Node_ptr L,int pos,datatype e);//单向链表翻转
int list_reverse(Node_ptr L);//销毁单链表
void list_destroy(Node_ptr L);//单链表尾插
int list_insert_tail(Node_ptr L,datatype e);//单链表的尾删
int list_delete_tail(Node_ptr L);//单链表按值查找返回位置
int list_find_value(Node_ptr L,int e);//单链表按值修改
int list_edit_value(Node_ptr L,int w,datatype e);//单链表的排序
int list_sort(Node_ptr L);//单链表的去重
int list_duplicate_removal(Node_ptr L);//清空单链表
int list_clear(Node_ptr L);//返回单链表的长度
int list_len(Node_ptr L);#endif
测试文件
#include "linklist.h"
int main(int argc, const char *argv[])
{//调用链表创建函数Node_ptr L = list_create();if(NULL == L){return -1;}//调用头插函数list_insert_head(L,'A');list_insert_head(L,'B');list_insert_head(L,'C');list_insert_head(L,'D');list_insert_head(L,'A');list_insert_head(L,'B');list_insert_head(L,'C');list_insert_head(L,'D');//调用遍历函数list_show(L);/* //调用任意插入函数list_insert_anypos(L,1,'u');list_show(L);list_insert_anypos(L,L->len+1,'P');list_show(L);list_insert_anypos(L,3,'9');list_show(L);//调用头删函数list_head_delete(L);list_show(L);//调用任意位置删除list_delete_anywhere(L,3);list_show(L);list_delete_anywhere(L,2);list_show(L);//调用按位置修改函数list_update_pos(L,2,'H');list_show(L);//调用翻转函数list_reverse(L);list_show(L);//调用尾插法list_insert_tail(L,'e');list_show(L);//调用尾删除list_delete_tail(L);list_show(L);//调用按值查找函数int a = list_find_value(L,'H');printf("位置为%d\n",a);//调用单链表按值修改list_edit_value(L,'H','A'); list_show(L);//调用排序函数list_sort(L);list_show(L);//调用去重函数list_duplicate_removal(L);list_show(L);printf("%d",L->len);//调用清空函数list_clear(L);list_show(L);
printf("%d",L->len);//调用销毁函数list_destroy(L);L = NULL;list_show(L);*/printf("链表长度为:%d\n",list_len(L));return 0;
}
功能函数文件
#include "linklist.h"
//创建链表
Node_ptr list_create()
{//在堆区申请一个头结点的空间Node_ptr L = (Node_ptr)malloc(sizeof(Node));if(L == NULL){printf("创建失败\n");return NULL;}//程序执行至此,一个头结点就申请成功//有了头结点就有了一条2链表//初始化操作L->len = 0; //表示链表长度为0L->next = NULL; //防止野指针printf("链表创建成功\n");return L;}//链表判空操作
//如果链表为空,返回1,非空返回0
int list_empty(Node_ptr L)
{//判断逻辑if(NULL == L){printf("链表不合法\n");return -1;}return 0;}//定义申请节点封装数据函数
static Node_ptr node_apply(datatype e)
{//在堆区申请一个节点的空间Node_ptr P = (Node_ptr)malloc(sizeof(Node));if(NULL == P){printf("节点申请失败\n");return NULL;}//将数据封装进节点的数据域P->data = e;P->next = NULL; //防止野指针return P; //将封装好的节点地址返回
}//单向链表头插
int list_insert_head(Node_ptr L,datatype e)
{//判断逻辑if(NULL == L){printf("链表不合法\n");return -1;}//申请节点封装数据Node_ptr P = node_apply(e);if(NULL ==P ){return -1;}//程序执行至此,表示节点申请成功//头插逻辑P->next = L->next;L->next = P;//表长变化L->len++;printf("插入成功\n");}//单向链表的按位置查找返回节点
Node_ptr list_find_node(Node_ptr L,int pos)
{//判断逻辑、if( NULL == L||pos <0||pos>L->len){printf("查找失败\n");return NULL;}//查找逻辑Node_ptr Q = L; //定义遍历指针for(int i=0;i<pos;i++){Q = Q->next; //将指针偏移到下一个节点位置}//返回节点return Q;}//单链表遍历
void list_show(Node_ptr L)
{//判断逻辑if(list_empty(L)){printf("遍历失败\n");return ;}/*遍历所有节点printf("链表中的元素分别是:");for(int i=1;i<L->len;i++){Node_ptr Q = list_find_node(L,i); //找到第i个节点printf("%c\t",Q->data);}*/printf("链表中的元素分别是:");Node_ptr Q = L->next; //定义遍历指针从第一个节点出发/*for(int i=0;i<L->len;i++){Q = Q->next;printf("%c\t",Q->data);}*/while(Q){//当前节点不为空,输出数据域printf("%c\t",Q->data);Q = Q->next; //继续遍历下一个节点}printf("输出完成\n");
}//单向链表任意位置插入
int list_insert_anypos(Node_ptr L,int pos,datatype e)
{//判断逻辑if(pos>L->len+1||pos<1||NULL == L){printf("插入失败\n");return -1;}//判断逻辑//找到要插入位置的前一个节点Node_ptr Q = list_find_node(L,pos-1);//插入逻辑Node_ptr W = node_apply(e);if(NULL == W){return -1;}W->next = Q->next;Q->next = W;//表长变化L->len++;printf("插入成功\n");
}//单链表头删
int list_head_delete(Node_ptr L)
{//判断逻辑if(NULL == L||list_empty(L)){printf("删除失败\n");return -1;}Node_ptr Q = L->next;L->next = Q->next;free(Q);Q = NULL;//表长变化L->len--;printf("删除成功\n");return 0;
}//任意位置删除
int list_delete_anywhere(Node_ptr L,int pos)
{//判断逻辑if(NULL==L||list_empty(L)||pos<1||pos>L->len){printf("删除失败\n");return -1;}//删除逻辑Node_ptr Q = list_find_node(L,pos-1); //找到前驱Node_ptr W = Q->next; //标记要删除的节点Q->next = W->next; //孤立要删除的节点free(W); //释放要删除的节点W = NULL;//表长变化L->len--;printf("删除成功\n");return 0;
}//按位置进行修改
int list_update_pos(Node_ptr L,int pos,datatype e)
{//判断逻辑 if(NULL==L||list_empty(L)||pos<1||pos>L->len){printf("删除失败\n");return -1;}//查找指定节点Node_ptr Q = list_find_node(L,pos-1); //找到前驱//进行修改Q->data = e;printf("修改成功\n");return 0;
}//单向链表翻转
int list_reverse(Node_ptr L)
{//判断逻辑 if(NULL==L||list_empty(L)||L->len == 1){printf("翻转失败\n");return -1;}//翻转逻辑Node_ptr H = L->next; //用头指针托管链表L->next = NULL; //清空当前链表while(H!=NULL){Node_ptr Q = H; //挖墙脚H= H->next; //管理下一位//以头插法的形式将Q插入到L中Q->next = L->next;L->next = Q;}printf("翻转成功\n");return 0;
}//销毁单链表
void list_destroy(Node_ptr L)
{//判断逻辑if(NULL == L||L->next == NULL){printf("销毁失败\n");return ;}Node_ptr Q = L->next;while(Q!=NULL){Node_ptr temp = Q;Q = Q->next;free(temp);}L->next = NULL;printf("销毁成功\n");/*//释放逻辑//将所有普通节点释放while(!list_empty(L)){//调用头删除函数list_head_delete(L);}//释放头节点free(L);L = NULL;printf("销毁成功\n");*/
}//单链表尾插
int list_insert_tail(Node_ptr L,datatype e)
{//判断逻辑if(NULL == L){printf("单链表不合法\n");return -1;}//插入逻辑Node_ptr Q = list_find_node(L,L->len);Node_ptr W = node_apply(e);Q->next = W;//长度变化L->len++;printf("添加成功\n");return 0;
}//单链表的尾删
int list_delete_tail(Node_ptr L)
{if(NULL == L||L->len<1){printf("删除失败\n");return -1;}//删除逻辑Node_ptr Q = list_find_node(L,L->len-1);Node_ptr W = Q->next;Q->next = NULL;free(W);W = NULL;//长度变化L->len--;printf("删除成功\n");return 0;}//单链表按值查找返回位置
int list_find_value(Node_ptr L,int e)
{//判断逻辑if(NULL == L||list_empty(L)){printf("查找失败\n");return -1;}//查找逻辑Node_ptr Q = L->next;for(int i=0;i<L->len;i++){if(Q->data == e){printf("查找成功\n");return i+1;}Q = Q->next;}printf("未查找到该值\n");return 0;
}//单链表按值修改
int list_edit_value(Node_ptr L,int w,datatype e)
{//判断逻辑if(NULL == L||list_empty(L)){printf("查找失败\n");return -1;}//修改逻辑int flag = 0; //检测是否修改Node_ptr Q = L->next;for(int i=0;i<L->len;i++){if(Q->data == w){flag = 1;Q->data = e;}Q = Q->next;}if(flag == 0){printf("未查找到该值\n");return 0;}else{printf("修改成功\n");return 0;}}//单链表的排序
int list_sort(Node_ptr L)
{if(NULL == L||list_empty(L)){printf("排序失败\n");return -1;}//排序逻辑Node_ptr Q = NULL;Node_ptr T = NULL;Node_ptr W = NULL;//冒泡排序for(int i=1;i<L->len;i++){Q = L;T = Q->next;W = T->next;for(int j=0;j<L->len-i;j++){//升序if(T->data > W->data){T->next = W->next;//链接后面节点W->next = Q->next;Q->next = W;//便于下次交换Q=Q->next;//p已经被交换到后面W = T->next;}else{//不满足条件继续后移比较Q = Q->next;T = T->next;W = W->next;}}}return 0;
}//单链表的去重
/*
int list_duplicate_removal(Node_ptr L)
{if(NULL == L||L->len<2||list_empty(L)){printf("去重失败\n");return -1;}//去重逻辑Node_ptr Q = L;Node_ptr T = NULL;Node_ptr W = NULL;//外层循环避免多个重复元素,控制趟数
for(int i=1;i<L->len-1;i++)//for(int i=1;Q!=NULL||Q->next !=NULL;i++){T = Q;//内层循环结束,重新指向W = Q->next;for(int j=0;j<L->len-2-i;j++)//for(int j=0;W!=NULL;j++){if(T->data == W->data){Node_ptr Temp = W->next;free(W);//删除重复部分,释放内存T->next = Temp;//长度变化L->len--;printf("%d\n",L->len);}else{W = W->next; //移动到下一个节点}}Q = Q->next;//内层循环结束向前移动一次}printf("去重成功\n");return 0;
}
*/
int list_duplicate_removal(Node_ptr L) {if (NULL == L || L->len < 2 || list_empty(L)) {printf("去重失败\n");return -1;}Node_ptr T, W, prev;int i;// 遍历链表,T为当前节点,W为T的下一个节点for (T = L->next, prev = L; T != NULL && T->next != NULL; ) {W = T->next; // W指向T的下一个节点// 检查W是否与T之后的节点有重复while (W != NULL) {if (T->data == W->data) {Node_ptr temp = W->next; // 保存W的下一个节点prev->next = temp; // 跳过W节点free(W); // 释放W节点的内存L->len--; // 更新链表长度W = temp; // W更新为新的节点,继续检查} else {prev = W; // 更新prev为W,W移动到下一个节点W = W->next;}}T = T->next; // T移动到下一个节点}printf("去重成功\n");return 0;
}//清空单链表
int list_clear(Node_ptr L)
{if(NULL == L||list_empty(L)){printf("单链表不存在或为空\n");return -1;}while(L->next!=NULL){list_head_delete(L);}printf("清空完成\n");return 0;
}
//返回单链表的长度
int list_len(Node_ptr L)
{if(NULL == L){printf("该链表不存在\n");return -1;}Node_ptr Q = L->next;int num = 0;while(Q){Q = Q->next;num++;}return num;
}
相关文章:
2024.11.29(单链表)
思维导图 声明文件 #ifndef __LINKLIST_H__ #define __LINKLIST_H__#include <myhead.h>typedef char datatype; //数据元素类型 //定义节点类型 typedef struct Node {union{int len; //头节点数据域datatype data; //普通节点数据域};struct Node *next; //指针域…...
基于深度学习和卷积神经网络的乳腺癌影像自动化诊断系统(PyQt5界面+数据集+训练代码)
乳腺癌是全球女性中最常见的恶性肿瘤之一,早期准确诊断对于提高生存率具有至关重要的意义。传统的乳腺癌诊断方法依赖于放射科医生的经验,然而,由于影像分析的复杂性和人类判断的局限性,准确率和一致性仍存在挑战。近年来…...
opengl 三角形
最后效果: OpenGL version: 4.1 Metal 不知道为啥必须使用VAO 才行。 #include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream> #include <vector>void framebuffer_size_callback(GLFWwindow *window, int width, int heigh…...
23种设计模式-抽象工厂(Abstract Factory)设计模式
文章目录 一.什么是抽象工厂设计模式?二.抽象工厂模式的特点三.抽象工厂模式的结构四.抽象工厂模式的优缺点五.抽象工厂模式的 C 实现六.抽象工厂模式的 Java 实现七.代码解析八.总结 类图: 抽象工厂设计模式类图 一.什么是抽象工厂设计模式?…...
手机上怎么拍证件照,操作简单且尺寸颜色标准的方法
在数字化时代,手机已成为我们日常生活中不可或缺的一部分。它不仅是通讯工具,更是我们拍摄证件照的便捷利器。然而,目前证件照制作工具鱼龙混杂,很多打着免费名号的拍照软件背后却存在着泄漏用户信息、照片制作不规范导致无法使用…...
IDEA报错: java: JPS incremental annotation processing is disabled 解决
起因 换了个电脑打开了之前某个老项目IDEA启动springcloud其中某个服务直接报错,信息如下 java: JPS incremental annotation processing is disabled. Compilation results on partial recompilation may be inaccurate. Use build process “jps.track.ap.depen…...
OCR实现微信截图改名
pip install paddlepaddle -i https://pypi.tuna.tsinghua.edu.cn/simple/ ──(Sat,Nov30)─┘ pip install shapely -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install paddleo…...
第一届“吾杯”网络安全技能大赛 Writeup
战队信息 战队名称:在你眼中我是誰,你想我代替誰? 战队排名:13 Misc Sign Hex 转 Str,即可得到flag。 原神启动! 不好评价,stegsolve 秒了: WuCup{7c16e21c-31c2-439e-a814-b…...
再谈Java中的String类型是否相同的判断方法
目录 第一部分 代码展示 画图展示 第二部分 代码展示 画图展示 第一部分 代码展示 画图展示 第二部分 代码展示 画图展示...
<一>51单片机环境
目录 1,51单片机开发语言是C,环境keil 1.1,工程创建 1.2用什么把代码放进单片机里面 2,初识代码 1,51单片机开发语言是C,环境keil 1.1,工程创建 1. 创建项目工程文件夹,可以当作模板Template 2. 创建文件,取名main.c 3,编译,选择输出文…...
【0x0001】HCI_Set_Event_Mask详解
目录 一、命令概述 二、命令格式 三、命令参数说明 四、返回参数说明 五、命令执行流程 5.1. 主机准备阶段 5.2. 命令发送阶段 5.3. 控制器接收与处理阶段 5.4. 事件过滤与反馈阶段 5.5. 主机处理(主机端) 5.6. 示例代码 六、命令应用场景 …...
第三方Express 路由和路由中间件
文章目录 1、Express 应用使用回调函数的参数: request 和 response 对象来处理请求和响应的数据。2、Express路由1.路由方法2.路由路径3.路由处理程序 3. 模块化路由4. Express中间件1.中间件简介2.中间件分类3.自定义中间件 1、Express 应用使用回调函数的参数&am…...
七、Python —— 元组、集合和字典
文章目录 一、元组1.1、元组的初始化1.2、元组的解包1.3、元组的比较运算1.4、元组的其他操作 二、集合 set2.1、集合的初始化2.2、集合的常用操作2.3、使用 for 循环遍历集合 三、字典 map3.1、字典的初始化3.2、字典的常用操作3.3、使用 for 循环遍历字典 四、补充 一、元组 …...
Aes加解密
加解密概念 加密AES加密填充模式加密模式示例 加密 通过一系列计算将明文转换成一个密文。 加密和解密的对象通常是字节数组(有的语言动态数组类比切片) 加密后的数据,可能有很多是不可读字符。通常会将其转换为可见的字符串。 直接将字节…...
【时时三省】Tessy 故障入侵 使用教程
目录 1,故障入侵 介绍 故障入侵适用场景: 打故障入侵的方法和选项介绍: 2,打单个函数的故障入侵 3,打整体用例的故障入侵 4,一个函数打多个故障入侵 山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 1,故障入侵 介绍 故障入侵适用场景: 故障入侵 …...
.NET 9 AOT的突破 - 支持老旧Win7与XP环境
引言 随着技术的不断进步,微软的.NET 框架在每次迭代中都带来了令人惊喜的新特性。在.NET 9 版本中,一个特别引人注目的亮点是 AOT( Ahead-of-Time)支持,它允许开发人员将应用程序在编译阶段就优化为能够在老旧的 Win…...
CondaValueError: Malformed version string ‘~‘: invalid character(s).
问题描述:在window下使用conda安装任何包都会报错。报错信息是CondaValueError: Malformed version string ~: invalid character(s). 解决办法:把.condarc文件的源地址删除(八成是源地址访问不了了),只保存默认的&am…...
01-Ubuntu24.04LTS上安装PGSQL
目录 一、准备工作 1.1、系统要求 1.2 、更新 Ubuntu 系统 1.3 、安装依赖 1.4 、添加 PostgreSQL 16 软件源 二、安装 PostgreSQL 16 数据库 三、管理 PostgreSQL 服务 四、PostgreSQL 管理操作 4.1 、访问 Postgres 超级用户账户 4.2 、创建数据库并设置管理权限 4…...
Esp32使用micropython基于espnow实现语音对讲机
ESP-NOW协议介绍 ESP-NOW 是乐鑫自主研发的无连接通信协议,具有短数据包传输功能。该协议使多个设备能够以简单的方式相互通信。ESP-NOW 支持以下功能: 加密和未加密的单播通信; 混合加密和未加密的对等设备; 最多可携带 250 字节 的有效载荷; 发送回调功能,可以设置用于…...
Docker 容器隔离关键技术:SELinux
Docker 容器隔离关键技术:SELinux SELinux(Security-Enhanced Linux) 是 Linux 内核中的一项安全机制,用于实现强制访问控制(MAC)。Docker 利用了 SELinux 来增强容器的隔离性,通过对文件、进程…...
低门槛语音AI落地:SenseVoice-Small ONNX非技术人员使用指南
低门槛语音AI落地:SenseVoice-Small ONNX非技术人员使用指南 你是不是也觉得语音转文字很麻烦?要么得联网上传录音,担心隐私泄露;要么本地工具配置复杂,一堆命令行看得人头疼;要么识别出来的文字没有标点&…...
Meta 打造 AI 版扎克伯格与员工交流,扎克伯格亲力亲为 AI 项目,股价涨 7%
Meta 正打造人工智能版马克扎克伯格用于和员工交流,该工作处于早期阶段。同时,扎克伯格在人工智能发展上亲力亲为,Meta 发布新模型后股价上涨 7%。打造 AI 版扎克伯格作为重塑公司为人工智能核心的一部分,Meta 正在打造人工智能版…...
砸钱、站台、被拉黑:孙宇晨与特朗普家族的「塑料友谊」翻车了
撰文:Yangz,Techub News曾经把特朗普称为「加密行业恩人」的孙宇晨,这两天彻底翻脸了。4 月 12 日下午,孙宇晨突然发文炮轰由特朗普家族支持的 DeFi 项目 World Liberty Financial(WLFI)。他抛出了一连串指…...
【三维重建】【3DGS系列】【深度学习】从概率密度到几何形体:3D高斯椭球的数学构建与可视化
1. 从概率密度到几何形体:3D高斯椭球的数学本质 第一次接触3D高斯泼溅(3DGS)技术时,最让我困惑的就是为什么一个概率分布函数能表示三维几何体。后来在复现论文代码时才发现,这背后的数学之美就藏在多维高斯分布的等概率密度面中。想象一下捏…...
Flink CDC 3.0.0 同步Oracle 19c数据,我踩过的那些坑(时区、字符集、权限)
Flink CDC 3.0.0同步Oracle 19c实战避坑指南 最近在金融级数据中台项目中实施Flink CDC 3.0.0对接Oracle 19c时,遇到了不少官方文档未提及的"深坑"。这些坑轻则导致数据不一致,重则引发生产事故。本文将分享五个典型问题的完整解决方案&#x…...
MySQL在Windows环境下的高效部署与实战指南
1. Windows平台MySQL安装方式全解析 第一次在Windows上装MySQL的朋友可能会被各种安装包搞晕头。作为一个踩过无数坑的老司机,我强烈建议新手从图形化安装入手。Windows平台主要有两种安装方式:图形化安装(.msi)和免安装版&#x…...
全文降AI工具价格效果对比:嘎嘎降AI、比话降AI怎么选
全文降AI工具价格效果对比:嘎嘎降AI、比话降AI怎么选 选全文降AI工具的时候,大家最关心两件事:一是效果好不好,二是价格贵不贵。 效果不好,花再少的钱也是浪费。效果好但价格离谱,很多同学也吃不消。所以最…...
[精品]基于微信小程序的宿舍报修系统的设计与实现 UniApp
收藏关注不迷路!!需要的小伙伴可以发链接或者截图给我 这里写目录标题项目介绍项目实现效果图所需技术栈文件解析微信开发者工具HBuilderXuniappmysql数据库与主流编程语言登录的业务流程的顺序是:毕设制作流程系统性能核心代码系统测试详细视…...
Gilisoft Total Repair(全能修复大师)
链接:https://pan.quark.cn/s/a8e8b547d1f9Gilisoft Total Repair是一款功能强大的文件修复软件,中文又被成为“全能修复大师”,具有一键式智能修复引擎,可以自动解决500多个常见问题,如系统延迟、游戏崩溃和文件损坏。…...
从手动压枪到智能补偿:罗技鼠标宏如何革新绝地求生射击体验
从手动压枪到智能补偿:罗技鼠标宏如何革新绝地求生射击体验 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 在《绝地求生》这类战术竞…...
