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

单链表的实现

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主页&#xff1a;醋溜马桶圈_C语言进阶,初始C语言,数据结构-CSDN博客 Gitee主页&#xff1a;mnxcc (mnxcc) - Gitee.com 专栏&#xff1a;数据结构_醋溜马桶圈的博客-CSDN博客 目录 1.认识单链表 2.创建单链表 3.单链表的操作 3.1打印单链表 3.2开辟新空间 3.3尾插 3.4头插…...

【python】面向对象(类型定义魔法方法)

目录 一、引言 二、类型定义 1、什么是类型的定义&#xff1f; 2、案例 三、魔法方法 1、什么是魔法方法 2、基础部分 3、比较操作 4、容器类型 5、属性管理 6、封装 7、方法拓展 8、继承 9、多态 一、引言 Python是一种面向对象的语言&#xff0c;它支持类&#…...

1.微服务与SpringCloud

微服务和SpringCloud 文章目录 微服务和SpringCloud1.什么是微服务2.SpringCloud3. 微服务 VS SpringCloud4. SpringCloud 组件5.参考文档6.版本要求 1.什么是微服务 微服务是将一个大型的、单一的应用程序拆分成多个小型服务&#xff0c;每个服务实现特定的业务功能&#xff…...

【2023全网最全最火】Selenium WebDriver教程(建议收藏)

在本教程中&#xff0c;我将向您介绍 Selenium Webdriver&#xff0c;它是当今市场上使用最广泛的自动化测试框架。它是开源的&#xff0c;可与所有著名的编程语言&#xff08;如Java、Python、C&#xff03;、Ruby、Perl等&#xff09;一起使用&#xff0c;以实现浏览器活动的…...

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问题解决&#xff08;生产环境慎用&#xff09; 问题描述解决方案 问题描述 1.连接超时 2.连接能连上但马上断开并报错 3.提示保护模式什么的 (error) DENIED Redis is running in protected mode because protected mode is enabled链接redis …...

给女朋友开发个小程序低价点外卖吃还能赚钱

前言 今天又是无聊的一天,逛了下GitHub,发现一个库里面介绍美团饿了吗外卖红包外卖优惠券,先领红包再下单。外卖红包优惠券,cps分成,别人领红包下单,你拿佣金。哇靠,那我岂不是可以省钱还可以赚钱,yyds。。。。想想都美好哈哈哈!!! 回到正题,这个是美团饿了么分销…...

外贸客户管理系统是什么?推荐的管理软件?

外贸客户管理系统哪个好用&#xff1f;海洋建站如何选管理系统&#xff1f; 外贸客户管理系统&#xff0c;是一款专为外贸企业设计的客户关系管理系统&#xff0c;旨在帮助外贸企业建立与维护客户关系&#xff0c;提高客户满意度和忠诚度&#xff0c;提升企业业绩。海洋建站将…...

数据挖掘:分类,聚类,关联关系,回归

数据挖掘&#xff1a; 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sql要学&…...

力扣labuladong一刷day10一网打尽股票买卖问题共6题

力扣labuladong一刷day10股票买卖问题共6题 一、121. 买卖股票的最佳时机 题目链接&#xff1a;https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/ 思路&#xff1a;只能买入1次&#xff0c;定义dp[i][0]数组表示第i天持有股票时手中的最大金额 数&#xff0c;…...

微信小程序手写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&#xff1a;https://www.bilibili.com/video/BV1Hm4y1t7Kn/?spm_id_from333.337.search-card.all.click&vd_source707ec8983cc32e6e065d5496a7f79ee6 视…...

oracle删除重复的数据

去除重复数据&#xff1a; group by 对要比对的字段进行查询是否重复 CREATE TABLE 临时表 AS (select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1) 上面这句话就是建立了临时表&#xff0c;并将查询到的数据插入其中。 下面就可以进行…...

Python中的并发编程是什么,如何使用Python进行并发编程?

Python中的并发编程是指使用多线程或多进程来同时执行多个任务。这样可以提高程序的执行效率&#xff0c;特别是在处理I/O密集型任务时。Python提供了多种方式来实现并发编程&#xff0c;如threading模块和multiprocessing模块。 使用Python进行并发编程的方法如下&#xff1a…...

【LeetCode】136. 只出现一次的数字

136. 只出现一次的数字 难度&#xff1a;简单 题目 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且该算法只使用…...

HTTP服务器——tomcat的安装和使用

文章目录 前言下载tomcattomcat 文件bin 文件夹conf 文件lib 文件log 文件temp 文件webapps 文件work 目录 如何使用 tomcat 前言 前面我们已经学习了应用层协议 HTTP 协议和 HTTP 的改进版——HTTPS&#xff0c;这些协议是我们在写与服务器相关的代码的时候息息相关的&#x…...

代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和

LeetCode T1143 最长公共子序列 题目链接:1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 动规五部曲分析 1.确定dp数组的含义 这里dp数组的含义是结尾分别为i-1,j-1的text1和text2的最长公共子序列长度 至于为什么是i-1,j-1我之前已经说过了,这里再…...

写了个监控 ElasticSearch 进程异常的脚本!

服务器配置免密钥环境准备&#xff1a; 配置免密钥前&#xff0c;需要在服务器的 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新闻表 数据库系统是用来保存数据的软件系统&#xff0c;当今比较流行的数据库系统&#xff0c;如 MS…...

电脑检测温度软件有哪些?

环境&#xff1a; Win10 专业版 问题描述&#xff1a; 电脑检测温度软件有哪些&#xff1f; 解决方案&#xff1a; 有很多电脑检测温度的软件可供选择&#xff0c;以下是一些常用的电脑温度监测工具&#xff1a; HWMonitor&#xff1a;一款免费的硬件监控软件&#xff0…...

设计模式 -- 单例模式(Singleton Pattern)

单例模式&#xff1a;最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式…...

ubuntu给终端加代理服务器

ubuntu给终端加代理 访问google.com 是否可以访问通 curl https://www.google.com如果访问不通说明代理服务器没有配置好。 使用 gedit ~/.bashrc 打开网络配置 gedit ~/.bashrc找到文章的最后添加代理 export http_proxyhttp://127.0.0.1:7890 export https_proxyhttp://…...

centos 6.10 安装 readline 6.2.0

下载地址 解压文件 cd readline-6.2 ./configure -prefix /usr/local/readline-6.2 make && make install安装完成...

IDEA 2023搭建 SpringMVC +FreeMarker+JDBC

1.IDEA的版本&#xff0c;目前最新是2023&#xff0c;要选择旗舰版。笔者曾选择社区版&#xff0c;发现少了很多功能。只能重新安装。 2.安装好以后的第1件事&#xff0c;是设置Maven&#xff0c;并将下载地址改为淘定站&#xff0c;参照这篇一次包会——最新IDEA配置Maven指南…...

RabbitMQ传统数据持久化和Lazy queue的区别

问题引出&#xff1a; 在了解这个问题前我们需要一些前置知识&#xff1a; 关于MQ可靠性&#xff0c;在默认情况下&#xff0c;RabbitMQ会将接收到的信息保存在内存中以降低消息收发的延迟。这样会导致两个问题&#xff1a; 一旦MQ宕机&#xff0c;内存中的信息会丢失 内存空…...

docker部署lnmp环境

文章目录 前期准备&#xff1a;一、部署mysql1.1 获取 Mysql 5.7.22 镜像1.2 启动mysql容器 二、部署php2.1 获取php 7.2镜像2.2 启动php 容器2.3 php的扩展安装 三、部署nginx3.1 获取nginx:1.14镜像3.2 启动nginx容器3.3 编写nginx虚拟主机配置文件&#xff0c;使其支持php3.…...

数据结构 | 带头双向循环链表专题

数据结构 | 带头双向循环链表专题 前言 前面我们学了单链表&#xff0c;我们这次来看一个专题带头的双向循环链表~~ 文章目录 数据结构 | 带头双向循环链表专题前言带头双向循环链表的结构实现双向链表头文件的定义创建节点哨兵位初始化尾插尾删头插头删打印查找指定位置前插入…...

Redis使用Pipeline(管道)批量处理

Redis 批量处理 在开发中&#xff0c;有时需要对Redis 进行大批量的处理。 比如Redis批量查询多个Hash。如果是在for循环中逐个查询&#xff0c;那性能会很差。 这时&#xff0c;可以使用 Pipeline (管道)。 Pipeline (管道) Pipeline (管道) 可以一次性发送多条命令并在执…...

Linux中at命令添加一次性任务

1、工作原理 功能&#xff1a;在某个时间点&#xff0c;执行一次命令。 特点&#xff1a;任务是用户隔离的。 条件&#xff1a;必须要保证atd进程存在。 ps -ef |grep atd 原理&#xff1a;atd进程循环遍历队列里的任务&#xff0c;有任务&#xff0c;且到达执行时间&#xff…...

交换机基础知识之安全配置

交换机在网络基础设施中扮演着重要角色&#xff0c;它促进了设备之间数据包的流动。正因此&#xff0c;采取适当的安全措施来保护网络免受未经授权的访问和潜在攻击至关重要。本文将全面解读交换机基础安全配置知识&#xff0c;并提供实践方案&#xff0c;以保证安全的网络环境…...