数据结构(C语言版)代码实现(四)——静态单链表的部分代码实现

news2024/10/2 1:30:20

目录

参考材料、格式

头文件SLinkList.h

库、宏定义、函数类型声明

线性表的静态单链表存储结构

按值查找

初始化静态链表

分配空间

回收空间

打印已用链表中的元素

求集合(A-B)U(B-A)中的元素(重点介绍)

调试过程

修改报错与警告

调试

完整版头文件代码

测试函数(主函数)

测试结果

总结


参考材料、格式

参考自数据结构C语言严蔚敏版,本博文即该课本伪代码的部分实现。

头文件SLinkList.h

库、宏定义、函数类型声明

#include <cstdio>
#include <cstdlib>
#include <cstring>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//Status是函数的类型,其值是函数结果状态代码
typedef char ElemType;

线性表的静态单链表存储结构

//-----线性表的静态单链表存储结构-----
#define MAXSIZE 1000//链表的最大长度
typedef struct {
	ElemType data;
	int cur;
}component,SLinkList[MAXSIZE];//SLinkList[0]为头指针

按值查找

//算法2.13 按值查找
int LocateElem_SL(SLinkList S, ElemType e) {
	//在静态单链线性表L中查找第1个值为e的元素。
	//若找到,则返回它在L中的位序,否则返回0。
	int i = S[0].cur;//i指示表中第一个结点
	while (i && S[i].data != e)
		i = S[i].cur;//在表中顺链查找
	return i;
}

初始化静态链表

//例2-3 算法2.14 初始化静态链表
void InitSpace_SL(SLinkList& space) {
	//将一维数组space中各分量链成一个备用链表,space[0].cur为头指针,
	//“0”表示空指针
	for (int i = 0;i < MAXSIZE - 1;++i)
		space[i].cur = i + 1;
	space[MAXSIZE - 1].cur = 0;
}

分配空间

//算法2.15 分配空间(分配备用空间到已用空间)
int Malloc_SL(SLinkList& space) {
	//若备用空间为空,则返回分配的结点下标,否则返回0
	//相当于删除备用链表的结点
	int i = space[0].cur;
	if (space[0].cur)
		space[0].cur = space[i].cur;
	return i;
}

回收空间

//算法2.16 回收空间
void Free_SL(SLinkList& space, int k) {
	//将下标为k的空闲结点回收到备用链表
	//相当于增加备用链表的结点
	space[k].cur = space[0].cur;
	space[0].cur = k;
}

打印已用链表中的元素

void PrintSLinkList(SLinkList L, int S) {
	//打印已用链表,改编自算法2.13,定位查找。
	//实例与图2.11相同,结果也一样,可以课本代码一起看。
	printf("集合元素");
	int i = L[S].cur;
	if (i == 0)
	{
		printf("为空。\n");
		return;
	}
	else
		printf(":");
	while (i != 0) {
		printf("%c ", L[i].data);
		i = L[i].cur;
	}
	printf("\n");
}

求集合(A-B)U(B-A)中的元素(重点介绍)

//算法2.17
//两套链表,一套备用链表,头指针为space;一套已用链表,头指针为space+S。
//两个链表的最后一个结点的cur的值均为0。
void difference(SLinkList& space, int& S) {
	//依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)U(B-A)
	//的静态链表,S为其头指针。假设备用空间足够大,space[0].cur为其头指针。
	InitSpace_SL(space);//初始化备用空间
	S = Malloc_SL(space);//生成S的头结点,S相当于头指针
	int r = S;//r指向S的当前最后结点
	int m, n;
	printf("请输入A和B的元素个数:");
	scanf_s("%d %d", &m, &n);//输入A和B的元素个数,两个%d之间有空格
	getchar();//吸收多余的回车键
	printf("输入集合A的元素:");
	for (int j = 1;j <= m;++j) {//建立集合A的链表
		int i = Malloc_SL(space);//分配结点
		scanf_s("%c", &space[i].data,1);//输入A的元素值
		getchar();
		space[r].cur = i;
		r = i;//插入到表尾,r相当于尾指针
	}//for
	space[r].cur = 0;//尾结点的指针为空
	printf("输入集合B的元素:");
	for (int j = 1;j <= n;++j) {//依次输入B的元素,若不在当前表中,则插入,否则删除
		int p,k;//两个指针,k在p的下一个结点
		char b;//存储集合B的元素
		scanf_s("%c", &b,1);
		getchar();//吸收多余的空格
		p = S;
		k = space[S].cur;//k指向集合A中第一个结点
		while (k != space[r].cur && space[k].data != b) {//在当前表中查找
			p = k;
			k = space[k].cur;
		}//while
		if (k == space[r].cur) {//当前表中不存在该元素,插入在r所指结点之后,且r的位置不变
			int i = Malloc_SL(space);
			space[i].data = b;
			space[i].cur = space[r].cur;
			space[r].cur = i;
		}//if
		else {//该元素已在表中,删除之
			space[p].cur = space[k].cur;
			Free_SL(space, k);
			if (r == k)r = p;//若删除的是r所指结点,则需修改尾指针
		}//else
	}//for
}//difference

调试过程

修改报错与警告

本来以为这次很顺利,但跑起来却陷入了死循环,我先看了看下面的警告,发现如下错误:C6064:缺少“scanf_s”的整型参数(对应于转换说明符“2”_缺少scanf_s的整型参数对应于2-CSDN博客%d对应的scanf_s没有警告,但%c对应的scanf_s有,于是我按照上述博文修改了自己的代码。

原警告代码

scanf_s("%c", &space[i].data);

修改后代码

scanf_s("%c", &space[i].data,1);

但事实是没什么用,于是我祭出了第二大法宝——调试。

调试

先告诉大家我错误的原因:

​
scanf_s("%d %d", &m, &n);//输入A和B的元素个数,两个%d之间有空格
//getchar();//吸收多余的回车键

​

应该这样:

scanf_s("%d %d", &m, &n);//输入A和B的元素个数,两个%d之间有空格
getchar();//吸收多余的回车键

因为多余的回车会变成space[2].data='\n',下面是截图。

这是第一次进入循环时的情况,可见space[2].data=10,对应ASCII码为‘\n’,说明回车键成了第一个输入元素。

事实上不只是上面的代码有错误,下面代码也有同样的错误。

原代码

scanf_s("%c", &space[i].data,1);//输入A的元素值
//getchar();//吸收多余的空格

修改后代码

scanf_s("%c", &space[i].data,1);//输入A的元素值
getchar();//吸收多余的空格

最终结果:

记得第一次是死循环的,没截图,这是现在的错误。问题在于代码没报错,但就是跑不对。

完整版头文件代码

#pragma once
#include <cstdio>
#include <cstdlib>
#include <cstring>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//Status是函数的类型,其值是函数结果状态代码
typedef char ElemType;

//-----线性表的静态单链表存储结构-----
#define MAXSIZE 1000//链表的最大长度
typedef struct {
	ElemType data;
	int cur;
}component,SLinkList[MAXSIZE];//SLinkList[0]为头指针

//算法2.13 按值查找
int LocateElem_SL(SLinkList S, ElemType e) {
	//在静态单链线性表L中查找第1个值为e的元素。
	//若找到,则返回它在L中的位序,否则返回0。
	int i = S[0].cur;//i指示表中第一个结点
	while (i && S[i].data != e)
		i = S[i].cur;//在表中顺链查找
	return i;
}

//例2-3 算法2.14 初始化静态链表
void InitSpace_SL(SLinkList& space) {
	//将一维数组space中各分量链成一个备用链表,space[0].cur为头指针,
	//“0”表示空指针
	for (int i = 0;i < MAXSIZE - 1;++i)
		space[i].cur = i + 1;
	space[MAXSIZE - 1].cur = 0;
}

//算法2.15 分配空间(分配备用空间到已用空间)
int Malloc_SL(SLinkList& space) {
	//若备用空间为空,则返回分配的结点下标,否则返回0
	//相当于删除备用链表的结点
	int i = space[0].cur;
	if (space[0].cur)
		space[0].cur = space[i].cur;
	return i;
}

//算法2.16 回收空间
void Free_SL(SLinkList& space, int k) {
	//将下标为k的空闲结点回收到备用链表
	//相当于增加备用链表的结点
	space[k].cur = space[0].cur;
	space[0].cur = k;
}

//算法2.17
//两套链表,一套备用链表,头指针为space;一套已用链表,头指针为space+S。
//两个链表的最后一个结点的cur的值均为0。
void difference(SLinkList& space, int& S) {
	//依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)U(B-A)
	//的静态链表,S为其头指针。假设备用空间足够大,space[0].cur为其头指针。
	InitSpace_SL(space);//初始化备用空间
	S = Malloc_SL(space);//生成S的头结点,S相当于头指针
	int r = S;//r指向S的当前最后结点
	int m, n;
	printf("请输入A和B的元素个数:");
	scanf_s("%d %d", &m, &n);//输入A和B的元素个数,两个%d之间有空格
	getchar();//吸收多余的回车键
	printf("输入集合A的元素:");
	for (int j = 1;j <= m;++j) {//建立集合A的链表
		int i = Malloc_SL(space);//分配结点
		scanf_s("%c", &space[i].data,1);//输入A的元素值
		getchar();//吸收多余的空格
		space[r].cur = i;
		r = i;//插入到表尾,r相当于尾指针
	}//for
	space[r].cur = 0;//尾结点的指针为空
	printf("输入集合B的元素:");
	for (int j = 1;j <= n;++j) {//依次输入B的元素,若不在当前表中,则插入,否则删除
		int p,k;//两个指针,k在p的下一个结点
		char b;//存储集合B的元素
		scanf_s("%c", &b,1);
		getchar();//吸收多余的空格
		p = S;
		k = space[S].cur;//k指向集合A中第一个结点
		while (k != space[r].cur && space[k].data != b) {//在当前表中查找
			p = k;
			k = space[k].cur;
		}//while
		if (k == space[r].cur) {//当前表中不存在该元素,插入在r所指结点之后,且r的位置不变
			int i = Malloc_SL(space);
			space[i].data = b;
			space[i].cur = space[r].cur;
			space[r].cur = i;
		}//if
		else {//该元素已在表中,删除之
			space[p].cur = space[k].cur;
			Free_SL(space, k);
			if (r == k)r = p;//若删除的是r所指结点,则需修改尾指针
		}//else
	}//for
}//difference

void PrintSLinkList(SLinkList L, int S) {
	//打印已用链表,改编自算法2.13,定位查找。
	//实例与图2.11相同,结果也一样,可以课本代码一起看。
	printf("集合元素");
	int i = L[S].cur;
	if (i == 0)
	{
		printf("为空。\n");
		return;
	}
	else
		printf(":");
	while (i != 0) {
		printf("%c ", L[i].data);
		i = L[i].cur;
	}
	printf("\n");
}

测试函数(主函数)

注:没有测试定位查找函数

#include "SLinkList.h"

int main()
{
	SLinkList L;//静态链表
	int S;//已用链表的头指针
	difference(L, S);
	PrintSLinkList(L, S);
	return 0;
}

测试结果

注:同课本34-35页测试数据,A=(c,b,e,g,f,d),B=(a,b,n,f)

符合预期。

总结

本来以为这一次很简单,但又败在没吃掉空格上了。这个问题,每一学期上课的老师都会提醒,但我总是记不住,或者说,之前只是见过,现在才是亲身经历到了。唉,为以前不好好写代码感到懊悔。

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

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

相关文章

何恺明 ResNet 引用量正式破20万!!!

注: 本文转自微信公众号 BravoAI (专注AI资讯和技术分享), 原文网址: 何恺明 ResNet 引用量正式破20万!!!, 扫码关注公众号 谷歌学术显示, 截止到 2024年1月26日, 何凯明 ResNet 一文引用量正式突破 20W!!! 更为惊人的是, 从论文发表到今天, 不过7年!!!‍‍‍‍‍‍‍‍‍‍‍‍…

6轴机器人运动正解-逆解控制【1】——三种控制位姿的方式

概览&#xff1a; 通过运动学正解控制机器人运动通过运动学逆解控制机器人运动一个简单的物体搬运&#xff08;沿轨迹运动&#xff09; 后续会陆续更新&#xff08;本例仅供学习交流用&#xff09; 一、6轴机器人 二、运动正解控制 通过修改各个轴的角度&#xff0c;实现末…

演示黄金票据,使用普通账户导入黄金票据创建域管理员

前提域搭建好了&#xff0c;域名是lin.com 首先我进入的是本机的用户不是域用户 我要是用本地用户&#xff0c;本地用户拿的票告诉我们这个TGS服务说我是域管账户administrator&#xff08;需要拿到域用户的哈希&#xff09; 此时进入到预控主机中&#xff08;人家是正儿八经…

Google Chrome RCE漏洞 CVE-2020-6507 和 CVE-2024-0517 流程分析

本文深入研究了两个在 Google Chrome 的 V8 JavaScript 引擎中发现的漏洞&#xff0c;分别是 CVE-2020-6507 和 CVE-2024-0517。这两个漏洞都涉及 V8 引擎的堆损坏问题&#xff0c;允许远程代码执行。通过EXP HTML部分的内存操作、垃圾回收等流程方式实施利用攻击。 CVE-2020-…

计算机网络 第6章(应用层)

系列文章目录 计算机网络 第1章&#xff08;概述&#xff09; 计算机网络 第2章&#xff08;物理层&#xff09; 计算机网络 第3章&#xff08;数据链路层&#xff09; 计算机网络 第4章&#xff08;网络层&#xff09; 计算机网络 第5章&#xff08;运输层&#xff09; 计算机…

MySQL十部曲之一:MySQL概述及手册说明

文章目录 数据库、数据库管理系统以及SQL之间的关系关系型数据库与非关系型数据库手册语法约定 数据库、数据库管理系统以及SQL之间的关系 名称说明数据库&#xff08;Database&#xff09;即存储数据的仓库&#xff0c;其本质是一个文件系统。它保存了一系列有组织的数据。数…

【第四天】蓝桥杯备战

题 1、求和2、天数3、最大缝隙 1、求和 https://www.lanqiao.cn/problems/1442/learning/ 解法&#xff1a;字符串方法的应用 import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scann…

xshell无法连接linux,查询本机ip时出现<NO-CARRIER,BROADCAST,MULTICAST,UP>

在用xshell连接虚拟机VMware中的linux时&#xff0c;发现昨天还能连通的&#xff0c;今天连接不了了 我寻思应该是网卡配置出问题了&#xff0c;就去终端ip addr试了一下&#xff0c;果然发现问题&#xff0c;ip 查看网卡ens33就发现出现ens33:<NO-CARRIER,BROADCAST,MULTI…

操作符详解(上)

目录 操作符的分类 二进制和进制转换 2进制转10进制 10进制转2进制数字 2进制转8进制 2进制转16进制 原码、反码、补码 移位操作符 左移操作符 右移操作符 位操作符&#xff1a;&、|、^、~ 单目操作符 逗号表达式 操作符的分类 • 算术操作符&#xff1a; …

无法获得dpkg前端锁、Linux之E: 无法锁定管理目录(/var/lib/dpkg/),是否有其他进程正占用它?(解决方法)

无法获得dpkg前端锁的解决方法 sudo rm /var/lib/dpkg/lock sudo rm /var/lib/dpkg/lock-frontend sudo rm /var/cache/apt/archives/lock 输入以上三个命令即可解除占用。解除后&#xff0c;继续运行apt命令&#xff0c;已经顺利运行了。解除前端锁后&#xff0c;Linux之E: 无…

自动写作软件有哪些?一次性分享5个好用软件

自动写作软件有哪些&#xff1f;随着科技的不断发展&#xff0c;自动写作软件逐渐进入了人们的视野。这些软件能够根据用户提供的关键词和主题&#xff0c;自动生成一篇完整的文章。这对于需要大量内容创作者来说&#xff0c;无疑是一个福音。下面介绍一些知名的自动写作软件&a…

鸿蒙开发实战-手写文心一言AI对话APP

运行环境 &#xff08;后面附有API9版本&#xff0c;可修改后在HarmonyOS4设备上运行&#xff09; DAYU200:4.0.10.16 SDK&#xff1a;4.0.10.15 IDE&#xff1a;4.0.600 在DAYU200:4.0.10.16上运行 一、创建应用 1.点击File->new File->Create Progect 2.选择模版…

D. Gargari and Permutations

很好玩的一道类似LCS的DP 问题 定义dp(i) 为考虑最后一个字符串&#xff0c;且选择a&#xff08;i&#xff09;得到的最大LIS值 然后枚举所有小于i的位置&#xff0c;可以更新的条件是 所有的字符串中都有a[j]<a[i] 这个用map一处理就好了 #include<bits/stdc.h> usi…

EasyCVR视频融合平台雪亮工程视频智能监控方案设计与应用

随着科技的不断发展&#xff0c;视频监控已经成为城市安全防范的重要手段之一。为了提高城市安全防范水平&#xff0c;各地纷纷开展“雪亮工程”&#xff0c;即利用视频智能监控技术&#xff0c;实现对城市各个角落的全方位、全天候监控。本文将介绍一种雪亮工程视频智能监控方…

机器人学论文——智能施药机器人调研报告

目录 摘 要 Abstract 第一章&#xff1a;引言 1.1研究背景 1.2 研究意义 1.3文章架构 第二章&#xff1a;智能施药机器人发展现状 2.1引言 2.2 大田智能施药机器人发展现状 2.3 果园智能施药机器人发展现状 2.4 设施农业智能施药机器人发展现状 第三章&#xff1a;智能施药机器…

PCL-IO输入输入模块

IO输入输入模块 一、概述二、点云数据格式1. PCD 格式2. PLY 格式3. OBJ 格式4. STL 格式5. OFF 格式 三、读取3D文件1. API 总览2. 示例 四、保存3D文件1. API 总览2. 示例 一、概述 PCL 库提供了一个模块用来对3D数据进行读写操作&#xff0c;这个库提供了一个模块&#xff…

sony ps3 eye 摄像头win10、win11directShow补丁驱动,补充CL5.3驱动无法外部程序调用问题

最近把几年前&#xff0c;淘的sony ps3 eye 摄像头拿出来测试&#xff0c;发现升值了。原来4个打算做动捕用&#xff0c;结果发现安装完CL-Eye-Driver-5.3.0.0341驱动后&#xff0c;无法用外部程序驱动摄像头&#xff0c;后来知乎里发现有人解决了这个为题&#xff0c;是win10下…

2982. 找出出现至少三次的最长特殊子字符串 II

字典树思路 用字典树搞一下就好了&#xff0c;比如aaaaa &#xff1a; a存5次 aa 4次以此类推&#xff5e; 字典树板子复习&#xff1a;P8306 【模板】字典树 这里这个清空方式 很好 因为很多时候memset T #include<iostream> #include<cstring> using namesp…

1. MySQL 数据库

本章内容 关系型数据库基础 安装 MySQL 管理数据库和表 用户和权限管理 函数&#xff0c;存储过程&#xff0c;触发器和事件 MySQL 架构 存储引擎 服务器选项&#xff0c;系统和状态变量 优化查询和索引管理 锁和事务管理 日志管理 备份还原 MySQL 集群 压力测试…

Tensorflow2.0笔记 - tensor排序操作

本笔记主要记录sort,argsort,以及top_k操作&#xff0c;加上一个求Top K准确度的例子。 import tensorflow as tf import numpy as nptf.__version__#sort,argsort#对1维的tensor进行排序 tensor tf.random.shuffle(tf.range(10)) print(tensor) #升序 print("tf.sort(d…