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

数据结构——单向循环链表代码(补充)

在此前的文章中(链接如下),只有单向链表的代码,接下来我们来写单向循环链表,并用其实现一个简单的学生信息链表https://blog.csdn.net/2301_80406299/article/details/151157051?spm=1011.2415.3001.10575&sharefrom=mp_manage_link

1、单向链表与单向循环链表的不同

  • 单向链表:尾节点的 next 指针坚定地指向 NULL。这个 NULL 像一个终点站的标志,明确告知遍历者:“链表至此结束,前方无路”。这使得单向链表在逻辑上呈现为一种线性开环结构,有头有尾,有明确的起点和终点。

  • 单向循环链表:尾节点的 next 指针则指向了头节点。这一指向,如同将一条绳子的首尾相接,形成了一个闭合的环。它移除了结束的标志,使得遍历操作可以在链表中无限循环。因此,它是一种环形结构,没有传统意义上的“终点”。

单向循环链表代码——学生信息链表


主函数  main.c

/********************************************************************************* @file    main.c* @author  feng* @version V0.0.1* @date    2025.09.08* @brief   使用单向循环链表实现数据的增删查改——学生信息链表*          环境:ubuntu18.04*          编译+执行:./project.sh******************************************************************************** @attention**  本文档只供装逼学习使用,不得商用,违者必究**  github:       https://github.com/(求我拿链接)*  CSDN:          https://blog.csdn.net/(嘻嘻)*  gitee:         https://gitee.com/(求我拿链接)*  微信公众号:    没有*  没有疑问或者建议:12345678910@qq.com** *******************************************************************************/#include "singly_circular_link_list.h"int main(int argc, char const *argv[])
{node_p head_node = sc_link_list_InitHeadNode();if (head_node == NULL){printf("头节点初始化失败!\n");return -1;}node_p new_node = NULL;int select = 0;char name[20];int id, grade, age;float score;int search_id, del_id, change_id;while (1){sc_link_list_ShowListData(head_node);printf("\n请选择以下功能:\n");printf("1、插入数据(头插法)\n");printf("2、插入数据(尾插法)\n");printf("3、删除数据\n");printf("4、修改数据\n");printf("5、查找数据\n");printf("6、退出系统\n");printf("请选择: ");scanf("%d", &select);while (getchar() != '\n'); // 清空输入缓冲区switch (select){case 1: // 头插法printf("\n--- 添加学生(头插法) ---\n");printf("姓名: "); scanf("%19s", name);printf("学号: "); scanf("%d", &id);printf("年级: "); scanf("%d", &grade);printf("成绩: "); scanf("%f", &score);printf("年龄: "); scanf("%d", &age);while (getchar() != '\n'); new_node = sc_link_list_InitDataNode(name, id, grade, score, age);if (!new_node) {printf("创建节点失败!\n");break;}sc_link_list_HeadInsert(head_node, new_node);printf("添加成功!\n");break;case 2: printf("\n--- 添加学生(尾插法) ---\n");printf("姓名: "); scanf("%19s", name);printf("学号: "); scanf("%d", &id);printf("年级: "); scanf("%d", &grade);printf("成绩: "); scanf("%f", &score);printf("年龄: "); scanf("%d", &age);while (getchar() != '\n'); new_node = sc_link_list_InitDataNode(name, id, grade, score, age);if (!new_node) {printf("创建节点失败!\n");break;}sc_link_list_LastInsert(head_node, new_node);printf("添加成功!\n");break;case 3: // 删除printf("\n请输入要删除的学生学号: ");scanf("%d", &del_id);while (getchar() != '\n');if (sc_link_list_DelNodeData(head_node, del_id) == 0) {printf("删除成功!\n");}break;case 4: // 修改printf("\n请输入要修改的学生学号: ");scanf("%d", &change_id);while (getchar() != '\n'); printf("输入新的信息(留空则保持不变):\n");printf("姓名: "); scanf("%19s", name);printf("年级(0保持不变): "); scanf("%d", &grade);printf("成绩(-1保持不变): "); scanf("%f", &score);printf("年龄(0保持不变): "); scanf("%d", &age);while (getchar() != '\n'); if (sc_link_list_ChangeNodeData(head_node, change_id, name[0] ? name : NULL, grade, score, age) == 0) {printf("修改成功!\n");}break;case 5:printf("\n请输入要查找的学生学号: ");scanf("%d", &search_id);while (getchar() != '\n');sc_link_list_SearchNodeData(head_node, search_id);break;case 6: // 退出sc_link_list_Uninit(head_node);printf("系统已退出!\n");return 0;default:printf("无效选择,请重新输入!\n");break;}}
}

 


头文件 singly_circular_link_list.h

/********************************************************************************* @file    singly_circular_link_list.h* @author  feng* @version V0.0.1* @date    2025.29.28* @brief   单向循环链表的增删查改功能——学生信息链表* ******************************************************************************* @attention**  本文档只供学习使用,不得商用,违者必究* *  github:       https://github.com/(求我拿链接)*  CSDN:          https://blog.csdn.net/(嘻嘻)*  gitee:         https://gitee.com/(求我拿链接)*  微信公众号:    没有*  没有疑问或者建议:12345678910@qq.com* * *******************************************************************************/#ifndef SINGLY_CIRCULAR_LINK_LIST_H
#define SINGLY_CIRCULAR_LINK_LIST_H#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>typedef struct student {char name[20];int id;int grade;float score;int age;
} student_t;typedef struct node {student_t data; struct node *next_p;
} node_t, *node_p;node_p sc_link_list_InitHeadNode(void);
node_p sc_link_list_InitDataNode(const char *name, int id, int grade, float score, int age);  // 修改3: 参数列表修改
void sc_link_list_HeadInsert(node_p head_node, node_p new_node);
void sc_link_list_LastInsert(node_p head_node, node_p new_node);
bool sc_link_list_IfEmpty(node_p head_node);
int sc_link_list_ShowListData(node_p head_node);
int sc_link_list_DelNodeData(node_p head_node, int del_id);  // 修改4: 改为按学号删除
int sc_link_list_ChangeNodeData(node_p head_node, int find_id, const char *new_name, int new_grade, float new_score, int new_age);  // 修改5: 参数列表修改
int sc_link_list_SearchNodeData(node_p head_node, int search_id);  // 修改6: 改为按学号查找
void sc_link_list_Uninit(node_p head_node);#endif

功能函数:singly_circular_link_list

#include "singly_circular_link_list.h"node_p sc_link_list_InitHeadNode(void)
{node_p p = malloc(sizeof(node_t));if (p != NULL){memset(p, 0, sizeof(node_t));p->next_p = p;}return p;
}node_p sc_link_list_InitDataNode(const char *name, int id, int grade, float score, int age)
{node_p p = malloc(sizeof(node_t));if (p != NULL){memset(p, 0, sizeof(node_t));strncpy(p->data.name, name, sizeof(p->data.name)-1);p->data.id = id;p->data.grade = grade;p->data.score = score;p->data.age = age;p->next_p = p;}return p;
}void sc_link_list_HeadInsert(node_p head_node, node_p new_node)
{new_node->next_p = head_node->next_p;head_node->next_p = new_node;
}void sc_link_list_LastInsert(node_p head_node, node_p new_node)
{node_p temp_p = head_node;while (temp_p->next_p != head_node){temp_p = temp_p->next_p;}temp_p->next_p = new_node;new_node->next_p = head_node;
}bool sc_link_list_IfEmpty(node_p head_node)
{return head_node->next_p == head_node;
}int sc_link_list_ShowListData(node_p head_node)
{if (sc_link_list_IfEmpty(head_node)){printf("链表为空!\n");return -1;}node_p tem_p = head_node->next_p;int i = 0;printf("\n==================学生信息列表===================\n");while (tem_p != head_node){printf("学生 %d:\n", i+1);printf("  姓名: %s\n", tem_p->data.name);printf("  学号: %d\n", tem_p->data.id);printf("  年级: %d\n", tem_p->data.grade);printf("  成绩: %.2f\n", tem_p->data.score);printf("  年龄: %d\n", tem_p->data.age);printf("--------------------------------------------\n");tem_p = tem_p->next_p;i++;}printf("================================================\n");return 0;
}int sc_link_list_DelNodeData(node_p head_node, int del_id)
{if (sc_link_list_IfEmpty(head_node))return -1;node_p prev_p = head_node;node_p curr_p = head_node->next_p;while (curr_p != head_node){if (curr_p->data.id == del_id){prev_p->next_p = curr_p->next_p;free(curr_p);return 0;}prev_p = curr_p;curr_p = curr_p->next_p;}printf("未找到学号为 %d 的学生\n", del_id);return -1;
}int sc_link_list_ChangeNodeData(node_p head_node, int find_id, const char *new_name, int new_grade, float new_score, int new_age)
{if (sc_link_list_IfEmpty(head_node))return -1;node_p tem_p = head_node->next_p;while (tem_p != head_node){if (tem_p->data.id == find_id){if (new_name) strncpy(tem_p->data.name, new_name, sizeof(tem_p->data.name)-1);if (new_grade > 0) tem_p->data.grade = new_grade;if (new_score >= 0) tem_p->data.score = new_score;if (new_age > 0) tem_p->data.age = new_age;return 0;}tem_p = tem_p->next_p;}printf("未找到学号为 %d 的学生\n", find_id);return -1;
}int sc_link_list_SearchNodeData(node_p head_node, int search_id)
{if (sc_link_list_IfEmpty(head_node))return -1;node_p tem_p = head_node->next_p;while (tem_p != head_node){if (tem_p->data.id == search_id){printf("\n找到学生信息:\n");printf("  姓名: %s\n", tem_p->data.name);printf("  学号: %d\n", tem_p->data.id);printf("  年级: %d\n", tem_p->data.grade);printf("  成绩: %.2f\n", tem_p->data.score);printf("  年龄: %d\n", tem_p->data.age);return 0;}tem_p = tem_p->next_p;}printf("未找到学号为 %d 的学生\n", search_id);return -1;
}void sc_link_list_Uninit(node_p head_node)
{if (!head_node) return;node_p curr_p = head_node->next_p;while (curr_p != head_node){node_p next_p = curr_p->next_p;free(curr_p);curr_p = next_p;}free(head_node);
}


文章转载自:

http://rd8BjOJy.Lkpzx.cn
http://oPciRTWA.Lkpzx.cn
http://aezXKxoJ.Lkpzx.cn
http://NGvXyUwX.Lkpzx.cn
http://7NM8vCF0.Lkpzx.cn
http://8skNS78F.Lkpzx.cn
http://ViMXMTgL.Lkpzx.cn
http://hvVfuQcA.Lkpzx.cn
http://YtFa9DNo.Lkpzx.cn
http://DVpz8Y9E.Lkpzx.cn
http://pgGHQ75d.Lkpzx.cn
http://23PaMZR9.Lkpzx.cn
http://9EsoVHGG.Lkpzx.cn
http://WVNJ896Q.Lkpzx.cn
http://FVW9WKau.Lkpzx.cn
http://9Sak4bA9.Lkpzx.cn
http://n1MtRBpM.Lkpzx.cn
http://MQRUr7fn.Lkpzx.cn
http://qrWQyLy7.Lkpzx.cn
http://TLCdiIkq.Lkpzx.cn
http://bZISj1aA.Lkpzx.cn
http://WpkjJiYi.Lkpzx.cn
http://w79pCrmc.Lkpzx.cn
http://ANieK1j3.Lkpzx.cn
http://gyrUE2Hp.Lkpzx.cn
http://SnOjVTr4.Lkpzx.cn
http://zcsmZDNH.Lkpzx.cn
http://dKkT6mNN.Lkpzx.cn
http://nNRFaelO.Lkpzx.cn
http://ux9VILoM.Lkpzx.cn
http://www.dtcms.com/a/373688.html

相关文章:

  • 如何解锁之前通过 apt-mark hold 锁定的 NVIDIA 驱动和 cuDNN 相关包
  • 深入浅出 HarmonyOS ArkTS 并发编程:基于 Actor 模型与 TaskPool 的最佳实践
  • 【已解决,亲测有效】解决使用Python Matplotlib库绘制图表中出现中文乱码(中文显示为框)的问题的方法
  • STL库——二叉搜索树
  • 探索命令行之谜:ps -aux 和 ps aux 是一样的吗?
  • leetcode11(H 指数)
  • TensorRT自定义量化 对数量化
  • 【Python】S1 基础篇 P4 if 语句指南
  • 在使用ffmpeg与音转文模型时,会报错音转文stack expects a non-empty Tensor List
  • 苏州ecovadis认证500人内费用多少?
  • 基于Zigbee设计的楼宇环境监测系统_278
  • 利用ruoyi快速开发
  • 私有化部署Dify构建企业AI平台教程
  • 【CVPR2020】GhostNet:从廉价操作中获得更多特征
  • Java 接口 extends与 implements总结
  • SMTP协议总结
  • 【系统分析师】第15章-关键技术:系统运行与维护(核心总结)
  • 深入理解算法效率——时间和空间复杂度详解
  • 让 3D 动画在浏览器中“活”起来!
  • Acrobat/Reader JavaScript 开发:Net.HTTP.Request 的使用与限制
  • QT通过QModbusRtuSerialMaster读写电子秤数据实例
  • 【实战中提升自己】内网安全部署之STP的安全技术部署
  • MYSQL数据库初阶 之 MySQL索引特性1【索引概念】
  • Django入门:框架基础与环境搭建
  • 数据结构题集-第四章-串-基础知识题
  • 【golang学习笔记 gin 】1.1 路由封装和mysql 的使用封装
  • django5个人笔记
  • Linux 进程信号之信号的保存
  • 详细讲解锥齿轮丝杆升降机的加工制造工艺
  • nginx配置前端请求转发到指定的后端ip