当前位置: 首页 > news >正文

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

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

(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()可以优化,避免每次都要遍历整个链表才能打印出结果。可以考虑在插入、删除和修改节点时维护链表的长度,并在需要打印时直接使用链表长度进行循环打印。这样可以提高效率。

相关文章:

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

实验名称:设计单循环链表 (1&#xff09;实验目的:掌握线性表的链式存储结构;掌握单循环链表及其基本操作的实现。 (2&#xff09;主要内容:实现单循环链表的初始化、求数据元素个数、插入、删除、取数据元素等操作;用插入法建立带头结点的单循环链表;设计一个测试主函数验证…...

小谈设计模式(28)—解释器模式

小谈设计模式&#xff08;28&#xff09;—解释器模式 专栏介绍专栏地址专栏介绍 解释器模式角色分析抽象表达式&#xff08;Abstract Expression&#xff09;终结符表达式&#xff08;Terminal Expression&#xff09;非终结符表达式&#xff08;Non-terminal Expression&…...

Access denied for user ‘root‘@‘xxx‘ (using password: YES)

Access denied for user rootxxx (using password: YES) 这表示MySQL服务端拒绝来自xxx主机的root用户登录&#xff0c;尽管我检查了一下&#xff0c;root的用户名和密码都没错&#xff0c;还是拒绝。 解决方案&#xff1a; select user,host from mysql.user; 执行发现&am…...

对象与成员函数指针 function+bind

functionbind的理解 function模板类的构造函数&#xff0c;把对象与成员函数绑定&#xff0c;重载了&#xff08;&#xff09;&#xff0c;利用对象调用成员函数 bind模板函数&#xff0c;把对象与成员函数绑定&#xff0c;返回function对象&#xff0c;成员函数传参代码链接点…...

如何在 PyTorch 中冻结模型权重以进行迁移学习:分步教程

一、说明 迁移学习是一种机器学习技术&#xff0c;其中预先训练的模型适用于新的但类似的问题。迁移学习的关键步骤之一是能够冻结预训练模型的层&#xff0c;以便在训练期间仅更新网络的某些部分。当您想要保留预训练模型已经学习的特征时&#xff0c;冻结至关重要。在本教程中…...

代码随想录算法训练营第六十二、六十三天 | 单调栈 part 2 | 503.下一个更大元素II 、42. 接雨水、84.柱状图中最大的矩形

目录 503.下一个更大元素II思路代码 42. 接雨水思路一 双指针思路二 单调栈代码 84.柱状图中最大的矩形思路一 双指针思路二 单调栈代码 503.下一个更大元素II Leetcode 思路 将数组乘2来遍历即可&#xff0c;就是加长版的每日温度。 但是处理起来会有细节&#xff0c;如果…...

c#设计模式-行为型模式 之 迭代器模式

&#x1f680;简介 提供一个对象来顺序访问聚合对象中的一系列数据&#xff0c;而不暴露聚合对象的内部表示。 迭代器模式主要包含以下角色&#xff1a; 抽象聚合&#xff08;Aggregate&#xff09;角色&#xff1a;定义存储、添加、删除聚合元素以及创建迭代器对象的接口…...

SSM整合RabbitMQ,Spring4.x整合RabbitMQ

SSM整合RabbitMQ目录 前言版本实现目录参考pom.xml依赖rabbitmq.properties配置文件spring-rabbitmq.xmlspring-mvc.xml或applicationContext.xmlrabbitmq目录下MessageConsumer.javaMessageConsumer2.javaMessageProducer.javaMessageConstant.java 测试调用 扩展消息重发方式…...

【2023研电赛】商业计划书赛道上海市一等奖:基于双矢量优化谐波预测控制的MMC-PET光伏储能系统

该作品参与极术社区组织的2023研电赛作品征集活动&#xff0c;欢迎同学们投稿&#xff0c;获取作品传播推广&#xff0c;并有丰富礼品哦~ 团队介绍 参赛单位&#xff1a;上海理工大学 参赛队伍&#xff1a;Dream explorers 参赛队员&#xff1a;吕哲 李天皓 赵安杰 项目意义…...

minio桶命名规则

一、背景 今天做项目需要上传图片到minio&#xff0c;上传失败&#xff0c;查看错误是桶未创建成功。 minio桶的创建具有自己的命名规则&#xff0c;不符合则无法创建。 二、命名规则 1、存储桶名称的长度必须介于 3&#xff08;最小&#xff09;到 63&#xff08;最大&…...

【教学类-35-04】学号+姓名+班级(中3班)学号字帖(A4竖版2份 竖版长条)

图片展示: 背景需求: 2022年9-2023年1月我去过小3班带班&#xff0c;但是没有在这个班级投放过学具&#xff0c;本周五是我在本学期第一次带中3班&#xff0c;所以提供了一套学号描字帖。先让我把孩子的名字和脸混个眼熟。 之前试过一页两套名字的纸张切割方法有&#xff1a;…...

什么叫AI自动直播?

AI自动直播是一种使用人工智能技术进行自动直播的程序或系统。 它可以自动录制视频&#xff0c;并在直播平台上进行展示&#xff0c;以吸引观众并提高品牌知名度。AI自动直播通常需要使用特定的软件或平台来实现&#xff0c;并且需要具备一定的编程和人工智能知识。 AI自动直…...

LLaMA Adapter和LLaMA Adapter V2

LLaMA Adapter论文地址&#xff1a; https://arxiv.org/pdf/2303.16199.pdf LLaMA Adapter V2论文地址&#xff1a; https://arxiv.org/pdf/2304.15010.pdf LLaMA Adapter效果展示地址&#xff1a; LLaMA Adapter 双语多模态通用模型 为你写诗 - 知乎 LLaMA Adapter GitH…...

高压放大器在软体机器人领域的应用

软体机器人是一种新型机器人技术&#xff0c;与传统的硬体机器人有着很大的不同。软体机器人通常由柔软的材料制成&#xff0c;具有高度的柔韧性和灵活性&#xff0c;并且可以实现多种形状和动作。但是&#xff0c;软体机器人的发展面临很多技术挑战&#xff0c;其中之一就是控…...

《Linux C/C++服务器开发实践》之第4章 TCP服务器编程

《Linux C/C服务器开发实践》之第4章 TCP服务器编程 4.1 套接字的基本概念4.2 网络程序的架构4.3 IP地址的格式转换4.1.c 4.4 套接字的类型4.5 套接字地址4.5.1 通用socket地址4.5.2 专用socket地址4.5.3 获取套接字地址4.2.c 4.6 主机字节序和网络字节序4.3.c 4.7 协议族和地址…...

HCIA---静态路由扩展配置

静态的扩展配置&#xff1a; 1、负载均衡&#xff1a;当访问相同目标&#xff0c;具有多条开销相似路径时&#xff1b;可以让设备将流量拆分后延多条路径同时传输&#xff1b;起到带宽叠加的作用&#xff1b; 2、环回接口-- 创建后&#xff0c;可用于路由器测试TCP/IP协议组件…...

OCP Java17 SE Developers 复习题04

答案 F. Line 5 does not compile. This question is checking to see whether you are paying attention to the types. numFish is an int, and 1 is an int. Therefore, we use numeric addition and get 5. The problem is that we cant store an int in a String variab…...

spark中使用flatmap报错:TypeError: ‘int‘ object is not subscriptable

1、背景描述 菜鸟笔者在运行下面代码时发生了报错&#xff1a; from pyspark import SparkContextsc SparkContext("local", "apple1012")rdd sc.parallelize([[1, 2], 3, [7, 5, 6]])rdd1 rdd.flatMap(lambda x: x) print(rdd1.collect())报错描述如…...

node.js知识系列(5)-每天了解一点

目录 21. RESTful API 设计中的 HTTP 动词22. 中间件链和回调地狱23. Express.js 的 ORM 经验24. 错误处理中间件和 HTTP 状态码25. 事件循环&#xff08;Event Loop&#xff09;在异步编程中的作用26. Node.js 缓存机制27. Node.js 全局对象28. 性能分析和调优经验29. Express…...

Linux服务器(银河麒麟、CentOS 7+、CentOS 7+ 等)修改IP地址

打开终端或控制台&#xff0c;以root或具有sudo权限的用户身份登录。根据你的Linux发行版和网络管理工具的不同&#xff0c;相应的命令可能略有不同。使用以下命令编辑网络配置文件&#xff0c;例如eth0网卡的配置文件&#xff1a; 注意&#xff1a;ifcfg-eth0 可能会有不同的命…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...