数据结构---单链表

目录

一、概念

二、分类

1. 单向或者双向

2. 带头或者不带头  

3. 循环或者非循环  

三、接口实现

1.定义结构

 2、申请节点

3、尾插 

4、头插

 5、尾删

6、头删

7.查找,也可以充当修改

8、在pos之前插入x 

9、在pos之后插入x 

​编辑 10、删除pos位置

 11、删除pos之后位置

 四、完整代码


一、概念

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

二、分类

 实际中链表的结构非常多样,以下情况组合起来就有8种链表结构: 

1. 单向或者双向

2. 带头或者不带头  

3. 循环或者非循环  

虽然有这么多的链表的结构,但是我们实际中最常用还是两种结构:

这里我们只介绍无头单向非循环链表: 

无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构。

三、接口实现

1.定义结构

//定义一下结构
typedef int SLTDataType;
typedef struct SListNode
{SLTDataType data;struct SListNode* next;
}SLTNode;

这里为了方便我们测试代码的正确性,我们顺手实现一个Print,以方便我们检查

void SLTPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur){printf("%d->", cur->data);cur = cur->next;//cur向后走}printf("NULL\n");
}

 2、申请节点

SLTNode* BuySListNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;return newnode;
}

3、尾插 

下面这样写对吗?

//尾插
void SLTPushBack(SLTNode* phead, SLTDataType x)
{SLTNode* newnode = BuySListNode(x);SLTNode* tail = phead;while (tail != NULL){tail = tail->next;}tail = newnode;
}

改正:

//尾插
void SLTPushBack(SLTNode* phead, SLTDataType x)
{SLTNode* newnode = BuySListNode(x);SLTNode* tail = phead;while (tail->next!= NULL){tail = tail->next;}tail->next = newnode;
}

那么这样写就写完了吗?那如果我的链表是个空的呢?

//这样写对吗???
//尾插
void SLTPushBack(SLTNode* phead, SLTDataType x)
{SLTNode* newnode = BuySListNode(x);if (phead = NULL){phead = newnode;}else{SLTNode* tail = phead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}}

 

 从结果来看好像并没有插进去啊,这是怎么回事呢?

 我们要改变plist就要传plist的地址过去,所以代码应该这么写:

//正确代码
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = BuySListNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}}

4、头插

//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = BuySListNode(x);newnode->next = *pphead;*pphead = newnode;}

 5、尾删

下面这样写对吗? 

void SLTPopBack(SLTNode** pphead)
{//1、空assert(*pphead);//2、一个节点//3、一个以上节点if ((*pphead)->next = NULL){free(*pphead);*pphead = NULL;}else{SLTNode* tail = *pphead;while (tail->next){tail = tail->next;}free(tail);tail = NULL;}
}

正确代码:

//尾删
void SLTPopBack(SLTNode** pphead)
{//1、空assert(*pphead);//2、一个节点//3、一个以上节点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{//方法一:SLTNode* tailPrev = NULL;SLTNode* tail = *pphead;while (tail->next){tailPrev = tail;tail = tail->next;}free(tail);tailPrev->next = NULL;//方法二://SLTNode* tail = *pphead;//while (tail->next->next)//{//	tail = tail->next;//}//free(tail->next);//tail->next = NULL;}
}

6、头删

 

//头删
void SLTPopFront(SLTNode** pphead)
{//空assert(*pphead);//非空SLTNode* newhead = (*pphead)->next;free(*pphead);*pphead = newhead;
}

7.查找,也可以充当修改

//查找,也可以充当修改
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* cur = phead;while (cur){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}

8、在pos之前插入x 

 

//在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pos);if (pos == *pphead){SLTPushFront(pphead, x);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}SLTNode* newnode = BuySListNode(x);prev->next = newnode;newnode->next = pos;}
}

9、在pos之后插入x 

//在pos之后插入x
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = BuySListNode(x);newnode->next = pos->next;pos->next = newnode;
}

注意: 

 10、删除pos位置

//删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pos);if (pos == *pphead){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);}
}

 11、删除pos之后位置

//删除pos的后一个位置
void SLTEraseAfter(SLTNode* pos)
{assert(pos);//检查pos是不是尾节点assert(pos->next);SLTNode* posNext = pos->next;pos->next = posNext->next;fress(posNext);posNext = NULL;
}

 四、完整代码

//SList.h#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>//无头+单向+非循环链表//定义一下结构
typedef int SLTDataType;
typedef struct SListNode
{SLTDataType data;struct SListNode* next;
}SLTNode;
//打印
void SLTPrint(SLTNode* phead);//申请节点
SLTNode* BuySListNode(SLTDataType x);//头插
void SLTPushFront(SLTNode** phead, SLTDataType x);//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);//头删
void SLTPopFront(SLTNode** pphead);//尾删
void SLTPopBack(SLTNode** pphead);//查找,也可以充当修改
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);//在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);//在pos之后插入x
void SLTInsertAfter(SLTNode* pos, SLTDataType x);//删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos);//删除pos的后一个位置
void SLTEraseAfter(SLTNode* pos);
//SList.c#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
//打印
void SLTPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur){printf("%d->", cur->data);cur = cur->next;//cur向后走}printf("NULL\n");
}//申请节点
SLTNode* BuySListNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;return newnode;
}//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySListNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}}//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySListNode(x);newnode->next = *pphead;*pphead = newnode;}//尾删
void SLTPopBack(SLTNode** pphead)
{assert(pphead);//1、空assert(*pphead);//2、一个节点//3、一个以上节点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLTNode* tailPrev = NULL;SLTNode* tail = *pphead;while (tail->next){tailPrev = tail;tail = tail->next;}free(tail);tailPrev->next = NULL;//SLTNode* tail = *pphead;//while (tail->next->next)//{//	tail = tail->next;//}//free(tail->next);//tail->next = NULL;}
}//头删
void SLTPopFront(SLTNode** pphead)
{assert(pphead);//空assert(*pphead);//非空SLTNode* newhead = (*pphead)->next;free(*pphead);*pphead = newhead;
}//查找,也可以充当修改
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* cur = phead;while (cur){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}//在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead);assert(pos);if (pos == *pphead){SLTPushFront(pphead, x);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}SLTNode* newnode = BuySListNode(x);prev->next = newnode;newnode->next = pos;}
}//在pos之后插入x
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = BuySListNode(x);newnode->next = pos->next;pos->next = newnode;
}//删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead);assert(pos);if (pos == *pphead){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);}
}//删除pos的后一个位置
void SLTEraseAfter(SLTNode* pos)
{assert(pos);//检查pos是不是尾节点assert(pos->next);SLTNode* posNext = pos->next;pos->next = posNext->next;free(posNext);posNext = NULL;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/486095.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSU课内课程资料【github仓库】

里面是我当时的PPT&#xff0c;作业答案&#xff0c;实验&#xff0c;还有一些笔记啥的&#xff0c;里面有的是他人的笔记和报告&#xff0c;等之后闲下来的话&#xff0c;我会删掉这部分&#xff0c;起码人家的笔记也是有隐私权的。关于实验&#xff0c;大多也是很普通&#x…

深算院崖山发布核心平替战略 加速金融数智化跃迁

2024年11月14日&#xff0c;由深圳计算科学研究院&#xff08;简称&#xff1a;深算院&#xff09;主办、深圳崖山科技有限公司&#xff08;简称&#xff1a;崖山科技&#xff09;和赛迪网承办的“2024国产数据库创新生态大会”在深圳成功举办。会上&#xff0c;崖山数据库重磅…

【Web】2023安洵杯第六届网络安全挑战赛 WP

目录 Whats my name easy_unserialize signal Swagger docs 赛题链接&#xff1a;GitHub - D0g3-Lab/i-SOON_CTF_2023: 2023 第六届安洵杯 题目环境/源码 Whats my name 第一段正则用于匹配以 include 结尾的字符串&#xff0c;并且在 include 之前&#xff0c;可以有任…

从零开始的vscode配置及安装rust教程

配置vscode的rust环境 下载安装vscodemac 环境 1. 下载安装rust2. 配置 mac vscode环境3. 创建一个测试项目 windows 环境 1. 安装c运行环境2. 安装配置rustup3. 配置windows vscode环境4. 创建一个测试项目 下载安装vscode 1.官网应用程序下载 vscode&#xff1a;https://…

小程序 - 美食列表

小程序交互练习 - 美食列表小程序开发笔记 目录 美食列表 功能描述 准备工作 创建项目 配置页面 配置导航栏 启动本地服务器 页面初始数据 设置获取美食数据 设置onload函数 设置项目配置 页面渲染 页面样式 处理电话格式 创建处理电话格式脚本 页面引入脚本 …

ip所属地址是什么意思?怎么改ip地址归属地

在数字化时代&#xff0c;IP地址作为网络设备的唯一标识符&#xff0c;不仅关乎设备间的通信&#xff0c;还涉及到用户的网络身份与位置信息。IP所属地址&#xff0c;即IP地址的归属地&#xff0c;通常反映了设备连接互联网时的地理位置。本文将深入解析IP所属地址的含义&#…

【opencv入门教程】12. 矩阵初始化

文章选自&#xff1a; 一、 数据类型 建立矩阵必须要指定矩阵存储的数据类型&#xff0c;图像处理中常用的几种数据类型如下&#xff1a;包括数据位深度8位、32位&#xff0c;数据类型U:uchar、F:float型以及通道数C1&#xff1a;单通道、C3&#xff1a;三通道、C4&#xff…

Hadoop生态圈框架部署 伪集群版(七)- Hive部署

文章目录 前言一、Hive部署&#xff08;手动部署&#xff09;1. 下载Hive2. 解压Hive安装包2.1 解压2.2 重命名2.3 解决冲突2.3.1 解决guava冲突2.3.2 解决SLF4J冲突 3. 配置Hive3.1 配置Hive环境变量3.2 修改 hive-site.xml 配置文件3.3 配置MySQL驱动包 4. 初始化MySQL上的存…

Hadoop生态圈框架部署 伪集群版(五)- HBase伪分布式部署

文章目录 前言一、Hbase伪分布式部署&#xff08;手动部署&#xff09;1. 下载Hbase2. 上传安装包3. 解压HBase安装包4. 配置HBase配置文件4.1 修改hbase-env.sh配置文件4.2 修改hbase-site.xml配置文件4.3 修改regionservers配置文件4.4 删除hbase中slf4j-reload4j-1.7.33.jar…

家政项目小程序+ssm

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了微信小程序家政项目小程序的开发全过程。通过分析微信小程序家政项目小程序管理的不足&#xff0c;创建了一个计算机管理微信小程序家政项目小程序的方案。文章…

qt QNetworkAccessManager详解

1、概述 QNetworkAccessManager是QtNetwork模块中的一个核心类&#xff0c;它允许应用程序发送网络请求并接收响应。该类是网络通信的基石&#xff0c;提供了一种方便的方式来处理常见的网络协议&#xff0c;如HTTP、HTTPS等。QNetworkAccessManager对象持有其发送的请求的通用…

五、docker的网络模式

五、docker的网络模式 5.1 Docker的四种网络模式 当你安装docker时&#xff0c;它会自动创建三个网络&#xff0c;可使用如下命令查看&#xff1a; [rootlocalhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 7390284b02d6 bridge bridge lo…

T113-S3 Tina 串口切换

前面介绍了如何在 Tina 中添加新的板子及切换存储类型&#xff0c;本节介绍如何修改板子串口配置。 1、修改调试串口 Tina 调试串口 配置在 device/config/chips/t113/configs/evbemmc/sys_config.fex 文件中&#xff0c;可以修改 uart_para 变量来指定调试串口。 ;--------…

【计算机网络】 —— 数据链路层(壹)

文章目录 前言 一、概述 1. 基本概念 2. 数据链路层的三个主要问题 二、封装成帧 1. 概念 2. 帧头、帧尾的作用 3. 透明传输 4. 提高效率 三、差错检测 1. 概念 2. 奇偶校验 3. 循环冗余校验CRC 1. 步骤 2. 生成多项式 3. 例题 4. 总结 四、可靠传输 1. 基本…

M005 PHP+MYSQL+web编程课程网站的设计与实现 源码 配置 文档

web编程课程网站 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 随着互联网的飞速发展&#xff0c;各行各业的信息化进程逐步加快。商业信息化、政务信息化、教育信息、服务信息化等等已遍布全国各地。信息化的服务平台能更加高效的为用户提供各种服务…

深入理解 PyTorch 自动微分机制与自定义 torch.autograd.Function

文章目录 前言一、pytorch使用现有的自动微分机制二、torch.autograd.Function中的ctx解读1、forward 方法中的 ctx2、backward 方法中的 ctx3、小结 三、pytorch自定义自动微分函数&#xff08;torch.autograd.Function&#xff09;1、torch.autograd.Function计算前向与后向传…

python怎么打印心形

首先按WinR调出运行界面&#xff0c;输入cmd打开命令行。 接着输入python命令进入python环境。 然后复制下面的代码进行粘贴&#xff1a; print(\n.join([.join([(baidu[(x-y) % len(baidu)] if ((x*0.05)**2(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3 < 0else ) for x in r…

LabVIEW-简单串口助手

LabVIEW-简单串口助手 串口函数VISA配置串口VISA写入函数VISA读取函数VISA资源名称按名称解除捆绑 函数存放位置思维导图主体界面为以下 串口函数 VISA配置串口 VISA写入函数 VISA读取函数 VISA资源名称 按名称解除捆绑 函数存放位置 思维导图 主体界面为以下 从创建好的“枚举…

使用数据层进行数据生命周期管理

作者&#xff1a;来自 Elastic Stef Nestor Elasticsearch 7.10 使配置数据生命周期变得不再那么复杂。在这篇博文中&#xff0c;我将介绍一些变化、如何使用它们以及一些最佳实践。 数据生命周期可以包含很多阶段&#xff0c;因此我们将涉及&#xff1a; 将集群划分为层&…

IPv4路由典型配置-BGP

一、组网说明 三台设备运行BGP协议&#xff0c;SW 1属于AS 100&#xff0c;SW 2和SW 3属于AS 200。配置BGP协议&#xff0c;以保证三台设备之间可以互通。 二、组网图 三、配置步骤 SW 1的配置 #BGP部分 switch(config)#router bgp 100switch(config-router-bgp)#bgp …