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

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界面+数据集+训练代码)

乳腺癌是全球女性中最常见的恶性肿瘤之一&#xff0c;早期准确诊断对于提高生存率具有至关重要的意义。传统的乳腺癌诊断方法依赖于放射科医生的经验&#xff0c;然而&#xff0c;由于影像分析的复杂性和人类判断的局限性&#xff0c;准确率和一致性仍存在挑战。近年来&#xf…...

opengl 三角形

最后效果&#xff1a; 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)设计模式

文章目录 一.什么是抽象工厂设计模式&#xff1f;二.抽象工厂模式的特点三.抽象工厂模式的结构四.抽象工厂模式的优缺点五.抽象工厂模式的 C 实现六.抽象工厂模式的 Java 实现七.代码解析八.总结 类图&#xff1a; 抽象工厂设计模式类图 一.什么是抽象工厂设计模式&#xff1f…...

手机上怎么拍证件照,操作简单且尺寸颜色标准的方法

在数字化时代&#xff0c;手机已成为我们日常生活中不可或缺的一部分。它不仅是通讯工具&#xff0c;更是我们拍摄证件照的便捷利器。然而&#xff0c;目前证件照制作工具鱼龙混杂&#xff0c;很多打着免费名号的拍照软件背后却存在着泄漏用户信息、照片制作不规范导致无法使用…...

IDEA报错: java: JPS incremental annotation processing is disabled 解决

起因 换了个电脑打开了之前某个老项目IDEA启动springcloud其中某个服务直接报错&#xff0c;信息如下 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

战队信息 战队名称&#xff1a;在你眼中我是誰&#xff0c;你想我代替誰&#xff1f; 战队排名&#xff1a;13 Misc Sign Hex 转 Str&#xff0c;即可得到flag。 原神启动&#xff01; 不好评价&#xff0c;stegsolve 秒了&#xff1a; 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. 创建项目工程文件夹&#xff0c;可以当作模板Template 2. 创建文件&#xff0c;取名main.c 3,编译&#xff0c;选择输出文…...

【0x0001】HCI_Set_Event_Mask详解

目录 一、命令概述 二、命令格式 三、命令参数说明 四、返回参数说明 五、命令执行流程 5.1. 主机准备阶段 5.2. 命令发送阶段 5.3. 控制器接收与处理阶段 5.4. 事件过滤与反馈阶段 5.5. 主机处理&#xff08;主机端&#xff09; 5.6. 示例代码 六、命令应用场景 …...

第三方Express 路由和路由中间件

文章目录 1、Express 应用使用回调函数的参数&#xff1a; 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加密填充模式加密模式示例 加密 通过一系列计算将明文转换成一个密文。 加密和解密的对象通常是字节数组&#xff08;有的语言动态数组类比切片&#xff09; 加密后的数据&#xff0c;可能有很多是不可读字符。通常会将其转换为可见的字符串。 直接将字节…...

【时时三省】Tessy 故障入侵 使用教程

目录 1,故障入侵 介绍 故障入侵适用场景: 打故障入侵的方法和选项介绍: 2,打单个函数的故障入侵 3,打整体用例的故障入侵 4,一个函数打多个故障入侵 山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 1,故障入侵 介绍 故障入侵适用场景: 故障入侵 …...

.NET 9 AOT的突破 - 支持老旧Win7与XP环境

引言 随着技术的不断进步&#xff0c;微软的.NET 框架在每次迭代中都带来了令人惊喜的新特性。在.NET 9 版本中&#xff0c;一个特别引人注目的亮点是 AOT&#xff08; Ahead-of-Time&#xff09;支持&#xff0c;它允许开发人员将应用程序在编译阶段就优化为能够在老旧的 Win…...

CondaValueError: Malformed version string ‘~‘: invalid character(s).

问题描述&#xff1a;在window下使用conda安装任何包都会报错。报错信息是CondaValueError: Malformed version string ~: invalid character(s). 解决办法&#xff1a;把.condarc文件的源地址删除&#xff08;八成是源地址访问不了了&#xff09;&#xff0c;只保存默认的&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 容器隔离关键技术&#xff1a;SELinux SELinux&#xff08;Security-Enhanced Linux&#xff09; 是 Linux 内核中的一项安全机制&#xff0c;用于实现强制访问控制&#xff08;MAC&#xff09;。Docker 利用了 SELinux 来增强容器的隔离性&#xff0c;通过对文件、进程…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...