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

目录

参考材料、格式

头文件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;}elseprintf(":");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相当于尾指针}//forspace[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;}//whileif (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;}//ifelse {//该元素已在表中,删除之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相当于尾指针}//forspace[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;}//whileif (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;}//ifelse {//该元素已在表中,删除之space[p].cur = space[k].cur;Free_SL(space, k);if (r == k)r = p;//若删除的是r所指结点,则需修改尾指针}//else}//for
}//differencevoid PrintSLinkList(SLinkList L, int S) {//打印已用链表,改编自算法2.13,定位查找。//实例与图2.11相同,结果也一样,可以课本代码一起看。printf("集合元素");int i = L[S].cur;if (i == 0){printf("为空。\n");return;}elseprintf(":");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.mzph.cn/news/649389.shtml

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

相关文章

找不到msvcp110.dll怎么办,msvcp110.dll丢失修复方法分享

当计算机系统中无法找到msvcp110.dll这个特定的动态链接库文件时&#xff0c;可能会引发一系列运行问题和功能受限的情况。msvcp110.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;对于许多基于Windows的应用程序来说&#xff0c;它是至关重要的运行组件…

vue模拟聊天页面列表:滚动到底部,滚动到顶部触发加载更多

先看下效果&#xff1a; 代码&#xff1a; <template><div><div style"text-align: center"><button click"scrollTop">滚动到顶部</button><button click"scrollBottom">滚动到底部</button></d…

Vue深入学习2—虚拟DOM和Diff算法

1、snabbdom 是什么&#xff1f; snabbdom是“速度"的意思&#xff0c;源码只有200行&#xff0c;使用TS写的&#xff0c;让东西变得模块化 2、snabbdom 的 h 函数如何工作&#xff1f; h函数用于产生虚拟节点&#xff0c;同时也可以嵌套使用&#xff0c;得到虚拟DOM树&am…

kuberneters可视化界面-kuboard

一、kuboard安装 可以选用&#xff0c;docker和docker-commpose kuberneters 安装 kuboard官网 1、 docker安装 sudo docker run -d \--restartunless-stopped \--namekuboard \-p 80:80/tcp \-p 10081:10081/tcp \-e KUBOARD_ENDPOINT"http://192.168.1.10:80" …

linux的kali安装,换源,更新包

下载kali kali.org进入官网后点第二个 然后点第一个 解压kali 下载后获得.7z压缩包&#xff0c;建议移动到合适自己电脑的位置进行解压&#xff0c;我喜欢放在D盘 启动kali 双击进入解压出的文件夹&#xff0c;将唯一一个.vmx文件用vmware打开&#xff08;没装的自行提前装…

数据结构奇妙旅程之二叉树题型解法总结

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

【深度学习】CodeFormer训练过程,如何训练人脸修复模型CodeFormer

文章目录 BasicSR介绍环境数据阶段 I - VQGAN阶段 II - CodeFormer (w0)阶段 III - CodeFormer (w1) 代码地址&#xff1a;https://github.com/sczhou/CodeFormer/releases/tag/v0.1.0 论文的一些简略介绍&#xff1a; https://qq742971636.blog.csdn.net/article/details/134…

链路追踪-调用链跟踪-Jaeger

文章目录 一、什么是链路跟踪二、OpenCensusOpenCensus 主要特点OpenTracing标准基本概念Span 三、典型服务端产品什么是OpenTracing?opentracing 使用介绍 四、JaegerJaeger 包含的模块Jaeger-client&#xff08;客户端库&#xff09; 五、Jaeger服务容器化部署过程问题整理 …

csdn黑色背景用法

在edge浏览器下&#xff0c;下载油猴脚本管理器 脚本下载 edge扩展 效果图如下&#xff1a;&#xff1a;&#xff1a;

[ACM学习] 进制转换

进制的本质 本质是每一位的数位上的数字乘上这一位的权重 将任意进制转换为十进制 原来还很疑惑为什么从高位开始&#xff0c;原来从高位开始的&#xff0c;可以被滚动地乘很多遍。 将十进制转换为任意进制

适合深夜发朋友圈的心灵鸡汤(整理70句)

1、很多时候&#xff0c;我们赢得了口舌&#xff0c;却失去了感情。 2、失恋到极致的时候&#xff0c;我真的会用后退来保护自己。 3、全身心地去爱&#xff0c;你可能会受到伤害&#xff0c;但这是完整人生的唯一方式。 4、自由不是想干什么就干什么&#xff0c;而是不想干…

Linux中LVM实验

LVM实验&#xff1a; 1、分区 -L是大小的意思-n名称的意思 从vg0&#xff08;卷组&#xff09;分出来 2、格式化LV逻辑卷 LVM扩容 如果icdir空间不够了&#xff0c; 扩展空间lvextend -L 5G /dev/vg0/lv1 /dev/vg0/lv1(pp,vg,lv) 刷新文件系统xfs_growfs /lvdir VG扩容 …

php:规范小数位数,例:10.00展示为10,10.98展示为10.98

代码 <?php$value 10.98; // 原始的双精度类型值if ($value floor($value)) {$formattedValue number_format($value, 0); // 10.00 转换为 10echo $formattedValue;} else {$formattedValue number_format($value, 2); // 10.98 保持为 10.98echo $formattedValue;} …

Sublime Text 3配置 Java 开发环境

《开发工具系列》 《开发语言-Java》 Sublime Text 3配置 Java 开发环境 一、引言二、主要内容1. 初识 Sublime Text 32. 初识 Java3. 接入 Java3.1 JDK 下载3.2 安装和使用 java3.3 环境变量配置 4. 配置 Java 开发环境5. 编写 Java 代码6. 编译和运行 Java 代码7. 乱码问题 三…

服务器无法访问外网怎么办

目前是互联网时代&#xff0c;网络已经成为人们日常生活中不可或缺的一部分。我们通过网络获取信息、进行沟通、甚至进行工作&#xff0c;因此&#xff0c;保持网络的稳定和通畅是非常重要的。然而&#xff0c;有时候我们可能会遇到一些网络无法访问外网的问题&#xff0c;这给…

作者推荐 | 【深入浅出MySQL】「底层原理」探秘缓冲池的核心奥秘,揭示终极洞察

探秘缓冲池的核心奥秘&#xff0c;揭示终极洞察 缓存池BufferPool机制MySQL缓冲池缓冲池缓冲池的问题 缓冲池的原理数据预读程序的局部性原则&#xff08;集中读写原理&#xff09;时间局部性空间局部性 innodb的数据页查询InnoDB的数据页InnoDB缓冲池缓存数据页InnoDB缓存数据…

[DIOR | DIOR-R]旋转目标检测数据集——基于YOLOv8obb,map50已达81.8%

DIOR是一个用于光学遥感图像目标检测的大规模基准数据集。涵盖20个对象类。这20个对象类是飞机、机场、棒球场、篮球场、桥梁、烟囱、水坝、高速公路服务区、高速公路收费站、港口、高尔夫球场、地面田径场、天桥、船舶、体育场、储罐、网球场、火车站、车辆和风磨。 1. DIOR简…

常见の算法链表问题

时间复杂度 1.链表逆序 package class04;import java.util.ArrayList; import java.util.List;public class Code01_ReverseList {public static class Node {public int value;public Node next;public Node(int data) {value data;}}public static class DoubleNode {publi…

Java 字符串 05 练习-遍历字符串和统计字符个数

代码&#xff1a; import java.util.Scanner; public class practice{public static void main(String[] args) {//键盘录入一个字符串&#xff0c;并进行遍历&#xff1b;Scanner input new Scanner(System.in);System.out.println("输入一个字符串&#xff1a;")…

webassembly003 whisper.cpp的main项目-1

参数设置 /home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug/bin/main options:-h, --help [default] show this help message and exit-t N, --threads N [4 ] number of threads to use during computation-p N, --processors …