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

【数据结构】_不带头非循环单向链表

目录

1. 链表的概念及结构

2. 链表的分类

3. 单链表的实现

3.1 SList.h头文件

3.2 SList.c源文件

3.3 Test_SList.c测试文件


关于线性表,已介绍顺序表,详见下文:

【数据结构】_顺序表-CSDN博客

本文介绍链表;

基于顺序表的特点,思考改善方案:

按需申请释放空间,不再将数据存储于连续的一整块空间中,而是需要一个数据开辟一个小空间。为了方便访问数据,首先创建一个头指针(头结点)指向存放第一个数据的内存位置处,而在该位置处,除了存储该数据本身,再分配一块空间用于存放下一个数据的地址,直至某位置存放的下一个位置的指针为空则数据截止。

同时,这种存储方式也有效地提高了插入删除数据时的效率,无需再大量挪动数据。

这种数据结构就称为链表。

1. 链表的概念及结构

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

链表在逻辑上是连续的,在物理上不是连续的

2. 链表的分类

单向和双向:

带头和不带头:

循环和非循环:

最常用的链表结构是:无头单向非循环链表 和 带头双向循环链表:

3. 单链表的实现

3.1 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);
void SLTPushBack(SLTNode** pphead, SLTDataType x);
void SLTPushFront(SLTNode** pphead, SLTDataType x);
void SLTPopBack(SLTNode** pphead);
void SLTPopFront(SLTNode** pphead);
SLTNode* SLTCreatNode(SLTDataType x);
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
// 在指定位置前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
// 在指定位置后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);
// 删除pos结点
void SLTErase(SLTNode** pphead, SLTNode* pos);
// 删除pos后的结点
void SLTEraseAfter(SLTNode* pos);
// 销毁
void SLTDestory(SLTNode** pphead);

3.2 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* SLTCreatNode(SLTDataType x) {SLTNode* newNode = (SLTNode*)malloc(sizeof(SLTNode));if (newNode == NULL) {perror("malloc fail\n");exit(1);}newNode->data = x;newNode->next = NULL;return newNode;
}
void SLTPushBack(SLTNode** pphead, SLTDataType x) {assert(pphead);SLTNode* newNode = SLTCreatNode(x);// 空链表if (*pphead == NULL) {*pphead = newNode;}else {// 非空链表SLTNode* curNode = *pphead;while (curNode->next) {curNode = curNode->next;}curNode->next = newNode;}
}
void SLTPushFront(SLTNode** pphead, SLTDataType x) {assert(pphead);SLTNode* newNode = SLTCreatNode(x);newNode->next = *pphead;// 令新结点为链表的头结点*pphead = newNode;
}
void SLTPopBack(SLTNode** pphead) {assert(pphead && *pphead);// 链表只有一个结点if ((*pphead)->next == NULL) {free(*pphead);*pphead = NULL;}// 链表有多个结点else {SLTNode* tailPrevNode = *pphead;SLTNode* tailNode = *pphead;while (tailNode->next) {tailPrevNode = tailNode;tailNode = tailNode->next;}free(tailNode);tailNode = NULL;tailPrevNode->next = NULL;}
}
void SLTPopFront(SLTNode** pphead) {assert(pphead && *pphead);SLTNode* secNode = (*pphead)->next;free(*pphead);*pphead = secNode;
}
SLTNode* SLTFind(SLTNode* phead, SLTDataType x) {SLTNode* curNode = phead;while (curNode) {if (curNode->data == x) {return curNode;}curNode = curNode->next;}return NULL;
}
// 在指定位置前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x) {assert(pphead && *pphead && pos);SLTNode* newNode = SLTCreatNode(x);if (pos == *pphead) {// 调用头插方法SLTPushFront(pphead, x);}else {SLTNode* posPrevNode = *pphead;while (posPrevNode->next != pos) {posPrevNode = posPrevNode->next;}posPrevNode->next = newNode;newNode->next = pos;}
}
// 在指定位置后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x) {assert(pos);SLTNode* newNode = SLTCreatNode(x);SLTNode* posAfterNode = pos->next;pos->next = newNode;newNode->next = posAfterNode;
}
// 删除pos结点
void SLTErase(SLTNode** pphead, SLTNode* pos) {assert(pphead && *pphead && pos);if (*pphead == pos) {// 调用头删方法SLTPopFront(pphead);}else {SLTNode* posPrevNode = *pphead;while (posPrevNode->next != pos) {posPrevNode = posPrevNode->next;}posPrevNode->next = pos->next;free(pos);pos = NULL;}
}
// 删除pos后的结点
void SLTEraseAfter(SLTNode* pos) {assert(pos && pos->next);SLTNode* posAfterNode = pos->next;pos->next = posAfterNode->next;free(posAfterNode);posAfterNode = NULL;
}
// 销毁
void SLTDestory(SLTNode** pphead) {assert(pphead && *pphead);SLTNode* curNode = *pphead;while (curNode) {SLTNode* curNextNode= curNode->next;free(curNode);curNode = NULL;}*pphead = NULL;
}

3.3 Test_SList.c测试文件

#include"SList.h"
void Test11() {SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);SLTDestory(&plist);SLTPrint(plist);
}
void Test10() {SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);SLTNode* aimNode1 = SLTFind(plist, 3);SLTEraseAfter(aimNode1);SLTPrint(plist);SLTNode* aimNode2 = SLTFind(plist, 1);SLTEraseAfter(aimNode2);SLTPrint(plist);
}
void Test9() {SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);SLTNode* aimNode1 = SLTFind(plist, 3);SLTErase(&plist, aimNode1);SLTPrint(plist);SLTNode* aimNode2 = SLTFind(plist, 1);SLTErase(&plist, aimNode2);SLTPrint(plist);
}
void Test8() {SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);SLTNode* aimNode1 = SLTFind(plist, 3);SLTInsertAfter(aimNode1, 85);SLTPrint(plist);SLTNode* aimNode2 = SLTFind(plist, 1);SLTInsertAfter(aimNode2, 97);SLTPrint(plist);
}
void Test7(){SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);SLTNode* aimNode1 = SLTFind(plist, 3);SLTInsert(&plist, aimNode1, 85);SLTPrint(plist);SLTNode* aimNode2 = SLTFind(plist, 1);SLTInsert(&plist, aimNode2, 97);SLTPrint(plist);
}
void Test6() {SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);// SLTNode* aimNode = SLTFind(plist, 3);SLTNode* aimNode = SLTFind(plist, 6);if (aimNode == NULL)printf("Find nothing\n");elseprintf("Find successfully\n");
}
void Test5() {SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);
}
void Test4() {SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);
}
void Test3() {SLTNode* plist = NULL;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist);
}
void Test2() {SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);
}void Test1() {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);
}
int main() {//Test1();//Test2();//Test3();//Test4();//Test5();//Test6();//Test7();//Test8();//Test9();//Test10();Test11();return 0;
}

相关文章:

【数据结构】_不带头非循环单向链表

目录 1. 链表的概念及结构 2. 链表的分类 3. 单链表的实现 3.1 SList.h头文件 3.2 SList.c源文件 3.3 Test_SList.c测试文件 关于线性表&#xff0c;已介绍顺序表&#xff0c;详见下文&#xff1a; 【数据结构】_顺序表-CSDN博客 本文介绍链表&#xff1b; 基于顺序表…...

golang 使用双向链表作为container/heap的载体

MyHeap&#xff1a;container/heap的数据载体&#xff0c;需要实现以下方法&#xff1a; Len&#xff1a;堆中数据个数 Less&#xff1a;第i个元素 是否必 第j个元素 值小 Swap&#xff1a;交换第i个元素和 第j个元素 Push&#xff1a;向堆中追加元素 Pop&#xff1a;从堆…...

C#集合操作优化:高效实现批量添加与删除

在C#中&#xff0c;对集合进行批量操作&#xff08;如批量添加或删除元素&#xff09;通常涉及使用集合类型提供的方法和特性&#xff0c;以及可能的循环或LINQ查询来高效地处理大量数据。以下是一些常见的方法和技巧&#xff1a; 批量添加元素 使用集合的AddRange方法&#x…...

142.WEB渗透测试-信息收集-小程序、app(13)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;141.WEB渗透测试-信息收集-小程序、app&#xff08;12&#xff09; 软件用法&#xff0c…...

24.日常算法

1. 数组中两元素的最大乘积 题目来源 给你一个整数数组 nums&#xff0c;请你选择数组的两个不同下标 i 和 j&#xff0c;使 (nums[i]-1)*(nums[j]-1) 取得最大值。请你计算并返回该式的最大值。 示例 1&#xff1a; 输入&#xff1a;nums [3,4,5,2] 输出&#xff1a;12 解释…...

分布式理解

分布式 如何理解分布式 狭义的分布是指&#xff0c;指多台PC在地理位置上分布在不同的地方。 分布式系统 分布式系**统&#xff1a;**多个能独立运行的计算机&#xff08;称为结点&#xff09;组成。各个结点利用计算机网络进行信息传递&#xff0c;从而实现共同的“目标或者任…...

wordpress调用指定ID页面的链接

在WordPress中&#xff0c;如果你想调用一个指定ID的页面链接&#xff0c;可以使用以下几种方法&#xff1a; 方法一&#xff1a;使用页面ID 你可以直接使用页面的ID来生成链接。例如&#xff0c;如果你想链接到ID为123的页面&#xff0c;可以使用以下代码&#xff1a; <…...

单值二叉树(C语言详解版)

一、摘要 今天要讲的是leetcode单值二叉树&#xff0c;这里用到的C语言&#xff0c;主要提供的是思路&#xff0c;大家看了我的思路之后可以点击链接自己试一下。 二、题目简介 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。 只有给定的树是单…...

python学opencv|读取图像(四十二)使用cv2.add()函数实现多图像叠加

【1】引言 前序学习过程中&#xff0c;掌握了灰度图像和彩色图像的掩模操作&#xff1a; python学opencv|读取图像&#xff08;九&#xff09;用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客 python学opencv|读取图像&#xff08;四十&#xff09;掩模&#xff1a;三…...

速通Docker === Docker Compose

目录 Docker Compose 简介 Docker Compose 常用命令 使用 Docker Compose 启动 WordPress 普通启动方式&#xff08;使用 Docker 命令&#xff09; 使用 Docker Compose 启动 Docker Compose 的特性 Docker Compose 简介 Docker Compose 是一个用于定义和运行多容器 Dock…...

LMI Gocator GO_SDK VS2019引用配置

LMI SDK在VS2019中的引用是真的坑爹,总结一下经验,希望后来的人能少走弯路.大致内容如下: &#xff08;1&#xff09; 环境变量 &#xff08;2&#xff09;C/C 附加包含目录 E:\GWQ\Gocator\GO_SDK\Gocator\GoSdk E:\GWQ\Gocator\GO_SDK\Platform\kApi &#xff08;3&#…...

技术之翼,创作之心

引言&#xff1a;初入编程的迷茫与追求 当我第一次接触到编程时&#xff0c;心中充满了既期待又迷茫的情感。那时&#xff0c;我还是一名刚刚踏入大学的学生&#xff0c;面对一门陌生而复杂的学科——计算机科学&#xff0c;我的内心充满了好奇与困惑。课堂上&#xff0c;老师…...

WebSocket异步导出

WebSocket异步导出 1、安装sockjs-client和stompjs2、连接后台3、vite.config.ts 配置反向代理4、导出并实时通信5、 封装WebSocket 文件注册登录(城通网盘) 1、安装sockjs-client和stompjs import SockJS from sockjs-client/dist/sockjs.min.js import Stomp from stompjs2、…...

OS2.【Linux】基本命令入门(1)

目录 1.操作系统是什么? 2.好操作系统的衡量标准 3.操作系统的核心工作 4.在计算机上所有行为都会被转换为硬件行为 5.文件 6.简单介绍一些基本命令 1.clear 2.pwd 3.ls 1.ls -l 2.隐藏文件的创建 3.ls -al 4.ls -ld 5.ls -F(注意是大写) 4.cd 1.cd .. "…...

【二叉树】4. 判断一颗二叉树是否是平衡二叉树。5. 对称二叉树。6. 二叉树的构建及遍历 7. 二叉树的分层遍历 。

判断一颗二叉树是否是平衡二叉树。OJ链接 可以在求树高度的过程中判断树是否平衡 对称二叉树。OJ链接 二叉树的构建及遍历。OJ链接 注意&#xff1a;public static int i最好把static去掉 否则当有多个测试用例时 i无法重新为0二叉树的分层遍历 。OJ链接 但此题要求返回List…...

OS Copilot功能测评:智能助手的炫彩魔法

简介&#xff1a; OS Copilot 是一款融合了人工智能技术的智能助手&#xff0c;专为Linux系统设计&#xff0c;旨在提升系统管理和运维效率。本文详细介绍了在阿里云ECS实例上安装和体验OS Copilot的过程&#xff0c;重点评测了其三个核心参数&#xff1a;-t&#xff08;模式…...

MFC结构体数据文件读写实例

程序功能将结构体内数组数据写入文件和读出 2Dlg.h中代码: typedef struct Student {int nNum[1000];float fScore;CString sss;}stu; class CMy2Dlg : public CDialog { // Construction public:CMy2Dlg(CWnd* pParent NULL); // standard constructorstu stu1; ... } 2Dl…...

音频 PCM 格式 - raw data

文章目录 raw 音频格式&#xff1a;PCM其他音频格式&#xff1a;mp31. 无损压缩音频&#xff08;类比 PNG 图像&#xff09;2. 有损压缩音频&#xff08;类比 JPEG 图像&#xff09; 试了一下科大讯飞的音频识别云 api&#xff0c;踩了点坑 与本文无关&#xff1a;讯飞的 api 使…...

关于deepin上运行Qt开发的程序

国产化替代是将来各单位的主流趋势&#xff0c;探索自行开发应用程序在国产操作系统上正常运行是将来的主要工作之一。本文浅尝gui程序在统信社区版——deepin上遇到的小问题。 使用Qt在deepin上做了一个类似gif的帧动画弹窗&#xff0c;在编译运行时&#xff0c;程序可以正常…...

css 如何将字体进行压扁,即水平缩放scaleX

1、下面是来自baidu ai的结果&#xff1a; 2、下面是测试结果&#xff1a; .font-yh {text-align: center;font-family: msyh;display: inline-block; /* 确保transform作用于元素本身 */transform: scaleX(1.5); /* 水平缩放 */ } font-face {font-family: msyh;font-style:…...

C++AVL树(二)详解

文章目录 AVL树旋转单旋右单旋左单旋 双旋左右双旋右左双旋 平衡因子的更新左右双旋右左双旋 判断是不是AVL树时间复杂度分析全部的代码 AVL树 旋转 单旋 单旋是纯粹的一边高 单旋平衡因子是同号 右单旋 a,b,c自身不能发生旋转 并且也不能不向上继续更新&#xff08;不能停…...

RocketMQ 的 Topic 和消息队列MessageQueue信息,是怎么分布到Broker的?怎么负载均衡到Broker的?

目录 1. Topic 和 MessageQueue 的基本概念 1.1 Topic 1.2 MessageQueue 2. Topic 和 MessageQueue 的分布 2.1 Topic 的创建 2.2 MessageQueue 分配到 Broker 2.3 分布规则 3. 负载均衡机制 3.1 Producer 的负载均衡 3.2 Consumer 的负载均衡 3.3 Broker 的负载均衡…...

无人机核心项目开发系列:从设计到实现的完整解析

无人机核心项目开发系列&#xff1a;从设计到实现的完整解析 01-面试大保健-核心项目-无人机-架构-硬件 1. 无人机项目概述 在这篇博客中&#xff0c;我们将回顾一个遥控四轴无人机的项目。这是一个面向儿童的玩具无人机&#xff0c;具备基础的飞行功能&#xff1a;上升、下…...

浅谈Redis

2007 年&#xff0c;一位程序员和朋友一起创建了一个网站。为了解决这个网站的负载问题&#xff0c;他自己定制了一个数据库。于2009 年开发&#xff0c;称之为Redis。这位意大利程序员是萨尔瓦托勒桑菲利波(Salvatore Sanfilippo)&#xff0c;他被称为Redis之父&#xff0c;更…...

Ceisum无人机巡检直播视频投射

接上次的视频投影&#xff0c;Leader告诉我这个视频投影要用在两个地方&#xff0c;一个是我原先写的轨迹回放那里&#xff0c;另一个在无人机起飞后的地图回显&#xff0c;要实时播放无人机拍摄的视频&#xff0c;还要能转镜头&#xff0c;让我把这个也接一下。 我的天&#x…...

【组件库】使用Vue2+AntV X6+ElementUI 实现拖拽配置自定义vue节点

先来看看实现效果&#xff1a; 【组件库】使用 AntV X6 ElementUI 实现拖拽配置自定义 Vue 节点 在现代前端开发中&#xff0c;流程图和可视化编辑器的需求日益增加。AntV X6 是一个强大的图形化框架&#xff0c;支持丰富的图形操作和自定义功能。结合 ElementUI&#xff0c;…...

Vue.js组件开发-如何实现全选反选

在 Vue.js 中实现全选和反选功能&#xff0c;可以通过结合v-model、计算属性和事件处理来完成。 实现思路 • 数据绑定&#xff1a;为每个复选框绑定一个选中状态。 • 全选控制&#xff1a;通过一个复选框控制所有复选框的选中状态。 • 反选控制&#xff1a;通过一个按钮或…...

2025.1.20——四、[强网杯 2019]Upload1 文件上传|反序列化

题目来源&#xff1a;buuctf [强网杯 2019]Upload 1 目录 一、打开靶机&#xff0c;查看信息 二、解题思路 step 1&#xff1a;登陆进去看情况 step 2&#xff1a;大佬来支援——问题在cookie step 3&#xff1a;测试两个思路 1.目录穿越 2.目录扫描 step 4&#xff…...

php代码审计2 piwigo CMS in_array()函数漏洞

php代码审计2 piwigo CMS in_array()函数漏洞 一、目的 本次学习目的是了解in_array()函数和对项目piwigo中关于in_array()函数存在漏洞的一个审计并利用漏洞获得管理员帐号。 二、in_array函数学习 in_array() 函数搜索数组中是否存在指定的值。 in_array($search,$array…...

docker搭建redis集群(三主三从)

本篇文章不包含理论解释&#xff0c;直接开始集群&#xff08;三主三从&#xff09;搭建 环境 centos7 docker 26.1.4 redis latest &#xff08;7.4.2&#xff09; 服务器搭建以及环境配置 请查看本系列前几篇博客 默认已搭建好三个虚拟机并安装配置好docker 相关博客&#xf…...