暴力数据结构之单链表专题

1. 单链表的初始化

首先定义节点的结构,然后动态内存申请一部分空间,每一个节点都有一个值以及指向下一个节点的指针,称作值域和指针域。 

//定义节点的结构
//数据 + 指向下一个节点的指针typedef int SLTDataType;typedef struct SListNode
{SLTDataType data;struct	SListNode* next;
}SLTNode;

初始化需要为链表节点动态申请一块空间,然后对值域和指针域初始化。

//初始化函数
SLTNode* SLTBuyNode(SLTDataType x) 
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;return newnode;
}

2. 单链表的相关函数

2.1 头插和头删

首先断言头结点不能为空,然后直接从表头插入节点。

//头插函数
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);//newnode *pphead//将链表依次后移,从头插入newnode->next = *pphead;*pphead = newnode;
}

断言判断头结点及其地址都不为空,然后将原头结点的下一个节点保存起来,释放原来的头结点,则原头结点的下一个节点成为新的头结点。

//头删函数
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}
2.2 尾插和尾删

断言头结点不能为空,同样插入,但是要判断原链表是否为空链表,是空链表则直接插入,反之遍历链表找到尾节点再插入。

//尾插函数
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);//*pphead 就是指向第一个节点的指针//空链表和非空链表SLTNode* newnode = SLTBuyNode(x);if (*pphead == NULL){*pphead = newnode;}else{//找尾SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}//ptail指向的是尾节点ptail->next = newnode;}
}

断言判断头结点及其地址均不为空,同样的原链表如果只有一个节点则直接释放,反之找到尾节点后释放尾节点。

//尾删函数
void SLTPopBack(SLTNode** pphead)
{//链表不能为空assert(pphead && *pphead);//考虑链表只有一个节点的情况if ((*pphead)->next == NULL){free(pphead);pphead = NULL;}else{SLTNode* prev = *pphead;SLTNode* ptail = *pphead;while (ptail->next){prev = ptail;ptail = ptail->next;}free(ptail);ptail = NULL;prev->next = NULL;}
}
2.3 在指定位置的前后插入数据

断言待插入节点位置、头结点及其地址均不为空,如果pos为头结点就直接头插,反之遍历链表找到pos的上一个节点,然后在二者中间插入。

//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pos);assert(pphead && *pphead);SLTNode* newnode = SLTBuyNode(x);//判断是否为头节点if (pos == *pphead){SLTPushFront(pphead, x);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}newnode->next = pos;prev->next = newnode;}
}

断言待插入节点位置、头结点及其地址均不为空,找到pos的上一个节点,然后在二者中间插入。 

//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);newnode->next = pos->next;pos->next = newnode;
}
2.4 删除当前节点或后面节点

 断言待插入节点位置、头结点及其地址均不为空,如果pos为头结点直接头删,反之遍历链表找     到pos节点后保存相邻节点,释放pos节点,将相邻节点连接起来形成新链表。

//删除pos当前指向的节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && *pphead);assert(pos);//pos是头结点/不是头结点if (pos == *pphead){//头删SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}

断言待插入节点位置及其下一个节点均不为空,保存pos下一个节点即待删除节点,释放pos节点,将相邻节点连接起来形成新链表。

//删除pos之后的节点
void SLTErase(SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;pos = del->next;free(del);del = NULL;
}
2.5 销毁和查找 

遍历链表找符合的节点,然后直接返回该节点。

//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* pcur = phead;while (pcur != NULL){if (pcur->data == x){return pcur;}pcur = pcur->next;}//pcur == NULL;return NULL;
}

由于前面有动态内存申请,所以要进行释放free掉,就有了销毁函数。 

//销毁链表
void SLTDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

3. 代码展示(可自行复制调试)

3.1 test.c
#include"SList.h"void SListTest01()
{//链表是由一个一个的节点组成//创建几个节点SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));node1->data = 1;SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));node2->data = 2;SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));node3->data = 3;SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));node4->data = 4;//将四个节点连接起来node1->next = node2;node2->next = node3;node3->next = node4;node4->next = NULL;//调用链表的打印SLTNode* plist = node1;SLTPrint(plist);
}void SListTest02()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);//SLTPushBack(NULL, 5);////测试头插//SLTPushFront(&plist, 6);//SLTPrint(plist);//SLTPushFront(&plist, 7);//SLTPrint(plist);//SLTPushFront(&plist, 8);//SLTPrint(plist);//测试尾删SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);}int main()
{//SListTest01();SListTest02();return 0;
}
3.2 SList.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#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* SLTBuyNode(SLTDataType x);//头插函数
void SLTPushFront(SLTNode** pphead, SLTDataType x);//尾插函数
void SLTPushBack(SLTNode** pphead, SLTDataType x);//头删函数
void SLTPopFront(SLTNode** pphead);//尾删函数
void SLTPopBack(SLTNode** pphead);//删除pos之后的节点
void SLTErase(SLTNode* pos);//销毁链表
void SLTDesTroy(SLTNode** pphead);
3.3 SList.c 
#include"SList.h"//打印函数
void SLTPrint(SLTNode* phead)
{SLTNode* pcur = phead;while (pcur){printf("->%d", pcur->data);pcur = pcur->next;}printf("->NULL\n");
}//初始化函数
SLTNode* SLTBuyNode(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 SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);//newnode *pphead//将链表依次后移,从头插入newnode->next = *pphead;*pphead = newnode;
}//尾插函数
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);//*pphead 就是指向第一个节点的指针//空链表和非空链表SLTNode* newnode = SLTBuyNode(x);if (*pphead == NULL){*pphead = newnode;}else{//找尾SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}//ptail指向的是尾节点ptail->next = newnode;}
}//尾删函数
void SLTPopBack(SLTNode** pphead)
{//链表不能为空assert(pphead && *pphead);//考虑链表只有一个节点的情况if ((*pphead)->next == NULL){free(pphead);pphead = NULL;}else{SLTNode* prev = *pphead;SLTNode* ptail = *pphead;while (ptail->next){prev = ptail;ptail = ptail->next;}free(ptail);ptail = NULL;prev->next = NULL;}
}//头删函数
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* pcur = phead;while (pcur != NULL){if (pcur->data == x){return pcur;}pcur = pcur->next;}//pcur == NULL;return NULL;
}//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pos);assert(pphead && *pphead);SLTNode* newnode = SLTBuyNode(x);//判断是否为头节点if (pos == *pphead){SLTPushFront(pphead, x);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}newnode->next = pos;prev->next = newnode;}
}//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);newnode->next = pos->next;pos->next = newnode;
}//删除pos当前指向的节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && *pphead);assert(pos);//pos是头结点/不是头结点if (pos == *pphead){//头删SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}//删除pos之后的节点
void SLTErase(SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;pos = del->next;free(del);del = NULL;
}//销毁链表
void SLTDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

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

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

相关文章

40. UE5 RPG给火球术增加特效和音效

前面&#xff0c;我们将火球的转向和人物的转向问题解决了&#xff0c;火球术可以按照我们的想法朝向目标发射。现在&#xff0c;我们解决接下来的问题&#xff0c;在角色释放火球术时&#xff0c;会产生释放音效&#xff0c;火球也会产生对应的音效&#xff0c;在火球击中目标…

【深度学习】DDoS-Detection-Challenge aitrans2024 入侵检测,基于机器学习(深度学习)判断网络入侵

当了次教练&#xff0c;做了个比赛的Stage1&#xff0c;https://github.com/AItransCompetition/DDoS-Detection-Challenge&#xff0c;得了100分。 一些记录&#xff1a; 1、提交的flowid不能重复&#xff0c;提交的是非入侵的数量和数据flowid,看check.cpp可知。 2、Stage…

大数据入门——概念、工具等

目录 一、基本概念 1.大数据技术 2.大数据特点 3.常见概念 4.数据分析师、数据开发工程师 二、相关工具 三、应用场景 四、大数据业务流程及组织结构 一、基本概念 1.大数据技术 主要解决海量数据的采集、存储和分析计算问题 2.大数据特点 大量、高速、多样、价值、…

【六十】【算法分析与设计】用一道题目解决dfs深度优先遍历,dfs中节点信息,dfs递归函数模板进入前维护出去前回溯,唯一解的剪枝飞升返回值true

路径之谜 题目描述 小明冒充X星球的骑士,进入了一个奇怪的城堡。 城堡里边什么都没有,只有方形石头铺成的地面。 假设城堡地面是nn个方格。如下图所示。 按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着音走,也不能跳跃。每走到一个新方格,就要向正北 方和正西…

ESP32开发

目录 1、简介 1.1 种类 1.2 特点 1.3 管脚功能 1.4 接线方式 1.5 工作模式 2、基础AT指令介绍 2.1 AT指令类型 2.2 基础指令及其描述 2.3 使用AT指令需要注意的事 3、AT指令分类和提示信息 3.1 选择是否保存到Flash的区别 3.2 提示信息 3.3 其他会保存到Flash的A…

基础SQL DQL语句

基础查询 select * from 表名; 查询所有字段 create table emp(id int comment 编号,workno varchar(10) comment 工号,name varchar(10) comment 姓名,gender char(1) comment 性别,age tinyint unsigned comment 年龄,idcard char(18) comment 身份证号,worka…

排序算法:顺序查找

简介 顺序查找&#xff08;也称为线性查找&#xff09;是一种简单直观的搜索算法。按照顺序逐个比较列表或数组中的元素&#xff0c;直到找到目标元素或搜索完整个列表。 应用场景 数据集比较小&#xff0c;无需使用复杂的算法。数据集没有排序&#xff0c;不能使用二分查找…

书生·浦语大模型实战营(第二期):OpenCompass司南大模型评测实战

目录 大语言模型评测中的挑战如何评测大模型模型客观题&主观题提示词工程长文本评测OpenCompass评测流水线CompassHub&#xff1a;高质量评测基准社区 OpenCompass介绍作业&#xff1a;使用OpenCompass评测internlm2-chat-1_8b模型在C-Eval数据集上的性能准备阶段环境配置数…

html--canvas粒子球

<!doctype html> <html> <head> <meta charset"utf-8"> <title>canvas粒子球</title><link type"text/css" href"css/style.css" rel"stylesheet" /></head> <body><script…

element plus:tree拖动节点交换位置和改变层级

图层list里有各种组件&#xff0c;用element plus的tree来渲染&#xff0c;可以把图片等组件到面板里&#xff0c;面板是容器&#xff0c;非容器组件&#xff0c;比如图片、文本等&#xff0c;就不能让其他组件拖进来。 主要在于allow-drop属性的回调函数编写&#xff0c;要理清…

解决JDK7调用https报:java.net.SocketException: Connection reset错误

原因分析&#xff1a; 大多数现代的 HTTPS 连接将使用 TLS 1.2协议 或 TLS 1.3协议&#xff0c;具体取决于服务器和客户端支持的版本以及其之间的协商&#xff0c;而JDK7及以下版本默认使用是TLS v1协议&#xff0c;所以在调用HTTPS接口时&#xff0c;会出现java.net.SocketExc…

ElasticSearch笔记一

随着这个业务的发展&#xff0c;我们的数据量越来越庞大。那么传统的这种mysql的数据库就渐渐的难以满足我们复杂的业务需求了。 所以在微服务架构下一般都会用到一种分布式搜索的技术。那么今天呢我们就会带着大家去学习分布搜索当中最流行的一种ElasticSearch&#xff0c;Ela…

基于harris角点和RANSAC算法的图像拼接matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ....................................................................... I1_harris fu…

【洛谷 P8605】[蓝桥杯 2013 国 AC] 网络寻路 题解(图论+无向图+组合数学)

[蓝桥杯 2013 国 AC] 网络寻路 题目描述 X X X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包&#xff0c;为了安全起见&#xff0c;必须恰好被转发两次到达目的地。该包可能在任意一个节点产生&#xff0c;我们需要知道该网络中一共有多少种…

django结合smartchart实现系统的数据看板页面

1、安装smartchart pip3 install smartchart 2、在你的setting.py的INSTALL_APPS中加入’smart_chart.echart 3、MIDDLEWARE 中注释掉XFrameOptionsMiddleware 4、检查确保在Templates的设定处有DIRS的相关设定 TEMPLATES = [{BACKEND: django.template.backends.django.…

python基础知识三(运算符、while循环、for循环)

目录 运算符&#xff1a; 算术运算符&#xff1a; 比较运算符&#xff1a; 赋值运算符&#xff1a; 逻辑运算符&#xff1a; 位运算符&#xff1a; 成员运算符&#xff1a; while循环&#xff1a; 1. while循环的语法&#xff1a; 2. while循环的执行过程&#xff1a…

Docker常用操作记录

docker 常用命令 // 查看docker系统信息 docker info // 显示 Docker 版本信息 docker version docker ps // 查看正在运行的容器 docker ps -a // 查看所有已经创建的容器 docker images // 列出镜像列表 docker container ls // 效果同ps命令(加-a效果同)// 详细信息 docke…

232 基于matlab的MIMO雷达模型下一种子空间谱估计方法

基于matlab的MIMO雷达模型下一种子空间谱估计方法&#xff0c;采用过估计的方法&#xff0c;避免了信源数估计的问题&#xff0c;对数据协方差矩阵进行变换&#xff0c;构造信号子空间投影矩阵和噪声子空间投影矩阵&#xff0c;不需要像经典的MUSIC一样对其进行特征分解&#x…

【笔试强训】数字统计|两个数组的交集|点击消除

一、数字统计 链接&#xff1a;[NOIP2010]数字统计_牛客题霸_牛客网 (nowcoder.com) 思路&#xff1a; 枚举数字拆分&#xff08;模10 除10&#xff09; &#x1f4a1; 当前数据范围为10^4可以用int类型解决&#xff0c;如果到了10^9就需要用long类型 代码实现&#xff1a; i…

实验七 智能手机互联网程序设计(微信程序方向)实验报告

请编写一个用户登录界面&#xff0c;提示输入账号和密码进行登录&#xff0c;要求在输入后登陆框显示为绿色&#xff1b; 二、实验步骤与结果&#xff08;给出对应的代码或运行结果截图&#xff09; index.wxml <view class"content"> <view class"a…