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

单链表的概念,结构和优缺点

1. 概念

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

2. 单链表的结构

单链表是由一系列节点组成的线性结构,每个结点包含两个域。:数据域和指针域。

数据域用来存储数据,指针域用来存储下一个结点的指针。单链表的头结点指向第一个结点,最后一个结点的指针域为空。

一个结点的结构:

逻辑结构:为了方便形象理解,想象出来的。

物理结构:实际内存中,真实的样子。

1.3 单链表的优缺点

优点:

1. 插入和删除操作效率高(只需修改指针的指向)

2. 空间利用率高(不需要预先分配空间)

3. 长度可变

缺点:

1. 随机访问效率低(只能挨个遍历)

2. 存储空间浪费(每个结点包含数据和指针)

3. 链接信息的丢失 (无法访问前一个节点)

2. 单链表的实现

单链表各接口函数

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDataType;//这样做的目的是为了增加代码的可读性和可维护性,以及提高代码的可移植性,
//因为如果将来需要更改 SLTDataType 的类型,只需要在 typedef 语句中修改一处即可,
// 如果我们在程序的其他地方需要修改 SLTDataType 的类型,
//只需在 typedef 语句中修改 int 为其他类型即可,不需要修改其他代码。
//typedef int SLTADataType;typedef struct SListNode //--single Linked List
{SLTDataType data;//成员变量struct SListNode* next;
}SLTNode;void SLTPrint(SLTNode* phead);
void SLPushFront(SLTNode** pphead, SLTDataType x);//头部插入
void SLPushBack(SLTNode** pphead, SLTDataType x);//尾部插入void SLPopFront(SLTNode** pphead);//头部删除
void SLPopBack(SLTNode** pphead);//尾部删除//单链表查找
SLTNode* STFind(SLTNode* phead, SLTDataType x);//单链表pos之前插入
void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//单链表pos之后插入
void SLInsertAfter(SLTNode* pos, SLTDataType x);
//单链表pos位置删除
void SLErase(SLTNode** pphead, SLTNode* pos);
//单链表pos之后删除
void SLEraseAfter(SLTNode* phead);

2.1 结点的定义

单链表的英文为:Single linked list --简写为SL

而顺序表的英文是:Sequence table -- 简写为Seq

结点的英文为:node

typedef int SLTDataType;
typedef struct SListNode //--single Linked List
{SLTDataType data;//成员变量struct SListNode* next;
}SLTNode;

2.2 链表的打印

//函数的作用是遍历单链表,并将每个节点的数据元素打印到屏幕上。
void SLTPrint(SLTNode* phead)//参数是一个指向 SLTNode 类型的指针 phead,表示单链表的头节点。
{SLTNode* cur = phead;//头结点存储的地址给cur指针。while (cur != NULL)//使用一个while循环对单链表进行遍历,循环条件为 cur 不为 NULL。{    		printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");
}

2.3 创建一个新节点

SLTNode* BuyLTNode(SLTDataType x)//表示要创建的节点的数据元素。
//函数的作用是创建一个新的单链表节点,并将其初始化为包含数据元素 x 的节点。
{ SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");return NULL;}newnode->data = x;newnode->next = NULL;return newnode;//返回的是一个结点的地址
}

2.4 单链表尾插

void SLPushBack(SLTNode** pphead, SLTDataType x)//尾插的本质是让上一个结点链接下一个结点
{SLTNode* newnode = BuyLTNode(x);// 1、空链表// 2、非空链表if (*pphead == NULL){*pphead = newnode;}else{SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}}

2.5 单链表头插

void SLPushFront(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = BuyLTNode(x);newnode->next = *pphead;*pphead = newnode;
}

2.6 单链表头删

void SPopFront(SLTNode** pphead)
{//没有节点//暴力检查assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//多个节点else{SLTNode* del = *pphead;//相当于一个标记,删掉的标记//写法一//*pphead = del->next;//写法二 *pphead = (*pphead)->next;free(del);}}

2.7 单链表尾删

void SLPopBack(SLTNode** pphead)
{//没有节点(空链表)//暴力检查assert(*pphead);//一个节点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//多个节点else{SLTNode* prev = NULL;SLTNode* tail = *pphead;//找尾//方法一/*while (tail->next){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;*///方法二SLTNode* tail = *pphead;while (tail->next->next){tail = tail->next;}free(tail->next);tail->next = NULL;}
}

2.8 单链表查找/修改某个值

SLTNode* STFind(SLTNode* phead, SLTDataType x)
{//assert(phead);SLTNode* cur = phead;while (cur){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}

2.9 单链表在pos之前插入

void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead);//&plistassert(pos);//assert(*pphead);//一个节点if (*pphead == NULL){SLPushFront(pphead, x);}else//多个节点{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}SLTNode* newnode = BuyLTNode(x);prev->next = newnode;newnode->next = pos;}
}

2.10 单链表在pos之后插入

void SLInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* newnode = BuyLTNode(x);newnode->next = pos->next;pos->next = newnode;
}

2.11 单链表删除pos的值

void SLErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead);assert(pos);if (pos == *pphead){SLPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next!=pos){prev = prev->next;}prev->next = pos->next;free(pos);}
}

2.12 单链表删除pos之后的值

void SLEraseAfter(SLTNode* pos)
{assert(pos);SLTNode* next= pos->next;pos->next = next->next;free(next);
}

相关文章:

单链表的概念,结构和优缺点

1. 概念 链表是一种物理存储结构上非连续&#xff0c;非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 2. 单链表的结构 单链表是由一系列节点组成的线性结构&#xff0c;每个结点包含两个域。&#xff1a;数据域和指针域。 数据域用来…...

SpringBoot+数据可视化的奶茶点单购物平台(程序+论文+讲解+安装+调试+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 本奶茶点单购物平台搭建在 Spring Boot 框架之上&#xff0c;充分利用其强大的依赖管理机…...

深入理解 Vue3 中 ref 与 reactive 的区别及应用

深入理解 Vue3 中 ref 与 reactive 的区别及应用 在 Vue3 的开发世界里&#xff0c;响应式编程是其核心特性之一&#xff0c;而ref与reactive作为实现响应式的关键 API&#xff0c;理解它们的区别和适用场景对于开发者来说至关重要。本文将带你深入剖析这两个 API&#xff0c;…...

TDengine 客户端连接工具 taos-Cli

简介工具获取运行命令行参数 基础参数高级参数 数据导出/导入 数据导出数据导入 执行 SQL 脚本使用小技巧 TAB 键自动补全设置字符列显示宽度其它 错误代码表 简介 TDengine 命令行工具&#xff08;以下简称 TDengine CLI&#xff09;是用户操作 TDengine 实例并与之交互最简…...

Linux(ubuntu)下载ollama速度慢解决办法

国内安装Ollama都很慢&#xff0c;因为一直卡在下载中&#xff0c;直接通过官网的链接地址下载方法&#xff1a; curl -fsSL https://ollama.com/install.sh | sh速度大概是10min下载1%&#xff0c;完全不能接受啊&#xff01; 其中很好的一个加速方式是通过使用github文件加速…...

Mac安装JD-GUI

Mac安装反编译工具步骤如下&#xff1a; 打开官网https://java-decompiler.github.io/ 选择下载mac的安装包解压下载好的压缩包&#xff0c;点击JD-GUI安装 有可能会遇到如下错误。请先检查是否安装JDK&#xff0c;通过java -version命令查看是否是1.8版本的jdk如果jdk没问题&…...

Jenkins 配置 Git Parameter 四

Jenkins 配置 Git Parameter 四 一、开启 项目参数设置 勾选 This project is parameterised 二、添加 Git Parameter 如果此处不显示 Git Parameter 说明 Jenkins 还没有安装 Git Parameter plugin 插件&#xff0c;请先安装插件 Jenkins 安装插件 三、设置基本参数 点击…...

【AI】Docker中快速部署Ollama并安装DeepSeek-R1模型: 一步步指南

【AI】Docker中快速部署Ollama并安装DeepSeek-R1模型: 一步步指南 一、前言 为了确保在 Docker 环境中顺利安装并高效运行 Ollama 以及 DeepSeek 离线模型&#xff0c;本文将详细介绍整个过程&#xff0c;涵盖从基础安装到优化配置等各个方面。通过对关键参数和配置的深入理解…...

Python 自然语言处理(NLP)和文本挖掘的常规操作过程

Python 自然语言处理&#xff08;NLP&#xff09;和文本挖掘 自然语言处理&#xff08;NLP&#xff09;和文本挖掘是数据科学中的重要领域&#xff0c;涉及对文本数据的分析和处理。Python 提供了丰富的库和工具&#xff0c;用于执行各种 NLP 和文本挖掘任务。以下是一些常见的…...

传统数组 vs vector和list

传统的数组&#xff1a; int arr[10]&#xff1b; 传统的数组有以下的缺点&#xff1a; 1&#xff09;长度不可修改 2)内存分配 局部数组:把数组定在函数内&#xff0c; 数组便是局部变量&#xff0c;故会被分配在栈上 但栈的大小是有限制的 &#xff0c;故其在内存中不能超…...

CRMEB 多商户版v3.0.1源码全开源+PC端+Uniapp前端+搭建教程

一.介绍 crmeb多商户是一套B2B2C商家入驻模式的平台多商户商城系统&#xff0c;系统支持平台自营、联营、招商等多种运营模式&#xff0c;可满足企业新零售、批发、分销、预售、O2O、多店、商铺入驻等各种业务需求。 后端全开源、uniapp多端可编译&#xff01; 二、搭建教程…...

【ESP32】ESP-IDF开发 | WiFi开发 | HTTPS服务器 + 搭建例程

1. 简介 1.1 HTTPS HTTPS&#xff08;HyperText Transfer Protocol over Secure Socket Layer&#xff09;&#xff0c;全称安全套接字层超文本传输协议&#xff0c;一般理解为HTTPSSL/TLS&#xff0c;通过SSL证书来验证服务器的身份&#xff0c;并为浏览器和服务器之间的通信…...

Vue2 中使用 UniApp 时,生命周期钩子函数总结

在 Vue2 中使用 UniApp 时&#xff0c;生命周期钩子函数是一个重要的概念。它允许开发者在特定的时间点运行代码&#xff0c;管理组件的生命周期。以下是 Vue2 中 UniApp 常用的生命周期钩子函数总结&#xff1a; 1. beforeCreate 说明: 组件实例刚被创建&#xff0c;此时数据…...

如何在 Vue 3 中使用 Vue Router 和 Vuex

在 Vue 3 中使用 Vue Router 1. 安装 Vue Router 在项目根目录下&#xff0c;通过 npm 或 yarn 安装 Vue Router 4&#xff08;适用于 Vue 3&#xff09;&#xff1a; npm install vue-router4 # 或者使用 yarn yarn add vue-router42. 创建路由配置文件 在 src 目录下创建…...

Fiori APP配置中的Semantic object 小bug

在配置自开发程序的Fiori Tile时&#xff0c;需要填入Semantic Object。正常来说&#xff0c;是需要通过事务代码/N/UI2/SEMOBJ来提前新建的。 但是在S4 2022中&#xff0c;似乎存在一个bug&#xff0c;即无需新建也能输入自定义的Semantic Object。 如下&#xff0c;当我们任…...

【触想智能】工业显示器和普通显示器的区别以及工业显示器的主要应用领域分析

在现代工业中&#xff0c;工业显示器被广泛应用于各种场景&#xff0c;从监控系统到生产控制&#xff0c;它们在实时数据显示、操作界面和信息传递方面发挥着重要作用。与普通显示器相比&#xff0c;工业显示器在耐用性、可靠性和适应特殊环境的能力上有着显著的差异。 触想工业…...

BPMN.js 与 DeepSeek 集成:打造个性化 Web 培训项目的秘诀

在数字化时代&#xff0c;Web培训项目的需求日益增长&#xff0c;特别是对于程序员群体&#xff0c;他们寻求高效、灵活的方式来提升自己的技能。本文将深入探讨如何评估BPMN.js与DeepSeek集成方案&#xff0c;以满足开发Web培训项目的需求。 BPMN.js 的优势 BPMN.js是一个专…...

第二月:学习 NumPy、Pandas 和 Matplotlib 是数据分析和科学计算的基础

以下是一个为期 **1 个月&#xff08;30 天&#xff09;**的详细学习计划&#xff0c;精确到每天的学习内容和练习作业&#xff0c;帮助你系统地掌握 NumPy、Pandas 和 Matplotlib 的核心功能。 第 1 周&#xff1a;NumPy 基础 Day 1&#xff1a;NumPy 简介与数组创建 学习内…...

安全测试|SSRF请求伪造

前言 SSRF漏洞是一种在未能获取服务器权限时&#xff0c;利用服务器漏洞&#xff0c;由攻击者构造请求&#xff0c;服务器端发起请求的安全漏洞&#xff0c;攻击者可以利用该漏洞诱使服务器端应用程序向攻击者选择的任意域发出HTTP请求。 很多Web应用都提供了从其他的服务器上…...

Flink提交pyflink任务

1.官方文档&#xff1a; flink1.14:https://nightlies.apache.org/flink/flink-docs-release-1.14/docs/deployment/cli/#submitting-pyflink-jobs flink1.18:https://nightlies.apache.org/flink/flink-docs-release-1.18/docs/deployment/cli/#submitting-pyflink-jobs 2.提…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...