数据结构与算法学习笔记之线性表四---单链表的表示和实现(C++)
目录
前言
一、顺序表的优缺点
二、单链表的表示和实现
1.初始化
2.清空表
3.销毁
4.表长
5.表空
6.获取表中的元素
7.下标
8.直接前驱
9.直接后继
10.插入
11.删除
12.遍历链表
13.测试代码
前言
这篇博客主要介绍单链表的表示和实现。
一、顺序表的优缺点
线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单直观的公式来表示。当然这种存储结构也存在弱点:在作插入或删除操作时,需移动大量元素。
二、单链表的表示和实现
单链表的两个要素:数据域,指针域。其中数据域表示的是当前结点的数据,指针域指向的下一个结点的地址。
单链表的定义如下:
// - - - - - 线性表的单链表存储结构 - - - - -
typedef int ElemType;
typedef int Staus;
typedef struct LNode {ElemType data; // 数据域struct LNode *next; // 指针域
} LNode, *LinkList;
1.初始化
// 链表初始化
Staus initLinkList(LinkList &linkList) {linkList = new LNode; // 创建头结点if (!linkList) { // 内存分配失败return false;}linkList->next = nullptr; // 头结点的指针域置空return true;
}
2.清空表
遍历单链表,置空指针
// 清空链表
void clearLinkList(LinkList &linkList) {LinkList p, q;p = linkList->next;while (p) {q = p;p = p->next;delete q;}linkList->next = nullptr;
}
3.销毁
// 销毁链表
void destroyLinkList(LinkList &linkList) {clearLinkList(linkList);delete linkList;linkList = nullptr;
}
4.表长
// 表长
int linkListLength(LinkList &link){LNode * p = link->next;int len = 0;while (p) {p = p->next;len++;}return len;
}
5.表空
// 表空
Status linkListEmpty(LinkList &link){return linkListLength(link) == 0;
}
6.获取表中的元素
// 获取表中的元素
Status getElemLinkList(LinkList &link,int pos,ElemType * element){if (pos < 1|| pos > linkListLength(link)) {return 0;}LinkList p = link->next;int j = 1;while (p && j < pos) {p = p ->next;++j;}if (!p ||j > pos) {return 0;}*element = p->data;return 1;
}
7.下标
// 获取数据元素element下标
Status getLocateinkList(LinkList &link,ElemType element,int * location){LinkList p = link->next;int j = 1;while (p) {if (p->data == element) {* location = j;return 1;}p = p ->next;++j;}return 0;
}
8.直接前驱
// 直接前驱
Status priorElemLinkList(LinkList &link,ElemType current,ElemType * priorElement){LinkList p = link->next;LinkList head = link;int j = 1;while (p) {if (p->data == current) {//找到数据元素if (j > 1) {* priorElement = head->data;return 1;}}p = p ->next;head = head->next;++j;}return 0;
}
9.直接后继
// 直接后继
Status nextElemLinkList(LinkList &link,ElemType current,ElemType * nextElement){LinkList p = link->next;while (p) {if (p->data == current) {//找到数据元素if (p -> next != nullptr) {* nextElement = p->next->data;return 1;}}}return 0;
}
10.插入
// 单链表插入
Status insertLinkList(LinkList &head, int pos, int element) {if (pos < 1) { // 位置非法return 0;}LinkList p = head;int j = 0;while (p && j < pos - 1) {p = p->next;++j;}if (!p || j > pos - 1) {return 0;}LinkList q = new LNode; // 生成新节点if (!q) { // 内存分配失败return 0;}q->data = element;q->next = p->next;p->next = q;return 1;
}
11.删除
// 单链表删除
Status deleteLinkList(LinkList &head, int pos) {if (pos < 1 || !head->next) { // 位置非法或空链表return false;}LinkList p = head;int j = 0;while (p->next && j < pos - 1) { // 找到要删除结点的前一个结点p = p->next;++j;}if (!p->next || j > pos - 1) { // 删除位置超出范围return false;}LinkList q = p->next; // 要删除的结点p->next = q->next; // 前一个结点指向后一个结点delete q; // 释放删除结点的内存return true;
}
12.遍历链表
// 遍历链表
void traverseList(LinkList linkList) {LinkList p = linkList->next;while (p) {cout << p->data << " ";p = p->next;}cout << endl;
}
13.测试代码
void testLinkList(void){LinkList myList;if (!initLinkList(myList)) {cout << "链表初始化失败!" << endl;}cout<<"表长:"<<linkListLength(myList)<<endl;int values[] = {1, 2, 3, 4, 5};int size = sizeof(values) / sizeof(values[0]);if (!createLinkList(myList, values, size)) {cout << "创建链表失败!" << endl;destroyLinkList(myList); // 避免内存泄漏}cout << "链表元素:";traverseList(myList);cout<<"表长:"<<linkListLength(myList)<<endl;cout << "获取某个位置的数据元素"<<endl;for (int i = -1; i <= 6; i++) {int element;if (getElemLinkList(myList, i, &element)) {cout<<"第"<<i<<"个数据元素获取成功,数据元素为:"<<element<<"\t"<<endl;}else{cout<<"第"<<i<<"个数据元素获取失败!"<<endl;}}cout<<endl;cout << "获取单链表数据元素下标"<<endl;for (int i = -1; i <= 6; i++) {int locate;if (getLocateinkList(myList, i, &locate)) {cout<<"数据元素"<<i<<"下标获取成功,下标为:"<<locate<<"\t"<<endl;}else{cout<<"数据元素"<<i<<"下标获取失败!"<<endl;}}cout<<endl;cout << "获取单链表数据元素直接前驱"<<endl;for (int i = -1; i <= 6; i++) {int element;if (priorElemLinkList(myList, i, &element)) {cout<<"数据元素"<<i<<"直接前驱为:"<<element<<"\t"<<endl;}else{cout<<"数据元素"<<i<<"没有直接前驱!"<<endl;}}// 插入元素int insertPos = 3;int insertElement = 10;if (!insertLinkList(myList, insertPos, insertElement)) {cout << "插入元素失败!" << endl;destroyLinkList(myList); // 避免内存泄漏}cout << "插入后的链表元素:";traverseList(myList);// 删除元素int deletePos = 2;if (!deleteLinkList(myList, deletePos)) {cout << "删除元素失败!" << endl;destroyLinkList(myList); // 避免内存泄漏}cout << "删除后的链表元素:";traverseList(myList);// 清空链表clearLinkList(myList);cout << "链表已清空!" << endl;// 销毁链表destroyLinkList(myList);cout << "链表已销毁!" << endl;
}
相关文章:

数据结构与算法学习笔记之线性表四---单链表的表示和实现(C++)
目录 前言 一、顺序表的优缺点 二、单链表的表示和实现 1.初始化 2.清空表 3.销毁 4.表长 5.表空 6.获取表中的元素 7.下标 8.直接前驱 9.直接后继 10.插入 11.删除 12.遍历链表 13.测试代码 前言 这篇博客主要介绍单链表的表示和实现。 一、顺序表的优缺点 线…...

go语言切片slice使用细节和注意事项整理
go语言中切片slice的使用是最为频繁的,效率也是最高的, 今天就给大家说说我们在使用过程中会忽略的一些细节。 先普及一下slice的核心基础知识, go语言中的切片是引用类型, 其底层数据的存储实际上是存储在一个数组 上(…...

C语言 | Leetcode C语言题解之第85题最大矩形
题目: 题解: int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize) {int m matrixSize;if (m 0) {return 0;}int n matrixColSize[0];int left[m][n];memset(left, 0, sizeof(left));for (int i 0; i < m; i) {for (int j …...

2024-05-13四月初六周一
2024-05-13四月初六周一 06:30-08:30 coding 动态规划算法: 08:30-12:30 深兰Ai第五期 Part1:课时269:00:00:00 12:30-13:00 午饭烧水: 13:30-19:00 深兰Ai第五期: 20:00-23:00 coding 线性回归:...
Android性能:高版本Android关闭硬件加速GPU渲染滑动卡顿掉帧
Android性能:高版本Android关闭硬件加速GPU渲染滑动卡顿掉帧 如果在Androidmanifest.xml配置: <application android:hardwareAccelerated"false" > 或者某个特点View使用代码: myView.setLayerType(View.LAYER_TYPE_SOFT…...

对于FileUpload控件的一些bug
我写的程序,问题出现的也很神奇,就是我在上传已经存在在我指定目录下的就可以成功,如果不存在,上传仍是可以成功的,但是就会不显示,但是你重启服务器的时候又会再次显示。这种问题出现的原因我们就需要了解…...

哲学家就餐问题
哲学家就餐问题 问题信号量实现发生死锁版限制人数版规定取筷顺序 条件变量实现 问题 在一个圆桌上坐着五位哲学家,每个哲学家面前有一个碗装有米饭的碗和一个筷子。哲学家的生活包括思考和进餐两个活动。当一个哲学家思考时,他不需要任何资源。当他饿了…...

Web安全:SQL注入之布尔盲注原理+步骤+实战操作
「作者简介」:2022年北京冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础对安全知识体系进行总结与归纳,著作适用于快速入门的 《网络安全自学教程》,内容涵盖系统安全、信息收集等…...

电商秒杀系统-案例04-redis下的session控制
前言: 在现代的Web应用中,安全和高效的用户身份验证机制是至关重要的。本文将深入探讨基于令牌的用户登录会话机制,特别是在使用Redis进行会话管理的情景。通过这一案例实战,我们将了解令牌如何在用户身份验证过程中发挥核心作用&…...

贪吃蛇(c实现)
目录 游戏说明: 第一个是又是封面,第二个为提示信息,第三个是游戏运行界面 游戏效果展示: 游戏代码展示: snack.c test.c snack.h 控制台程序的准备: 控制台程序名字修改: 参考:…...

【论文阅读笔记】MapReduce: Simplified Data Processing on Large Clusters
文章目录 1 概念2 编程模型3 实现3.1 MapReduce执行流程3.2 master数据结构3.3 容错机制3.3.1 worker故障3.3.2 master故障3.3.3 出现故障时的语义 3.4 存储位置3.5 任务粒度3.6 备用任务 4 扩展技巧4.1 分区函数4.2 顺序保证4.3 Combiner函数4.4 输入和输出的类型4.5 副作用4.…...

LeetCode题练习与总结:二叉树的中序遍历--94
一、题目描述 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2]示例 2: 输入:root [] 输出:[]示例 3: 输入:roo…...

云计算十三课
centos安装 点击左上角文件 点击新建虚拟机 点击下一步 点击稍后安装操作系统,下一步 选择Linux(l)下一步 设置虚拟机名称 点击浏览选择安装位置 新建文件夹设置名称不能为中文,点击确定 点击下一步 设置磁盘大小点击下一步…...

[数据集][目标检测]电力场景安全帽检测数据集VOC+YOLO格式295张2类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):295 标注数量(xml文件个数):295 标注数量(txt文件个数):295 标注类别…...

AtCoder Beginner Contest 308 A题 New Scheme
A题:New Scheme 标签:模拟 题意:给定 8 8 8个数的序列,询问这些数是否满足以下条件: 在 100 100 100到 675 675 675之间且能被 25 25 25整除序列是单调非递减的 题解:按题意模拟判断就好了。 代码&#…...

C++编程与朱元墇的关系
学编程和英语没关系,我说这句话,没人会相信,也不会有人说我什么哗众取宠。 我说学编程和朱元墇有关系,一定有人说我放P,其实这个P也和朱元墇有关系, 和朱元墇有什么P关系啊。 真有这P事啊, 朱元…...

0060__设计模式
1. 简单工厂模式( Simple Factory Pattern ) — Graphic Design Patterns 工厂模式 | 菜鸟教程 【设计模式——学习笔记】23种设计模式——建造者模式Builder(原理讲解应用场景介绍案例介绍Java代码实现)-CSDN博客 设计模式—— 五:迪米特…...

【Linux 网络】网络编程套接字 -- 详解
⚪ 预备知识 1、理解源 IP 地址和目的 IP 地址 举例理解:(唐僧西天取经) 在 IP 数据包头部中 有两个 IP 地址, 分别叫做源 IP 地址 和目的 IP 地址。 如果我们的台式机或者笔记本没有 IP 地址就无法上网,而因为…...

编译OpenResty遇到找不到OpenSSL的解决办法
以OpenResty-1.19.9.1为例 编辑openresty-1.19.9.1/build/nginx-1.19.9/auto/lib/openssl/conf CORE_INCS"$CORE_INCS $OPENSSL/.openssl/include" CORE_DEPS"$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h" CORE_LIBS"$CORE_LIBS $OPENSSL/.…...

Amazon Bedrock 托管 Llama 3 8B70B
Amazon Bedrock 托管 Llama 3 8B&70B,先来体验:(*实验环境账号有效期为1天,到期自动关停,请注意重要数据保护) https://dev.amazoncloud.cn/experience/cloudlab?id65fd86c7ca2a0d291be26068&visi…...

海豚调度器早期版本如何新增worker分组
在DolphinScheduler 1.3.5版本中,Worker分组通常是在部署时通过配置文件进行定义的,而不是在用户界面上直接操作。以下是在DolphinScheduler中新增Worker分组的一般步骤: 修改配置文件: DolphinScheduler的Worker分组信息通常在/…...

Debian Linux 下给Nginx 1.26.0 编译增加Brotli算法支持
明月发现参考【给Nginx添加谷歌Brotli压缩算法支持】一文给出的方法,在Debian Linux 12.5下就一直编译失败,主要的错误是因为文件缺失,在专门又安装了apt-get install libbrotli-dev的依赖库后依然会因为文件缺失无法编译完成,就这…...

中国银行从业在线教育系统,如何搭建网课平台?
如今这个时代相信没多少人是没听过网课平台的,绝大多数人对网课平台的名气是如雷贯耳的。时代的发展,让人们学习的方式变得更加的方便与快捷。今天就来和大家说说网课平台搭建都有哪些方法?网课平台难搭建么? 网课平台搭建的方法,其实网课平…...

解决java.lang.IllegalArgumentException异常的正确方法
java.lang.IllegalArgumentException 是 Java 中的一个异常类,表示方法中传递的参数不合法。这个异常通常在方法被调用时抛出,表明方法的参数出现了问题。要正确解决这个异常,你可以按照以下步骤进行: 查看异常信息:首…...

齿轮滚刀刃口钝化技术简介
介绍 在滚刀的使用中发现,进口滚刀和国产滚刀在加工质量和寿命方面存在显著差异。经过多次比较得知,滚刀的使用寿命可以达到国产滚刀的两倍以上,而进口滚刀返回原厂磨削后的使用寿命约为新刀具的90% ,但同样经过国内厂家磨削后&a…...

【ESP32接入ATK-MO1218 GPS模块】
【ESP32接入ATK-MO1218 GPS模块】 1. 引言2. ATK-MO1218 GPS模块概述3. 接入ATK-MO1218 GPS模块的步骤4. 示例代码5. 结论1. 引言 在现代的嵌入式系统和物联网项目中,精确的位置信息是至关重要的。ATK-MO1218 GPS模块作为一款高性能的GPS/北斗双模定位模块,为开发者提供了强…...

EDA设计学习笔记2:STM32F103C8T6最小系统板的仿绘
今日开始仿制练习一个STM32F103C8T6最小系统板,通过对这个最小系统板的仿制,达到对自己PCB设计的练习的目的,最终目标是自己设计出一块PCB,做一个OLED的桌面小摆件...... 也不知道画出来能不能用..... 目录 主控芯片的搜索与放置…...

实现树莓派DS18B20读取温度(OneWire)
简介 使用的是树莓派3B, Go编程实现OneWire方式读取DS18B20温度。 接线 DS18B20 包含经典三线, VCC和GND自不必说, 主要的是DQ线, 需要接4.7K的上拉电阻, 即4.7K欧姆的电阻接到DQ和VCC, 否则树莓派识别不到DS18B20&am…...

Android 蓝牙实战——蓝牙音乐播放/暂停状态(二十二)
对于蓝牙音乐的播放状态,我们首先主要处理的是 onPlayStatusChanged() 回调,这是协议栈通知 FW 层的一个回调接口。还有一个就是 getPlayBackState() 方法,这是媒体应用在初始化时未收到回调信息主动获取当前状态的方法。我们这里就来分析一下这两个状态的获取流程。 一、状…...

linux学习:视频输入+V4L2
目录 V4L2 视频采集流程 代码例子 核心命令字和结构体 VIDIOC_ENUM_FMT VIDIOC_G_FMT / VIDIOC_S_FMT / VIDIOC_TRY_FM VIDIOC_REQBUFS VIDIOC_QUERYBUF VIDIOC_QBUF /VIDIOC_DQBUF VIDIOC_STREAMON / VIDIOC_STREAMOFF V4L2 是 Linux 处理视频的最新标准代码模块&…...