第 2 章 线性表 (线性表的静态单链表存储结构(一个数组只生成一个静态链表)实现)

1. 背景说明

A = { c, b, e, g, f, d }B = { a, b, n, f }

2. 示例代码 

1) status.h

/* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H
#define STATUS_H#define CHECK_RET(ret) if (ret != RET_OK) { \printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret); \return ret; \
}#define CHECK_VALUE(value, ERR_CODE) if (value) { \printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_CODE); \return ERR_CODE; \
}#define CHECK_FALSE(value, ERR_CODE) if (!(value)) { \printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_CODE); \return FALSE; \
} /* 函数结果状态码 */
#define TRUE 					1			/* 返回值为真 */
#define FALSE 					0			/* 返回值为假 */
#define RET_OK 					0			/* 返回值正确 */
#define INFEASIABLE    		   	2			/* 返回值未知 */
#define ERR_MEMORY     		   	3			/* 访问内存错 */
#define ERR_NULL_PTR   			4			/* 空指针错误 */
#define ERR_MEMORY_ALLOCATE		5			/* 内存分配错 */
#define ERR_NULL_STACK			6			/* 栈元素为空 */
#define ERR_PARA				7			/* 函数参数错 */
#define ERR_OPEN_FILE			8			/* 打开文件错 */
#define ERR_NULL_QUEUE			9			/* 队列为空错 */
#define ERR_FULL_QUEUE			10			/* 队列为满错 */
#define ERR_NOT_FOUND			11			/* 表项不存在 */
typedef int Status;							/* Status 是函数的类型,其值是函数结果状态代码,如 RET_OK 等 */
typedef int Bollean;						/* Boolean 是布尔类型,其值是 TRUE 或 FALSE */#endif // !STATUS_H

 

2) staticLinkListSingle.h

/* 静态链表(一个数组只生成一个静态链表)实现头文件 */#ifndef STATICLINKLISTSINGLE_H
#define STATICLINKLISTSINGLE_H#include "status.h"#define MAX_SIZE 100typedef int ElemType;typedef struct {ElemType data;int curr;
} SLinkList[MAX_SIZE];/* 若备用链表非空,则返回分配的结点下标(备用链表的第一个结点),否则返回 0 */
int Malloc(SLinkList space);/* 将下标为 i 的空闲结点回收到备用链表(成为备用链表的第一个结点) */
void Free(SLinkList space, int i);/* 静态数组无法被销毁 */
void DestroyList(void);/* 构造一个空的链表,表头为 L 的最后一个单元 L[MAXSIZE - 1],其余单元链成一个备用链表,表头为 L 的第一个单元 L[0],'0' 表示空指针 */
void InitList(SLinkList L);/* 初始条件:线性表 L 已存在操作结果:将 L 重置为空表 */
Status ClearList(SLinkList L);/* 若 L 是空表,返回 TRUE;否则返回 FALSE */
Bollean ListEmpty(SLinkList L);/* 返回 L 中数据元素个数 */
int ListLength(SLinkList L);/* 用 e 返回 L 中第 i 个元素的值 */
Status GetElem(SLinkList L, int i, ElemType *e);/* 算法 2.13, 在静态单链线性表 L 中查找第 1 个值为 e 的元素。若找到,则返回它在 L 中的位序,否则返回 0 */
int LocateElem(SLinkList L, ElemType e);/* 初始条件:线性表 L 已存在操作结果:若 curr_e 是 L 的数据元素,且不是第一个,则用 pre_e返回它的前驱否则操作失败,pre_e 无定义 */
Status PriorElem(SLinkList L, ElemType curr_e, ElemType *pre_e);/* 初始条件:线性表 L 已存在操作结果:若 curr_e 是 L 的数据元素,且不是最后一个,则用 next_e 返回它的后继, 否则操作失败,next_e 无定义 */
Status NextElem(SLinkList L, ElemType curr_e, ElemType *next_e);/* 在 L 中第 i 个元素之前插入新的数据元素 e */
Status ListInsert(SLinkList L, int i, ElemType e);/* 删除在 L 中第 i 个数据元素 e,并返回其值 */
Status ListDelete(SLinkList L, int i, ElemType *e);/* 初始条件: 线性表 L 已存在操作结果: 依次对 L 的每个数据元素调用函数 vi()。一旦 vi() 失败, 则操作失败 */
Status ListTraverse(SLinkList L, void(*vi)(ElemType));#endif

3) staticLinkListSingle.c

/* 静态链表(一个数组只生成一个静态链表)实现源文件 */#include "staticLinkListSingle.h"
#include <stdio.h>/* 若备用链表非空,则返回分配的结点下标(备用链表的第一个结点),否则返回 0 */
int Malloc(SLinkList space)
{int i = space[0].curr;if (i) {space[0].curr = space[i].curr;}return i;
}/* 将下标为 i 的空闲结点回收到备用链表(成为备用链表的第一个结点) */
void Free(SLinkList space, int i)
{space[i].curr = space[0].curr;space[0].curr = i;
}/* 静态数组无法被销毁 */
void DestroyList(void)
{printf("Static array do not need to free memory!\n");
}/* 构造一个空的链表,表头为 L 的最后一个单元 L[MAXSIZE - 1],其余单元链成一个备用链表,表头为 L 的第一个单元 L[0],'0' 表示空指针 */
void InitList(SLinkList L)
{L[MAX_SIZE - 1].curr = 0;for (int i = 0; i < MAX_SIZE - 2; ++i) {L[i].curr = i + 1;}L[MAX_SIZE - 2].curr = 0;
}/* 初始条件:线性表 L 已存在操作结果:将 L 重置为空表 */
Status ClearList(SLinkList L)
{int i = L[MAX_SIZE - 1].curr;L[MAX_SIZE - 1].curr = 0;int k = L[0].curr;L[0].curr = i;int j;while (i) {j = i;i = L[i].curr;}L[j].curr = k;return RET_OK;
}/* 若 L 是空表,返回 TRUE;否则返回 FALSE */
Bollean ListEmpty(SLinkList L)
{return (L[MAX_SIZE - 1].curr == 0) ? TRUE : FALSE;
}/* 返回 L 中数据元素个数 */
int ListLength(SLinkList L)
{int length = 0;int i = L[MAX_SIZE - 1].curr;while (i) {i = L[i].curr;++length;}return length;
}/* 用 e 返回 L 中第 i 个元素的值 */
Status GetElem(SLinkList L, int i, ElemType *e)
{CHECK_VALUE(((i < 1) || (i > ListLength(L))), ERR_PARA)int head = MAX_SIZE - 1;for (int j = 0; j < i; ++j) {head = L[head].curr;}*e = L[head].data;return RET_OK;
}/* 算法 2.13, 在静态单链线性表 L 中查找第 1 个值为 e 的元素。若找到,则返回它在 L 中的位序,否则返回 0 */
int LocateElem(SLinkList L, ElemType e)
{int i = L[MAX_SIZE - 1].curr;while ((i) && (L[i].data != e)) {i = L[i].curr;}return i;
}/* 初始条件:线性表 L 已存在操作结果:若 curr_e 是 L 的数据元素,且不是第一个,则用 pre_e返回它的前驱否则操作失败,pre_e 无定义 */
Status PriorElem(SLinkList L, ElemType curr_e, ElemType *pre_e)
{int i = L[MAX_SIZE - 1].curr;int j;do {j = i;i = L[i].curr;} while ((i) && (L[i].data != curr_e));if (i) {*pre_e = L[j].data;return RET_OK;}printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NOT_FOUND);return ERR_NOT_FOUND;
}/* 初始条件:线性表 L 已存在操作结果:若 curr_e 是 L 的数据元素,且不是最后一个,则用 next_e 返回它的后继, 否则操作失败,next_e 无定义 */
Status NextElem(SLinkList L, ElemType curr_e, ElemType *next_e)
{int i = LocateElem(L, curr_e);int j;if (i) {j = L[i].curr;if (j) {*next_e = L[j].data;return RET_OK;}}printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NOT_FOUND);return ERR_NOT_FOUND;
}/* 在 L 中第 i 个元素之前插入新的数据元素 e */
Status ListInsert(SLinkList L, int i, ElemType e)
{CHECK_VALUE((i < 1) || i > ListLength(L) + 1, ERR_PARA)int j = Malloc(L);CHECK_VALUE(!j, ERR_MEMORY_ALLOCATE)L[j].data = e;int head = MAX_SIZE - 1;for (int k = 0; k < i - 1; ++k) {head = L[head].curr;}L[j].curr = L[head].curr;L[head].curr = j;return RET_OK;
}/* 删除在 L 中第 i 个数据元素 e,并返回其值 */
Status ListDelete(SLinkList L, int i, ElemType *e)
{CHECK_VALUE((i < 1) || i > ListLength(L), ERR_PARA)int head = MAX_SIZE - 1;int j;for (j = 0; j < i - 1; ++j) {head = L[head].curr;}j = L[head].curr;L[head].curr = L[j].curr;*e = L[j].data;Free(L, j);return RET_OK;
}/* 初始条件: 线性表 L 已存在操作结果: 依次对 L 的每个数据元素调用函数 vi()。一旦 vi() 失败, 则操作失败 */
Status ListTraverse(SLinkList L, void(*vi)(ElemType))
{int i = L[MAX_SIZE - 1].curr;while (i) {vi(L[i].data);i = L[i].curr;}return RET_OK;
}

4) main.c

#include "staticLinkListSingle.h"
#include <stdio.h>void Visit(ElemType e);int main(void)
{SLinkList L;InitList(L);for (int i = 0; i < 5; ++i) {ListInsert(L, 1, i + 1);}printf("After insert 1 ~ 5 in head of L, L is: ");ListTraverse(L, Visit);putchar('\n');printf("L is %s, the length of L is %d\n", ((ListEmpty(L) == TRUE) ? "empty" : "not empty"),ListLength(L));ClearList(L);printf("After clear L, L is: ");ListTraverse(L, Visit);putchar('\n');printf("L is %s, the length of L is %d\n", ((ListEmpty(L) == TRUE) ? "empty" : "not empty"),ListLength(L));for (int i = 0; i < 10; ++i) {ListInsert(L, i + 1, i + 1);}printf("After insert 1 ~ 10 in tail of L, L is: ");ListTraverse(L, Visit);putchar('\n');ElemType e;GetElem(L, 5, &e);printf("The %dth element of L is %d\n", 5, e);for (int i = 0; i < 2; ++i) {int pos = LocateElem(L, i);if (pos) {printf("The order of element %d in L is %d\n", i, pos);} else {printf("Element %d is not exist in L\n", i);}}for (int i = 1; i < 3; ++i) {ElemType e, prior;GetElem(L, i, &e);Status ret = PriorElem(L, e, &prior);if (ret == RET_OK) {printf("The previous element of %d is %d\n", e, prior);} else {printf("The previous element of %d is not exist.\n", e);}}for (int i = ListLength(L) - 1; i <= ListLength(L); ++i) {ElemType e, next;GetElem(L, i, &e);Status ret = NextElem(L, e, &next);if (ret == RET_OK) {printf("The next element of %d is %d\n", e, next);} else {printf("The next element of %d is not exist.\n", e);}}int length = ListLength(L);for (int i = length + 1; i >= length; --i) {ElemType e;Status ret = ListDelete(L, i, &e);if (ret == RET_OK) {printf("The element deleted is %d\n", e);} else {printf("Delete %dth element failed!\n", i);}}printf("Now, the element in L is: ");ListTraverse(L, Visit);putchar('\n');DestroyList();return 0;
}void Visit(ElemType e)
{printf("%d ", e);
}

3. 运行示例

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

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

相关文章

Java网络编程( 一 )数据如何在网络上传输

数据如何在网络上传输 网络发展背景发送端和接收端网络协议分层封装 & 分用封装&#xff1a;分用&#xff1a; 传输补充&#xff08;数据链路层&#xff08;以太网&#xff09;&#xff09;&#xff1a;ARP协议 网络发展背景 单机阶段—>局域网阶段—>广域网阶段—&…

【区块链】DeFi是什么?大白话科普文

对于一些没有玩过区块链、或者说没有真金白银的体验过这个虚拟世界的小伙伴来说,这篇文章可以帮你了解 DeFi。致力于帮你在这个线上走出这一步。 当然这不是理财建议。 文章目录 前言什么是去中心化金融?有哪些 DeFi 项目DeFi由哪几部分构成?热门DeFi项目有哪些?前言 Def…

tomcat安装、部署JSPGOU项目、Tomcat多实例

安装 官网找包 Apache Tomcat - Welcome! tomcat 8 准备运行环境 安装tomcat catalina.sh 服务脚本管理文件 server.xml 主配置文件 修改8009&#xff08;删除注释&#xff09; 启动tomcat 访问 为了避免每次进入绝对路径启动tomcat 法二&#xff1a; 三&#xff1a;部署…

Docker 的分层文件系统

1 分层文件系统 UnionFS 联合文件系统 bootfs&#xff1a;boot file systemrootfs&#xff1a;root file system 分层文件系统 Docker镜像都是只读的&#xff0c;当容器启动时&#xff0c;一个新的可写层被加到镜像的顶部&#xff0c;这一层就是我们通常说的容器层&#xf…

手写Spring:第11章-容器事件和事件监听器

文章目录 一、目标&#xff1a;容器事件和事件监听器二、设计&#xff1a;容器事件和事件监听器三、实现&#xff1a;容器事件和事件监听器3.1 工程结构3.2 容器事件和事件监听器类图3.3 定义和实现事件3.3.1 定义事件抽象类3.3.2 定义应用上下文事件实现类3.3.3 上下文刷新事件…

汇川PLC学习Day1:跑马灯程序编写

汇川PLC学习Day1&#xff1a;跑马灯程序编写 一、 软件安装 进入官网下载软件 二、 使用帮助 三、 新建工程与功能代码实现 CtrlN 寻找内带输出模块的CPU并设置好工程名字与保存路径&#xff0c;语言选择想熟悉的类型 工程建立后&#xff0c;PLC_PRG即为用户编写程序文件…

如何优化网站SEO(提高排名和流量的3个小知识)

百度百科SEO简介&#xff1a;搜索引擎优化&#xff08;SearchEngineOptimization&#xff09;是指通过对网站内部结构、外部链接以及页面内容等进行调整&#xff0c;从而使其在搜索引擎中排名更靠前&#xff0c;从而带来更多的流量和曝光。SEO是数字营销中的重要一环&#xff0…

合并区间【贪心算法】

合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 class Solution {public int[][] merge(int[…

TCP Header都有啥?

分析&回答 源端口号&#xff08;Source Port&#xff09; &#xff1a;16位&#xff0c;标识主机上发起传送的应用程序&#xff1b; 目的端口&#xff08;Destonation Port&#xff09; &#xff1a;16位&#xff0c;标识主机上传送要到达的应用程序。 源端&#xff0c;目…

安全测试 —— 你了解WEB安全测试吗?

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

Docker镜像解析获取Dockerfile文件

01、概述 当涉及到容器镜像的安全时&#xff0c;特别是在出现镜像投毒引发的安全事件时&#xff0c;追溯镜像的来源和解析Dockerfile文件是应急事件处理的关键步骤。在这篇博客中&#xff0c;我们将探讨如何从镜像解析获取Dockerfile文件&#xff0c;这对容器安全至关重要。 02…

【数学建模】2023数学建模国赛C题完整思路和代码解析

C题第一问代码和求解结果已完成&#xff0c;第一问数据量有点大&#xff0c;经过编程整理出来了单品销售额的汇总数据、将附件2中的单品编码替换为分类编码&#xff0c;整理出了蔬菜各品类随着时间变化的销售量&#xff0c;并做出了这些疏菜品类的皮尔森相关系数的热力图&#…

全球城市汇总【最新】

文章目录 案例图国家城市大洲 数据获取政策&#xff1a; 全球城市、国家、介绍汇总。包含 .csv .sql .xml 格式数据。 案例图 国家 城市 大洲 数据 获取上图资源绑定 https://blog.csdn.net/qq_40374604/category_12435042.html 获取政策&#xff1a; 如找不到在合集中查找…

PPT架构师架构技能图

PPT架构师架构技能图 目录概述需求&#xff1a; 设计思路实现思路分析1.软素质2.核心输出&#xff08;office输出&#xff09; 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,ma…

printf scanf

目录 printf scanf printf 把十的二进制代码放进去了&#xff0c;i对的是二进制代码&#xff0c;指定这一串0101代码以什么样的格式输出。 为什么要输出控制符&#xff0c;因为里面放的是二进制&#xff0c;必须控制输出的格式&#xff0c;指定这一串二进制以什么样的格式输出…

跨境电商产业链,服务商的“霸道”你见识过吗?(测评补单)

跨境电商行业的服务商众多&#xff0c;涉及到从前期培训和店铺注册准备到中期选品软件、营销服务、流量投放和支付等多个环节。然而&#xff0c;行业乱象也日益严重&#xff0c;出现了一些不良现象&#xff0c;如恶意竞争、高价要求、割韭菜等。 卖家在选择服务商时应谨慎&…

ZFS了解

存储数据的管理通常涉及两个方面:对一个或多个块存储设备(如硬盘驱动器和SD卡)进行物理卷管理&#xff0c;并将它们组织成操作系统所看到的逻辑块设备(通常涉及卷管理器、RAID控制器、阵列管理器或合适的设备驱动程序)&#xff0c;以及对存储在这些逻辑块设备(文件系统或其他数…

SpringBoot 统一功能处理

目录 一、用户登录权限验证 1.1 SpringAOP可以进行处理吗&#xff1f; 1.2 创建自定义拦截器 1.3 将自定义拦截器配置到系统配置项中 1.4 拦截器的实现原理 1.4.1 实现原理源码分析 1.5 统一访问前缀添加 二、统一异常处理 2.1 为什么需要使用统一异常处理&#xff1f;…

基于antd+vue2来实现一个简单的绘画流程图功能

简单流程图的实现&#xff08;基于antdvue2的&#xff09;代码很多哦~ 实现页面如下 1.简单操作如下 2.弹框中使用组件&#xff1a; <vfdref"vfd"style"background-color: white;":needShow"true":fieldNames"fieldNames"openUse…

day-04 基于UDP的服务器端/客户端

一.理解UDP &#xff08;一&#xff09;UDP套接字的特点 UDP套接字具有以下特点&#xff1a; 无连接性&#xff1a;UDP是一种无连接的协议&#xff0c;这意味着在发送数据之前&#xff0c;不需要在发送方和接收方之间建立连接。每个UDP数据包都是独立的&#xff0c;它们可以独…