上机实验二 设计单循环链表 西安石油大学数据结构

实验名称:设计单循环链表

(1)实验目的:掌握线性表的链式存储结构;掌握单循环链表及其基本操作的实现。

(2)主要内容:实现单循环链表的初始化、求数据元素个数、插入、删除、取数据元素等操作;用插入法建立带头结点的单循环链表;设计一个测试主函数验证所设计单循环链表的正确性。

1.实验目的

掌握线性表的链式存储结构;掌握单循环链表及其基本操作的实现。

2.问题描述

利用C语言设计实现单循环链表,并实现初始化、求数据元素个数、插入、删除、取数据元素等基本操作。使用插入法建立带头结点的单循环链表,并设计一个测试主函数验证所设计单循环链表的正确性。

3.基本要求

具体要求如下:

  1. 设计一个结构体表示链表的节点,包括数据域和指针域。

  2. 实现单循环链表的初始化操作,即创建一个空链表。

  3. 实现求数据元素个数的操作,即统计链表中已有的节点数。

  4. 实现插入操作,在指定位置插入一个节点,并将新节点链接到链表中。

  5. 实现删除操作,删除指定位置的节点。

  6. 实现取数据元素的操作,返回指定位置的节点值。

  7. 使用插入法建立带头结点的单循环链表,即通过用户输入逐个插入节点来创建链表,直到用户结束输入。

  8. 编写一个测试主函数,验证所设计单循环链表的正确性,包括对各个操作的测试。测试包括但不限于以下内容:创建一个空链表并输出链表元素个数。
    插入若干节点,并验证插入后链表的正确性。
    删除某个位置的节点,并验证删除后链表的正确性。
    取某个位置的节点值,并输出验证结果。

4.测试数据

初始链表为空,链表元素个数为:0

插入后的链表元素:10

插入后的链表元素:5 15 10 20

删除后的链表元素:15 20

取节点值的结果:

Position 0: 15

Position 1: 20

Position 2: -1

5.算法思想

链表数据结构的基本操作,包括初始化链表、获取链表元素个数、在指定位置插入节点、删除指定位置的节点、获取指定位置节点的值以及打印链表中的元素。其中,链表是一种线性结构,每个节点包括数据和指向下一个节点的指针,头结点不包含数据。

该算法通过遍历链表的方式来找到指定位置的节点,然后进行相应的操作。具体实现方法包括:在空链表中插入第一个节点时,直接将头结点指向新节点;在链表头部插入节点时,将新节点的指针指向原头结点,再将头结点指向新节点;在链表中间和尾部插入节点时,在找到插入位置的前一个节点后,将新节点的指针指向原位置的节点,再将前一个节点的指针指向新节点;删除节点时,首先找到要删除节点的前一个节点,将前一个节点的指针指向要删除节点的下一个节点,然后释放要删除节点的内存空间;获取节点值时,找到指定位置的节点,返回其数据域的值。

6.模块划分

  1. initList():初始化链表,返回头结点。
  2. listLength(Node* head):获取链表的元素个数。
  3. insertNode(Node* head, int position, int data):在链表指定位置插入节点。
  4. deleteNode(Node* head, int position):删除链表指定位置的节点。
  5. getNodeData(Node* head, int position):获取链表指定位置节点的值。
  6. printList(Node* head):打印链表中的元素。
  7. main():主函数。

7.数据结构

(1) 数据类型DataType定义如下:

typedef struct {int number;int cipher;
} DataType;

这个定义表示DataType结构体包含两个成员变量,即numbercipher,分别表示一个整数的数字和位数。

(2) 带头结点单循环链表结点的结构体定义如下:

typedef struct SCLNode {DataType data;struct SCLNode* next;
} SCLNode;

这个定义表示SCLNode结构体是一个带头结点的单循环链表的节点,包含两个成员变量。其中,data是存储数据元素的DataType类型的变量。next是指向下一个节点的指针,类型为指向SCLNode结构体的指针。

通过这样的定义,可以创建一个带头结点的单循环链表,每个节点存储一个数据元素,并且通过next指针连接起来形成循环链表。头结点的作用是指示链表的起始位置,尾节点的next指针指向头结点,形成循环。

8.源程序

#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node* next;
} Node;// 初始化链表,返回头结点
Node* initList() {Node* head = (Node*)malloc(sizeof(Node));head->next = NULL;  // 初始化时头结点指向NULL,形成空链表return head;
}// 获取链表的元素个数
int listLength(Node* head) {int count = 0;Node* current = head->next;while (current != NULL) {count++;current = current->next;}return count;
}// 在链表指定位置插入节点
void insertNode(Node* head, int position, int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;Node* current = head;int count = 0;while (current != NULL && count < position) {current = current->next;count++;}newNode->next = current->next;current->next = newNode;
}// 删除链表指定位置的节点
void deleteNode(Node* head, int position) {Node* current = head;int count = 0;while (current->next != NULL && count < position) {current = current->next;count++;}if (current->next != NULL) {Node* temp = current->next;current->next = temp->next;free(temp);}
}// 获取链表指定位置节点的值
int getNodeData(Node* head, int position) {Node* current = head->next;int count = 0;while (current != NULL && count < position) {current = current->next;count++;}if (current != NULL)return current->data;elsereturn -1;  // 返回-1表示节点不存在
}// 打印链表中的元素
void printList(Node* head) {Node* current = head->next;while (current != NULL) {printf("%d ", current->data);current = current->next;}printf("\n");
}int main() {Node* head = initList();printf("初始链表为空,链表元素个数为:%d\n", listLength(head));insertNode(head, 0, 10);  // 在空链表中插入第一个节点printf("插入后的链表元素:");printList(head);insertNode(head, 0, 5);  // 在链表头部插入节点insertNode(head, 1, 15); // 在链表中间插入节点insertNode(head, 3, 20); // 在链表尾部插入节点printf("插入后的链表元素:");printList(head);deleteNode(head, 0); // 删除头结点deleteNode(head, 1); // 删除链表中的某个节点deleteNode(head, 2); // 删除尾节点printf("删除后的链表元素:");printList(head);int data1 = getNodeData(head, 0); // 取链表头结点的数据int data2 = getNodeData(head, 1); // 取链表中间某个节点的数据int data3 = getNodeData(head, 2); // 取链表尾节点的数据printf("取节点值的结果:\n");printf("Position 0: %d\n", data1);printf("Position 1: %d\n", data2);printf("Position 2: %d\n", data3);return 0;
}

9.测试情况

在这里插入图片描述

进行测试结果分析

初始化链表后,链表为空,元素个数为0。

在空链表中插入第一个节点,插入后的链表元素为10。可以看到插入操作正常。

在链表头部插入节点5,链表中间插入节点15,链表尾部插入节点20。插入后的链表元素为5 15 10 20。可以看到在不同位置插入节点的操作正常。

删除头结点,删除链表中的某个节点,删除尾节点。删除后的链表元素为5 10。可以看到删除操作正常。

取链表头结点的数据,取链表中间某个节点的数据,取链表尾节点的数据。取节点值的结果如下:

Position 0: 5
Position 1: 10
Position 2: -1
可以看到,成功获取了节点的值,并且当位置越界时返回了-1。说明获取节点值的功能正常。

综上所述,根据测试结果,代码实现了链表的基本操作,并且功能正常。

描述存在的问题及建议

存在的问题是在插入和删除节点时没有进行越界检查,可能导致访问非法内存。建议在插入和删除节点的代码中增加对位置的合法性检查,确保不会越界。

另外,代码中的打印函数printList()可以优化,避免每次都要遍历整个链表才能打印出结果。可以考虑在插入、删除和修改节点时维护链表的长度,并在需要打印时直接使用链表长度进行循环打印。这样可以提高效率。

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

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

相关文章

hadoop组成

在hadoop1.x时代,Hadoop中的MapReduce同时处理业务逻辑运算和资源调度,耦合性较大; 在hadoop2.x时代,新增了yarn,主要负责资源的调度,MapReduce仅负责运算; 在hadoop3.x时代,在组成上没有变化;

2023-10-14 LeetCode每日一题(只出现一次的数字)

2023-10-14每日一题 一、题目编号 136. 只出现一次的数字二、题目链接 点击跳转到题目位置 三、题目描述 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时…

支付宝开放平台第三方代小程序开发,消息服务推送通知总结

大家好&#xff0c;我是小悟 关于支付宝开放平台第三方代小程序开发的消息服务推送通知&#xff0c;是开放平台代小程序实现业务的重要功能。 消息服务推送通知&#xff0c;支持商家两种通讯协议来接收消息&#xff0c;分别为websocket 长连接和http。 关于websocket方式&am…

苍穹外卖(八) 使用WebSocket协议完成来单提醒及客户催单功能

WebSocket介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信(双向传输)——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c; 并进行双向数据传输。 HTTP协议和WebSocket协议对比&#xff1a; HTTP…

ChatGPT角色扮演教程,Prompt词分享

使用指南 1、可直复制使用 2、可以前往已经添加好Prompt预设的AI系统测试使用 https://ai.idcyli.comhttps://ai.idcyli.com 雅思写作考官 我希望你假定自己是雅思写作考官&#xff0c;根据雅思评判标准&#xff0c;按我给你的雅思考题和对应答案给我评分&#xff0c;并且按…

DirectX绘制流水线

使用DirectX可以让在Windows平台上运行的游戏或多媒体程序获得更高的执行效率&#xff0c;掌握DirectX的基本概念和技术是虚拟现实技术、计算机仿真和3D游戏程序开发的基础。 DirectX概述 DirectX是微软的一个多媒体应用编程接口(API)工具包&#xff0c;用于为Windows操作系统…

EfficientDet: Scalable and Efficient Object Detection

CVPR2020 V7 Mon, 27 Jul 2020 引用量&#xff1a;243 机构&#xff1a;Google 贡献&#xff1a;1>提出了多尺度融合网络BiFPN 2>对backbone、feature network、box/class prediction network and resolution进行复合放缩&#xff0c;有着不同的…

在 VSCode 中使用 PlantUML

最近&#xff0c;因为工作需要绘制一些逻辑图&#xff0c;我自己现在使用的是 PlantUML 或者 mermaid&#xff0c;相比之下前者更加强大。不过它的环境也麻烦一些&#xff0c;mermaid 在一些软件上已经内置了。但是 PlantUML 一般需要自己本地安装或者使用远程服务器&#xff0…

Unity中Shader不同灯光类型的支持与区分

文章目录 前言一、在开始之前做一些准备1、在上一篇文章的场景基础上&#xff0c;增加一个Unity默认的球体作为对照组2、创建一个点光源&#xff0c;用来看点光源的影响 对 Unity默认的Shader效果 和 我们实现的Shader效果 之间的不同 二、点光源的适配把上一篇文章中 ForwardB…

R语言的计量经济学实践技术应用

计量经济学通常使用较小样本&#xff0c;但这种区别日渐模糊&#xff0c;机器学习在经济学领域、特别是经济学与其它学科的交叉领域表现日益突出&#xff0c;R语言是用于统计建模的主流计算机语言&#xff0c;在本次培训中&#xff0c;我们将从实际应用出发&#xff0c;重点从数…

【arm实验2】按键中断事件控制实验

设置按键中断&#xff0c;按键1按下&#xff0c;LED亮&#xff0c;再次按下&#xff0c;灭 按键2按下&#xff0c;蜂鸣器叫&#xff0c;再次按下&#xff0c;停 按键3按下&#xff0c;风扇转&#xff0c;再次按下&#xff0c;停 主函数&#xff1a; linuxlinux:~/study/08-c$…

【基础篇】四、本地部署Flink

文章目录 1、本地独立部署会话模式的Flink2、本地独立部署会话模式的Flink集群3、向Flink集群提交作业4、Standalone方式部署单作业模式5、Standalone方式部署应用模式的Flink Flink的常见三种部署方式&#xff1a; 独立部署&#xff08;Standalone部署&#xff09;基于K8S部署…

使用Tortoisegit界面拉起master主分支以副分支以及命令行操作

文章目录 1、Gui操作界面2、命令行操作3、合并分支到master分支上面 1、Gui操作界面 "小乌龟"通常指的是Git的图形用户界面&#xff08;GUI&#xff09;工具&#xff0c;其中比较常见的是TortoiseGit。下面是使用TortoiseGit来拉取&#xff08;checkout&#xff09;一…

数据结构(一)—— 数据结构简介

文章目录 一、基本概念和术语&#xff1f;1.1、数据1.2、数据元素1.3、数据项&#xff08;属性、字段&#xff09;1.4、数据对象1.5、数据结构 二、逻辑结构和物理结构&#xff08;存储结构&#xff09;2.1、逻辑结构1、定义2、分类&#xff08;线性结构和非线性结构&#xff0…

Netty 入门 — 亘古不变的Hello World

这篇文章我们正式开始学习 Netty&#xff0c;在入门之前我们还是需要了解什么是 Netty。 什么是 Netty 为什么很多人都推崇 Java boy 去研究 Netty&#xff1f;Netty 这么高大上&#xff0c;它到底是何方神圣&#xff1f; 用官方的话说&#xff1a;Netty 是一款异步的、基于事…

vue绑定style和class 对象写法

适用于&#xff1a;要绑定多个样式&#xff0c;个数确定&#xff0c;名字也确定&#xff0c;但不确定用不用。 绑定 class 样式【对象写法】&#xff1a; .box{width: 100px;height: 100px; } .aqua{background-color: aqua; } .border{border: 20px solid red; } .radius{bor…

【动态库】Ubuntu 添加动态库的搜索路径

在运行程序时&#xff0c;经常遇到下面这种动态库加载失败的情况&#xff0c;这时往往是系统在动态库的搜索路径下没有找到对应的库文件导致的。 目录 一、使用 LD_LIBRARY_PATH 二、修改 /etc/ld.so.conf 一、使用 LD_LIBRARY_PATH 环境变量 LD_LIBRARY_PATH是动态库的搜索…

Jenkins集成newman

一、Docker环境准备 二、Jenkins环境准备 三、登录Jenkins 安装NodeJs插件 四、Jenkins全局工具配置Nodejs 五、创建Jenkins自由风格项目 构建步骤1&#xff1a;选择Execute NodeJS script构建步骤2&#xff1a;选择执行shell脚本 六、将postman相关的脚本、环境变量数据、全局…

Java反射调用jar包

反射作为托管语言的特性&#xff0c;很多框架都依赖反射来实现容器和面向接口编程&#xff0c;对架构程序很重要&#xff0c;首先试验Java的反射部分。 首先创建一个ZLZJar的工程&#xff0c;让他打包成jar包&#xff0c;代码如下 public class Test {//加两个整数public int…

ELK 日志分析系统介绍与部署

目录 一、ELK 简介: 1.开源工具介绍&#xff1a; 2.其它组件&#xff1a; 2.1 Filebeat&#xff1a; 2.2 Fluentd&#xff1a; 2.3 缓存/消息队列&#xff08;redis、kafka、RabbitMQ等&#xff09;&#xff1a; 3. filebeat 结合 logstash 带来好处&#xff1a; 二、为什么要…