单链表的实现
CSDN主页:醋溜马桶圈_C语言进阶,初始C语言,数据结构-CSDN博客
Gitee主页:mnxcc (mnxcc) - Gitee.com
专栏:数据结构_醋溜马桶圈的博客-CSDN博客
目录
1.认识单链表
2.创建单链表
3.单链表的操作
3.1打印单链表
3.2开辟新空间
3.3尾插
3.4头插
3.5尾删
3.6头删
3.7查找
3.8在pos前面插入
3.9删除pos位置
3.10销毁
3.11在pos位置之后插入
3.12删除pos位置之后的值
4.总代码
SList.h
SList.c
test.c
我们之前学习了顺序表的有关知识,顺序表存在下面的问题:
- 尾插效率还不错,头插或中间插入删除,需要挪动数据,效率低
- 满了以后只能扩容,扩容是有一定的消耗的,扩容一般存在一定的空间浪费
1.认识单链表
这篇文章我们来认识一下单链表

如果想要插入一个结点,就不需要挪动数据了,改指针的指向就可以了

同样我们删除结点,直接将前一个结点的指针指向后一个结点就可以了

首先我们还是从工程的角度去考虑,创建SList.h SList.c test.c三个文件

SList.h放置函数的声明
SList.c放置函数的定义
test.c进行测试
2.创建单链表

3.单链表的操作
3.1打印单链表
//打印单链表
//尽量不要动phead
void SLTPrint(SLNode* phead)
{SLNode* cur = phead;while (cur != NULL){printf("%d->", cur->val);cur = cur->next;}printf("NULL\n");
}
3.2开辟新空间
//开辟新空间
SLNode* CreateNode(SLNDataType x)
{SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->val = x;newnode->next = NULL;return newnode;
}
3.3尾插
//尾插
void SLTPushBack(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}
3.4头插
//头插
void SLTPushFront(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = *pphead;*pphead = newnode;
}
3.5尾删
//尾删
void SLTPopBack(SLNode** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLNode* prev = NULL;SLNode* tail = *pphead;while (tail->next != NULL){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}
}
3.6头删
//头删
void SLTPopFront(SLNode** pphead)
{assert(*pphead);SLNode* tmp = *pphead;*pphead = (*pphead)->next;free(tmp);
}
3.7查找
//查找
SLNode* SLTFind(SLNode* phead, SLNDataType x)
{SLNode* cur = phead;while (cur){if (cur->val == x){return cur;}else{cur = cur->next;}}return NULL;
}
3.8在pos前面插入
//在pos前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{assert(pphead);assert(pos);assert(*pphead);//assert((!pos && !(*pphead)) || (pos && (*pphead)));if (*pphead == pos){SLTPushFront(pphead, x);}else{SLNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}SLNode* newnode = CreateNode(x);prev->next = newnode;newnode->next = pos;}
}
3.9删除pos位置
//删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos)
{assert(pphead);assert(pos);assert(*pphead);if (*pphead == pos){SLTPopFront(pphead);}else{SLNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}
3.10销毁
//销毁
void SLTDestroy(SLNode** pphead)
{assert(pphead);SLNode* cur = *pphead;while (cur->next != NULL){SLNode* next = cur->next;free(cur);cur = next;}*pphead = NULL;
}
3.11在pos位置之后插入
// 单链表在pos位置之后插入x
void SLTInsertAfter(SLNode* pos, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = pos->next;pos->next = newnode;
}
3.12删除pos位置之后的值
// 单链表删除pos位置之后的值
void SLTEraseAfter(SLNode* pos)
{assert(pos->next != NULL);pos->next = pos->next->next;free(pos->next);pos->next = NULL;
}
4.总代码
SList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//创建单链表
typedef int SLNDataType;
typedef struct SLNode
{SLNDataType val;struct SLNode* next;
}SLNode;//打印单链表
//尽量不要动phead
void SLTPrint(SLNode* phead);
//开辟新空间
SLNode* CreateNode(SLNDataType x);//尾插
void SLTPushBack(SLNode** pphead, SLNDataType x);
//头插
void SLTPushFront(SLNode** pphead, SLNDataType x);
//尾删
void SLTPopBack(SLNode** pphead);
//头删
void SLTPopFront(SLNode** pphead);//查找
SLNode* SLTFind(SLNode* phead, SLNDataType x);
//在pos前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x);
//删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos); // 单链表在pos位置之后插入x
void SLTInsertAfter(SLNode* pos, SLNDataType x);
// 单链表删除pos位置之后的值
void SLTEraseAfter(SLNode* pos);//销毁
void SLTDestroy(SLNode** pphead);
SList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"
//打印单链表
//尽量不要动phead
void SLTPrint(SLNode* phead)
{SLNode* cur = phead;while (cur != NULL){printf("%d->", cur->val);cur = cur->next;}printf("NULL\n");
}
//开辟新空间
SLNode* CreateNode(SLNDataType x)
{SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->val = x;newnode->next = NULL;return newnode;
}
//尾插
void SLTPushBack(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}
//头插
void SLTPushFront(SLNode** pphead, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = *pphead;*pphead = newnode;
}
//尾删
void SLTPopBack(SLNode** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLNode* prev = NULL;SLNode* tail = *pphead;while (tail->next != NULL){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}
}
//头删
void SLTPopFront(SLNode** pphead)
{assert(*pphead);SLNode* tmp = *pphead;*pphead = (*pphead)->next;free(tmp);
}
//查找
SLNode* SLTFind(SLNode* phead, SLNDataType x)
{SLNode* cur = phead;while (cur){if (cur->val == x){return cur;}else{cur = cur->next;}}return NULL;
}
//在pos前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{assert(pphead);assert(pos);assert(*pphead);//assert((!pos && !(*pphead)) || (pos && (*pphead)));if (*pphead == pos){SLTPushFront(pphead, x);}else{SLNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}SLNode* newnode = CreateNode(x);prev->next = newnode;newnode->next = pos;}
}
//删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos)
{assert(pphead);assert(pos);assert(*pphead);if (*pphead == pos){SLTPopFront(pphead);}else{SLNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}
// 单链表在pos位置之后插入x
void SLTInsertAfter(SLNode* pos, SLNDataType x)
{SLNode* newnode = CreateNode(x);newnode->next = pos->next;pos->next = newnode;
}
// 单链表删除pos位置之后的值
void SLTEraseAfter(SLNode* pos)
{assert(pos->next != NULL);pos->next = pos->next->next;free(pos->next);pos->next = NULL;
}
//销毁
void SLTDestroy(SLNode** pphead)
{assert(pphead);SLNode* cur = *pphead;while (cur->next != NULL){SLNode* next = cur->next;free(cur);cur = next;}*pphead = NULL;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
int main()
{SLNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushFront(&plist, 5);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLNode* pos = SLTFind(plist, 2);SLTInsert(&plist, pos, 0);SLTPrint(plist);/*SLTErase(&plist, pos);SLTPrint(plist);*/SLTInsertAfter(pos, 0);SLTPrint(plist);SLTEraseAfter(pos);SLTPrint(plist);SLTDestroy(&plist);return 0;
}相关文章:
单链表的实现
CSDN主页:醋溜马桶圈_C语言进阶,初始C语言,数据结构-CSDN博客 Gitee主页:mnxcc (mnxcc) - Gitee.com 专栏:数据结构_醋溜马桶圈的博客-CSDN博客 目录 1.认识单链表 2.创建单链表 3.单链表的操作 3.1打印单链表 3.2开辟新空间 3.3尾插 3.4头插…...
【python】面向对象(类型定义魔法方法)
目录 一、引言 二、类型定义 1、什么是类型的定义? 2、案例 三、魔法方法 1、什么是魔法方法 2、基础部分 3、比较操作 4、容器类型 5、属性管理 6、封装 7、方法拓展 8、继承 9、多态 一、引言 Python是一种面向对象的语言,它支持类&#…...
1.微服务与SpringCloud
微服务和SpringCloud 文章目录 微服务和SpringCloud1.什么是微服务2.SpringCloud3. 微服务 VS SpringCloud4. SpringCloud 组件5.参考文档6.版本要求 1.什么是微服务 微服务是将一个大型的、单一的应用程序拆分成多个小型服务,每个服务实现特定的业务功能ÿ…...
【2023全网最全最火】Selenium WebDriver教程(建议收藏)
在本教程中,我将向您介绍 Selenium Webdriver,它是当今市场上使用最广泛的自动化测试框架。它是开源的,可与所有著名的编程语言(如Java、Python、C#、Ruby、Perl等)一起使用,以实现浏览器活动的…...
dimp 导入dmp文件报错:无效的模式名(DM8:达梦数据库)
dimp 导入dmp文件报错:无效的模式名-DM8:达梦数据库 环境介绍1 搭建A1 数据库52361.1 A1数据库5236创建模式名,表,测试数据1.2 从A1数据库5236导出dmp文件 2 搭建A2数据库52372.1 创建 数据用户ABC2311152.2 在A2 数据库5237 导入DMP(报错无效的模式名)2.3 使用REMAP_SCHEMAABC…...
宿主机无法连接docker里的redis问题解决(生产环境慎用)
宿主机无法连接docker里的redis问题解决(生产环境慎用) 问题描述解决方案 问题描述 1.连接超时 2.连接能连上但马上断开并报错 3.提示保护模式什么的 (error) DENIED Redis is running in protected mode because protected mode is enabled链接redis …...
给女朋友开发个小程序低价点外卖吃还能赚钱
前言 今天又是无聊的一天,逛了下GitHub,发现一个库里面介绍美团饿了吗外卖红包外卖优惠券,先领红包再下单。外卖红包优惠券,cps分成,别人领红包下单,你拿佣金。哇靠,那我岂不是可以省钱还可以赚钱,yyds。。。。想想都美好哈哈哈!!! 回到正题,这个是美团饿了么分销…...
外贸客户管理系统是什么?推荐的管理软件?
外贸客户管理系统哪个好用?海洋建站如何选管理系统? 外贸客户管理系统,是一款专为外贸企业设计的客户关系管理系统,旨在帮助外贸企业建立与维护客户关系,提高客户满意度和忠诚度,提升企业业绩。海洋建站将…...
数据挖掘:分类,聚类,关联关系,回归
数据挖掘: 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,oracle,尤其sql要学&…...
力扣labuladong一刷day10一网打尽股票买卖问题共6题
力扣labuladong一刷day10股票买卖问题共6题 一、121. 买卖股票的最佳时机 题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/ 思路:只能买入1次,定义dp[i][0]数组表示第i天持有股票时手中的最大金额 数,…...
微信小程序手写table表格
wxml <view class"table"><view class"tr bg-w"><view class"th">张三</view><view class"th" style"color: #409eff;">李四</view><view class"th ">王五</view&…...
UE5 - UI Material Lab 学习笔记
1、学习资料收集 UI Material Lab : https://www.unrealengine.com/marketplace/zh-CN/product/ui-material-lab 视频1:https://www.bilibili.com/video/BV1Hm4y1t7Kn/?spm_id_from333.337.search-card.all.click&vd_source707ec8983cc32e6e065d5496a7f79ee6 视…...
oracle删除重复的数据
去除重复数据: group by 对要比对的字段进行查询是否重复 CREATE TABLE 临时表 AS (select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1) 上面这句话就是建立了临时表,并将查询到的数据插入其中。 下面就可以进行…...
Python中的并发编程是什么,如何使用Python进行并发编程?
Python中的并发编程是指使用多线程或多进程来同时执行多个任务。这样可以提高程序的执行效率,特别是在处理I/O密集型任务时。Python提供了多种方式来实现并发编程,如threading模块和multiprocessing模块。 使用Python进行并发编程的方法如下:…...
【LeetCode】136. 只出现一次的数字
136. 只出现一次的数字 难度:简单 题目 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用…...
HTTP服务器——tomcat的安装和使用
文章目录 前言下载tomcattomcat 文件bin 文件夹conf 文件lib 文件log 文件temp 文件webapps 文件work 目录 如何使用 tomcat 前言 前面我们已经学习了应用层协议 HTTP 协议和 HTTP 的改进版——HTTPS,这些协议是我们在写与服务器相关的代码的时候息息相关的&#x…...
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
LeetCode T1143 最长公共子序列 题目链接:1143. 最长公共子序列 - 力扣(LeetCode) 题目思路: 动规五部曲分析 1.确定dp数组的含义 这里dp数组的含义是结尾分别为i-1,j-1的text1和text2的最长公共子序列长度 至于为什么是i-1,j-1我之前已经说过了,这里再…...
写了个监控 ElasticSearch 进程异常的脚本!
服务器配置免密钥环境准备: 配置免密钥前,需要在服务器的 hosts 文件中配置目标主机名称与 IP 对应关系。 vim /etc/hosts IP1 hostname1 IP2 hostname2 ...... 将 mianmiyaojiaoben.zip 安装包解压在当前目录下 cd /usr/local/jiaoben unzip mianmi…...
第三篇 基于JSP 技术的网上购书系统—— 数据库系统设计(网上商城、仿淘宝、当当、亚马逊)
目录 1.逻辑关系设计 2.物理设计 2.1管理员表 2.2留言表 2.3会员登录表 2.4会员表 2.5订单表 2.6订单商品表 2.7产品表 2.8产品货架表 2.9收藏表 2.10类别表 2.11新闻表 数据库系统是用来保存数据的软件系统,当今比较流行的数据库系统,如 MS…...
电脑检测温度软件有哪些?
环境: Win10 专业版 问题描述: 电脑检测温度软件有哪些? 解决方案: 有很多电脑检测温度的软件可供选择,以下是一些常用的电脑温度监测工具: HWMonitor:一款免费的硬件监控软件࿰…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
鸿蒙Navigation路由导航-基本使用介绍
1. Navigation介绍 Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(Navigation的子组件)或非首页显示(Nav…...
安宝特方案丨从依赖经验到数据驱动:AR套件重构特种装备装配与质检全流程
在高压电气装备、军工装备、石油测井仪器装备、计算存储服务器和机柜、核磁医疗装备、大型发动机组等特种装备生产型企业,其产品具有“小批量、多品种、人工装配、价值高”的特点。 生产管理中存在传统SOP文件内容缺失、SOP更新不及、装配严重依赖个人经验、产品装…...
