【数据结构】线性表(二)单链表及其基本操作(创建、插入、删除、修改、遍历打印)
目录
前文、线性表的定义及其基本操作(顺序表插入、删除、查找、修改)
四、线性表的链接存储结构
1. 单链表(C语言)
a. 链表节点结构
b. 创建新节点
c. 在链表末尾插入新节点
d. 删除指定节点
e. 修改指定节点的数据
f. 遍历链表并打印
g. 主函数
C语言代码整合
Cpp代码整合
前文、线性表的定义及其基本操作(顺序表插入、删除、查找、修改)
按照线性表结点间的逻辑顺序依次将它们存储于一组地址连续的存储单元中的存储方式被称为线性表的顺序存储方式。
按顺序存储方式存储的线性表具有顺序存储结构,一般称之为顺序表。换言之,在程序中采用定长的一维数组,按照顺序存储方式存储的线性表,被称为顺序表。若顺序表中的元素按其值有序,则称其为有序顺序表。
在高级程序设计语言中,“数组”这种数据类型同样具有随机存储的特性,因此用高级程序设计语言实现线性表的顺序存储结构时,通常选择数组。因此,数组的长度就是顺序表的最大长度(MaxSize),顺序表的实际长度为length,其值必须小于等于MaxSize。

【数据结构】线性表(一)线性表的定义及其基本操作(顺序表插入、删除、查找、修改)-CSDN博客
https://blog.csdn.net/m0_63834988/article/details/132089038?spm=1001.2014.3001.5501
四、线性表的链接存储结构
顺序表的优点是存取速度快。但是,无论是插入一个结点,还是删除一个结点,都需要调整一批结点的地址。要克服该缺点,就必须给出一种不同于顺序存储的存储方式。用链接存储方式存储的线性表被称为链表,可以克服上述缺点。
链表中的结点用存储单元(若干个连续字节)来存放,存储单元之间既可以是(存储空间上)连续的,也可以是不连续的,甚至可以零散地分布在存储空间中的任何位置。换言之,链表中结点的逻辑次序和物理次序之间并无必然联系。最重要的是,链表可以在不移动结点位置的前提下根据需要随时添加删除结点,动态调整。

1. 单链表(C语言)
在链接存储结构中,插入和删除操作相对于顺序存储结构而言更加高效,时间复杂度为O(1)。而查找操作的时间复杂度为O(n)。
a. 链表节点结构
typedef struct Node {int data;struct Node* next;
} Node;
链表节点的结构体 Node,包含一个整数数据 data 和一个指向下一个节点的指针 next
b. 创建新节点
Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));if (newNode != NULL) {newNode->data = data;newNode->next = NULL;}return newNode;
}
- 创建一个新的节点并返回指向该节点的指针:
- 使用
malloc分配了节点的内存空间; - 将传入的数据赋值给节点的
data字段,并将next字段设置为NULL。
- 使用
c. 在链表末尾插入新节点
void insertAtEnd(Node** head, int data) {Node* newNode = createNode(data);if (newNode == NULL) {printf("内存分配失败!\n");return;}if (*head == NULL) {*head = newNode;} else {Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;}printf("已在链表末尾插入节点:%d", data);
}
- 调用
createNode函数创建一个新节点; - 检查内存分配是否成功;
- 如果成功,则根据链表是否为空来确定新节点的位置。
- 若链表为空,则将新节点设置为头节点;
- 否则,遍历链表找到最后一个节点,并将最后一个节点的
next指针指向新节点。
d. 删除指定节点
void deleteNode(Node** head, int data) {if (*head == NULL) {printf("链表为空!\n");return;}Node* temp = *head;Node* prev = NULL;if (temp != NULL && temp->data == data) {*head = temp->next;free(temp);printf("已删除节点:%d", data);return;}while (temp != NULL && temp->data != data) {prev = temp;temp = temp->next;}if (temp == NULL) {printf("节点 %d 不存在!\n", data);return;}prev->next = temp->next;free(temp);printf("已删除节点:%d", data);
}
- 检查链表是否为空,如果为空则输出相应的提示信息。
- 遍历链表,找到要删除的节点。
- 如果找到了节点,则修改前一个节点的
next指针,使其跳过要删除的节点,并释放该节点的内存空间。 - 如果没有找到要删除的节点,则输出相应的提示信息。
- 如果找到了节点,则修改前一个节点的
e. 修改指定节点的数据
void modifyNode(Node* head, int oldData, int newData) {if (head == NULL) {printf("链表为空!\n");return;}Node* temp = head;while (temp != NULL) {if (temp->data == oldData) {temp->data = newData;printf("已将节点 %d 修改为 %d\n", oldData, newData);return;}temp = temp->next;}printf("节点 %d 不存在!\n", oldData);
}
查找~删除~修改……这里不重复介绍,懂的都懂,不懂我也没办法
f. 遍历链表并打印
void printList(Node* head) {if (head == NULL) {printf("链表为空!\n");return;}Node* temp = head;printf("链表节点数据:");while (temp != NULL) {printf("%d ", temp->data);temp = temp->next;}printf("\n");
}
- 检查链表是否为空,如果为空则输出相应的提示信息。
- 使用一个临时指针变量
temp来遍历链表,依次访问每个节点并打印其数据。
g. 主函数
nt main() {Node* head = NULL; // 头节点insertAtEnd(&head, 1);insertAtEnd(&head, 2);insertAtEnd(&head, 3);printList(head);deleteNode(&head, 2);printList(head);deleteNode(&head, 4);return 0;
}
- 创建了一个头节点
head; - 调用
insertAtEnd函数三次,在链表末尾插入了三个节点; - 调用
printList函数打印链表的节点数据; - 调用
deleteNode函数删除链表中的一个节点,并再次打印链表的节点数据; - 调用
deleteNode函数尝试删除一个不存在的节点。

C语言代码整合
#include <stdio.h>
#include <stdlib.h>// 定义链表节点结构
typedef struct Node {int data;struct Node* next;
} Node;// 创建新节点
Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));if (newNode != NULL) {newNode->data = data;newNode->next = NULL;}return newNode;
}// 在链表末尾插入新节点
void insertAtEnd(Node** head, int data) {Node* newNode = createNode(data);if (newNode == NULL) {printf("内存分配失败!\n");return;}if (*head == NULL) {*head = newNode;} else {Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;}printf("已在链表末尾插入节点:%d", data);
}// 删除指定节点
void deleteNode(Node** head, int data) {if (*head == NULL) {printf("链表为空!\n");return;}Node* temp = *head;Node* prev = NULL;if (temp != NULL && temp->data == data) {*head = temp->next;free(temp);printf("已删除节点:%d", data);return;}while (temp != NULL && temp->data != data) {prev = temp;temp = temp->next;}if (temp == NULL) {printf("节点 %d 不存在!\n", data);return;}prev->next = temp->next;free(temp);printf("已删除节点:%d", data);
}
// 修改指定节点的数据
void modifyNode(Node* head, int oldData, int newData) {if (head == NULL) {printf("链表为空!\n");return;}Node* temp = head;while (temp != NULL) {if (temp->data == oldData) {temp->data = newData;printf("已将节点 %d 修改为 %d\n", oldData, newData);return;}temp = temp->next;}printf("节点 %d 不存在!\n", oldData);
}
// 遍历链表并打印节点数据
void printList(Node* head) {if (head == NULL) {printf("链表为空!\n");return;}Node* temp = head;printf("链表节点数据:");while (temp != NULL) {printf("%d ", temp->data);temp = temp->next;}printf("\n");
}// 主函数测试链表操作
int main() {Node* head = NULL; // 头节点insertAtEnd(&head, 1);insertAtEnd(&head, 2);insertAtEnd(&head, 3);printList(head);deleteNode(&head, 2);printList(head);deleteNode(&head, 4);return 0;
}
Cpp代码整合
与C语言基本相同,这里不再过多介绍
#include <iostream>// 定义链表节点结构
class Node {
public:int data;Node* next;// 构造函数Node(int data) : data(data), next(nullptr) {}
};// 链表类
class LinkedList {
private:Node* head;public:// 构造函数LinkedList() : head(nullptr) {}// 析构函数,用于释放链表内存~LinkedList() {Node* current = head;while (current != nullptr) {Node* next = current->next;delete current;current = next;}}// 在链表末尾插入新节点void insertAtEnd(int data) {Node* newNode = new Node(data);if (head == nullptr) {head = newNode;} else {Node* temp = head;while (temp->next != nullptr) {temp = temp->next;}temp->next = newNode;}std::cout << "已在链表末尾插入节点:" << data << std::endl;}// 删除指定节点void deleteNode(int data) {if (head == nullptr) {std::cout << "链表为空!" << std::endl;return;}Node* temp = head;Node* prev = nullptr;if (temp != nullptr && temp->data == data) {head = temp->next;delete temp;std::cout << "已删除节点:" << data << std::endl;return;}while (temp != nullptr && temp->data != data) {prev = temp;temp = temp->next;}if (temp == nullptr) {std::cout << "节点 " << data << " 不存在!" << std::endl;return;}prev->next = temp->next;delete temp;std::cout << "已删除节点:" << data << std::endl;}// 修改指定节点的数据void modifyNode(int oldData, int newData) {if (head == nullptr) {std::cout << "链表为空!" << std::endl;return;}Node* temp = head;while (temp != nullptr) {if (temp->data == oldData) {temp->data = newData;std::cout << "已将节点 " << oldData << " 修改为 " << newData << std::endl;return;}temp = temp->next;}std::cout << "节点 " << oldData << " 不存在!" << std::endl;}// 遍历链表并打印节点数据void printList() {if (head == nullptr) {std::cout << "链表为空!" << std::endl;return;}Node* temp = head;std::cout << "链表节点数据:";while (temp != nullptr) {std::cout << temp->data << " ";temp = temp->next;}std::cout << std::endl;}
};int main() {LinkedList list;list.insertAtEnd(1);list.insertAtEnd(2);list.insertAtEnd(3);list.printList();list.deleteNode(2);list.printList();list.deleteNode(4);return 0;
}

相关文章:
【数据结构】线性表(二)单链表及其基本操作(创建、插入、删除、修改、遍历打印)
目录 前文、线性表的定义及其基本操作(顺序表插入、删除、查找、修改) 四、线性表的链接存储结构 1. 单链表(C语言) a. 链表节点结构 b. 创建新节点 c. 在链表末尾插入新节点 d. 删除指定节点 e. 修改指定节点的数据 f. …...
label的作用是什么?是怎么用的?(1)
Label(标签)在不同的上下文中有不同的作用和用途。以下是几种常见的用途和用法: 1. 数据标注:在机器学习和数据科学中,标签用于标识数据样本的类别或属性。标注数据是监督学习中的一项重要任务,它为算法提…...
C- 使用原子变量实现自旋锁
自旋锁 自旋锁(Spinlock)是一种常用于多线程编程中的低开销锁,其特点是当线程尝试获取锁而锁已被其他线程占用时,该线程会处于一个持续的忙等待(busy-wait)状态,直到它可以获取到锁为止。这种方…...
汇编的指令
减法类指令: 不带借位的减法: sub dest,src;dest(dest)-(src) 注意: 1、源操作数和目的操作数不能同时为段寄存器或存储单元 2、对标志位有影响,主要影响CF、ZF、OF、SF。 带借位的减法: sbb dest,src;dest(dest)-(…...
《数据结构、算法与应用C++语言描述》使用C++语言实现数组队列
《数据结构、算法与应用C语言描述》使用C语言实现数组队列 定义 队列的定义 队列(queue)是一个线性表,其插入和删除操作分别在表的不同端进行。插入元素的那一端称为队尾(back或rear),删除元素的那一端称…...
零基础如何学习自动化测试
现在很多测试人员有些急于求成,没有任何基础想当然的,要在一周内上手自动化测试。 在自动化的过程中时候总有人会犯很低级的问题,有语法问题,有定位问题,而且有人居然连__init__.py 文件名都弄错误,还有将…...
系统架构师备考倒计时16天(每日知识点)
1.信息化战略与实施 2.UML图(12个) 3.结构化设计(耦合) 4.SMP与AMP的区别(多核处理器的工作方式) 多核处理器一般有SMP和AMP两种不同的工作方式: SMP(对称多处理技术):将2颗完全一样的处理器封…...
【MySQL系列】- Select查询SQL执行过程详解
【MySQL系列】- Select查询SQL执行过程详解 文章目录 【MySQL系列】- Select查询SQL执行过程详解一、SQL查询语句的执行过程二、SQL执行过程详解2.1. 连接器2.2. 查询缓存2.3. 分析器2.4. 优化器2.5. 执行器 三、undo log 和 redo log作⽤3.1. redo log (重做日志&a…...
软考高级信息系统项目管理师系列之:信息系统项目管理师论文评分参考标准
软考高级信息系统项目管理师系列之:信息系统项目管理师论文评分参考标准 论文满分是 75 分,论文评分可分为优良、及格与不及格 3 个档次。评分的分数可分为: 60 分至 75 分优良(相当于百分制 80 分至 100 分)。45 分至 59 分及格(相当于百分制 60 分至 79 分)。0 分至 44 分…...
MyBatis--多案例让你熟练使用CRUD操作
目录 一、前期准备 二、两种实现CRUD方式 三、增加数据(INSERT) 四、删除数据(DELETE) 五、查询数据(SELECT) 六、更新数据(UPDATE) 一、前期准备 1.创建maven项目并在pom文件…...
用Python造轮子
目录 背景安装setuptools库准备要打包的代码创建setup.py文件打包生成whl文件把库装到电脑上使用这个库 背景 如何把自己写的代码,打包成库方便其他人使用 安装setuptools库 正所谓想要富先修路,先把造轮子要用的库装上 pip install wheel pip insta…...
ARM 堆栈寻址类型区分
文章目录 堆栈指向分类堆栈指向数据分类满递增与满递减空递增与空递减 堆栈指向分类 根据堆栈指针的指向的方向不同,可以划分为向上生成型和向下生成型。 向上生成型: 随着数据的入栈,堆栈的指针逐渐增大,称为:递增…...
每日一练 | 网络工程师软考真题Day43
1、在生成树协议〔STP〕IEEE 802.1d中,根据 来选择根交换机。 A.最小的MAC地址 B.最大的MAC地址 C.最小的交换机ID D.最大的交换机ID 2、在快速以太网物理层标准中,使用两对5类无屏蔽双绞线的是 。 A&…...
jsonXML格式化核心代码
json格式化: 依赖: <dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>2.6.0</version><scope>compile</scope> </dependency> string t…...
PTQ量化和QAT量化
目录 1--PTQ量化 2--QAT量化 1--PTQ量化 PTQ量化表示训练后量化(Post Training Quantization)。使用一批校准数据对训练好的模型进行校准,将训练好的FP32网络直接转换为定点计算的网络,过程中无需对原始模型进行任何训练&#x…...
【Django 02】数据表构建、数据迁移与管理
1. Django 构建数据表创建与数据迁移 1.1 数据表创建 1.1.1 模块功能 如前所述,models.py文件主要用一个 Python 类来描述数据表。运用这个类,可以通过简单的 Python 代码来创建、检索、更新、删除 数据库中的记录而无需写一条又一条的SQL语句。今天的例子就是在…...
一天吃透Java集合面试八股文
内容摘自我的学习网站:topjavaer.cn 常见的集合有哪些? Java集合类主要由两个接口Collection和Map派生出来的,Collection有三个子接口:List、Set、Queue。 Java集合框架图如下: List代表了有序可重复集合,…...
高级深入--day36
Settings Scrapy设置(settings)提供了定制Scrapy组件的方法。可以控制包括核心(core),插件(extension),pipeline及spider组件。比如 设置Json Pipeliine、LOG_LEVEL等。 参考文档:Settings — Scrapy 1.0.5 文档 内置设置参考手册 BOT_NAME 默认: scrapybot 当您使用 sta…...
Jmeter接口测试工具的一些使用小技巧
如何使用英文界面的JMeter Jmeter启动时会自动判断操作系统的locale 并选择合适的语言启动,所以,我们启动jmeter后,其会出现一个倍感亲切的中文界面。但由于jmeter本身的汉化工作做得不好,你会看到有未被汉化的选项及元件的参数。…...
黄金眼PAAS化数据服务DIFF测试工具的建设实践 | 京东云技术团队
一、背景介绍 黄金眼PAAS化数据服务是一系列实现相同指标服务协议的数据服务,各个服务间按照所生产指标的主题作划分,比如交易实时服务提供实时交易指标的查询,财务离线服务提供离线财务指标的查询。黄金眼PAAS化数据服务支撑了黄金眼APP、黄…...
OpenClaw 实用指南-节假日系统巡检全自动化(下)
前言 在上一篇文章中,我们已详细讲解了节假日系统巡检全自动化的前三个核心部分,分别是:Part1:AI节假日智能判断、Part2:目标服务器稳定连接、Part3:借助“小龙虾”工具批量部署软件,并利用部署…...
Qwen2.5-14B-Instruct开源模型落地:像素剧本圣殿短视频脚本批量生成
Qwen2.5-14B-Instruct开源模型落地:像素剧本圣殿短视频脚本批量生成 1. 项目概述 像素剧本圣殿(Pixel Script Temple)是一款基于Qwen2.5-14B-Instruct深度微调的专业剧本创作工具。它将顶尖的AI推理能力与8-Bit复古美学完美融合,…...
实测Qwen-Image-Edit-2511:输入一张图,输出360°环绕视角,效果太强了
实测Qwen-Image-Edit-2511:输入一张图,输出360环绕视角,效果太强了 1. 引言:单图变多视角的技术突破 想象一下,你只需要一张普通的商品照片,就能自动生成360度全方位的展示效果。这不是科幻电影里的场景&…...
3分钟焕新网易云音乐:BetterNCM Installer插件框架一键部署方案
3分钟焕新网易云音乐:BetterNCM Installer插件框架一键部署方案 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer BetterNCM Installer是一款专为网易云音乐PC版设计的开源插…...
保姆级教学:用FUTURE POLICE和MySQL管理你的语音字幕数据
保姆级教学:用FUTURE POLICE和MySQL管理你的语音字幕数据 1. 为什么需要管理语音字幕数据? 想象一下这样的场景:你刚刚用FUTURE POLICE处理了100个会议录音,得到了精确到毫秒的字幕文件。这些文件散落在各个文件夹里,…...
终极指南:3分钟快速掌握Logisim-evolution数字电路设计与仿真
终极指南:3分钟快速掌握Logisim-evolution数字电路设计与仿真 【免费下载链接】logisim-evolution Digital logic design tool and simulator 项目地址: https://gitcode.com/gh_mirrors/lo/logisim-evolution 想要学习数字电路设计却不知从何开始࿱…...
Source Han Serif CN全解析:免费商用字体的7大维度深度指南
Source Han Serif CN全解析:免费商用字体的7大维度深度指南 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 一、问题:中文字体应用的三大行业困境 如何突破中文…...
Oracle里的MINUS是什么
在 Oracle 中,MINUS 是 SQL 中的一个集合操作符,它用于比较两个查询的结果集,并返回第一个查询中有而第二个查询中没有的不重复记录。 核心概念 MINUS 执行的是集合的“差集”操作。你可以把它想象成数学中的减法:结果集A - 结果集…...
数字记忆守护者:GetQzonehistory全攻略
数字记忆守护者:GetQzonehistory全攻略 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 一、数字记忆危机:我们正在失去什么? 在这个信息爆炸的时代&…...
FreeCache内存管理终极指南:零GC开销的预分配机制详解
FreeCache内存管理终极指南:零GC开销的预分配机制详解 【免费下载链接】freecache A cache library for Go with zero GC overhead. 项目地址: https://gitcode.com/gh_mirrors/fr/freecache 在Go语言开发中,内存管理和垃圾回收(GC&am…...
