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

C语言-链表_基础

链表-基础

1. 数组

1.1 静态数组

例子:int nums[5] = {0};struct person ps[5];
缺点:1,无法修改地址2,无法动态定义长度3,占用内存过大或过小4,增删速度慢
优点数组的内存是连续开辟的,所以读取速度快

1.2 动态数组

例子:int *nums = (int *) calloc(5,sizeof(int));struct person *ps = (struct person *)calloc(5,sizeof(struct person));
缺点:增删速度慢编写代码较为复杂
优点:读取效率高

2. 常用数据结构

1、数组结构:内存连续开辟

2、链表结构:离散开辟

3、树

4、二叉树(均衡二叉树,非均衡二叉树)

5、图

3. 链表结构

分类:

单链表:

  • 一个节点只记录下一个节点的地址

双链表:

  • 一个节点即记录下一个节点的地址,也记录上一个节点的地址

4. 设计节点

需求:将多个学员信息设计为链表

单链表节点设计:

typedef struct student
{//数据域char name[50];char sex[5];int num;double score;//指针域struct student *next;
}Stu;

双链表节点设计:

typedef truct student
{//数据域char name[50];char sex[5];int num;double score;//指针域struct student *next;struct student *head;
}Stu;

总结:

typedef struct 结构体名称
{//数据域//指针域
}别名;

5. 静态单链表

#include <stdio.h>
typedef struct student
{//数据域char name[50];char sex[5];int num;double score;//指针域struct student *next;
}Stu;
int main(int argc, char const *argv[])
{Stu s01 = {"张三", "男", 1, 99, NULL};Stu s02 = {"李四", "男", 2, 96, NULL};Stu s03 = {"王五", "女", 3, 97, NULL};Stu s04 = {"钱七", "男", 4, 93, NULL};Stu s05 = {"赵八", "女", 5, 97, NULL};Stu *head = &s01;   //将s01作为首节点s01.next = &s02;    //将s02设置为s01的下一个节点   s02.next = &s03;s03.next = &s04;s04.next = &s05;//链表的遍历//pd:当前链表的节点Stu *pd = head;while(pd != NULL){printf("%s %s %d %.2lf\n", pd->name, pd->sex, pd->num, pd->score);//下一个节点赋值给当前节点,为下一轮循环pd = pd->next;}return 0;
}

6. 动态单链表

动态开辟内存,存储结构体学生信息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student
{//数据域char name[50];char sex[5];int age;//指针域struct student *next;
}Stu;
int main(int argc, char const *argv[])
{Stu *s01 = calloc(1,sizeof(Stu));strcpy(s01->name, "陈晴朗");strcpy(s01->sex, "男");s01->age = 18;Stu *s02 = calloc(1,sizeof(Stu));strcpy(s02->name, "李槐");strcpy(s02->sex, "男");s02->age = 8;Stu *s03 = calloc(1,sizeof(Stu));strcpy(s03->name, "李宝瓶");strcpy(s03->sex, "女");s03->age = 14;Stu *s04 = calloc(1,sizeof(Stu));strcpy(s04->name, "裴钱");strcpy(s04->sex, "女");s04->age = 12;Stu *s05 = calloc(1,sizeof(Stu));strcpy(s05->name, "崔东山");strcpy(s05->sex, "男");s05->age = 16;Stu *head = s01;   //将s01作为首节点s01->next = s02;    //将s02设置为s01的下一个节点   s02->next = s03;s03->next = s04;s04->next = s05;//链表的遍历//pd:当前链表的节点Stu *pd = head;while(pd != NULL){printf("%s\t%s\t%d\n", pd->name, pd->sex, pd->age);//下一个节点赋值给当前节点,为下一轮循环pd = pd->next;}return 0;
}
// 陈晴朗  男      18
// 李槐    男      8
// 李宝瓶  女      14
// 裴钱    女      12
// 崔东山  男      16

练习:学员管理系统

需求:

选项有:1,查询所有学员信息2,添加学员信息3,插入学员信息4,删除学员信息5,修改学员信息(作业)6,查找指定位置的学员(作业)7,退出程序(释放内存)

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student
{//数据域char name[30];char sex[10];int num;//指针域struct student *next;
}STU;
//记录链表首节点
STU *head = NULL;//查询函数(打印链表)
void print_link(STU *head)
{//定义一个节点作为当前节点STU *pd = head;while (pd != NULL){printf("姓名:%s\t性别:%s\t学号:%d\n",pd->name,pd->sex,pd->num);//获取下一个节点赋值给当前节点pd = pd->next;}printf("\n");
}//计算链表长度
int get_len(STU *head)
{int i = 0;STU *pd = head;while(pd != NULL){i++;pd = pd->next;}return i;
}//添加学员信息逻辑
/*添加新节点到连接尾部参数;head:链表的头节点stu:要添加的新节点返回值链表的头节点
*/
STU *add(STU *head, STU *stu)
{//如果传进来的学员信息为空,直接返回传进来的头结点if (stu == NULL){return head;}//判断链表首节点是否为空,为空表示此时链表还没有节点,直接将数据赋值给首结点if (head == NULL){head = stu;printf("添加成功\n\n");return head;}//查询最后一个节点,找到NULL的前一个节点//假设当前节点就是最后一个节点(即一个也没有),此时首节点就是最后一个节点STU *lastNode = head;while(lastNode != NULL){//进循环,表示这不是最后一个节点,就判断他的下一个节点是否为空,为空直接跳出循环if (lastNode->next == NULL){break;}else{//此时表示他的下一个节点不是NULL,将它的下一个节点赋值给它lastNode = lastNode->next;}}//没有进循环表示lastNode就是当前链表的最后一个节点//此时就要将本次创建的节点添加到 原链表最后一个节点的后面lastNode->next = stu;printf("添加成功\n\n");return head;
}//尾部添加学员信息
STU *add_student(STU *head)
{//开辟一块堆内存空间赋值 结构体指针变量,用来存储学员信息(即stu指向这片堆内存)STU *stu = calloc(1,sizeof(STU));printf("请输入学员姓名\n");scanf("%s", stu->name);printf("请输入学员性别\n");scanf("%s", stu->sex);printf("请输入学员学号\n");scanf("%d", &stu->num);head = add(head, stu);return head;}//插入学员
STU *inster_student(STU *head)
{STU *stu = calloc(1,sizeof(STU));printf("请输入学员姓名\n");scanf("%s", stu->name);printf("请输入学员性别\n");scanf("%s", stu->sex);printf("请输入学员学号\n");scanf("%d", &stu->num);printf("请输入要插入学员的位置(从0开始)\n");int index = 0;scanf("%d", &index);//排除错误int len = get_len(head);if (index > len){//插入位置超过链表长度,插入链表末位head = add(head, stu);return head;}if (index < 0){printf("输入位置有误\n");return head;}//为0表示插入第一个位置if (index == 0){//将首节点位置变为下一个节点stu->next = head;//将新建的节点赋值给首节点head = stu;printf("添加成功\n");return head;}//寻找插入节点的前一个节点STU *pd = head;for (int i = 0; i < index - 1; i++){pd = pd->next;}stu->next = pd->next; //将前一个节点的原后一个节点赋值给新节点的下一个节点pd->next = stu;printf("添加成功\n\n");return head;
}//删除学员
STU *del_student(STU *head)
{printf("请输入要删除学员的位置(从0开始)\n");int index = 0;scanf("%d", &index);//排除错误int len = get_len(head);if (index > len || index < 0){printf("输入位置有误\n");return head;}//为0表示删除第一个位置if (index == 0){//将首节点的下一个节点变为首节点head = head->next;printf("删除成功\n");return head;}STU *pd1 = head, *pd2;int i = 0;while (i < index){pd2 = pd1;pd1 = pd1->next;i++;}if (pd1 != NULL){pd2->next = pd1->next;}printf("删除成功\n");return head;
}//修改学员
STU *update_student(STU *head)
{STU *stu = calloc(1,sizeof(STU));printf("请输入要修改学员姓名\n");scanf("%s", stu->name);printf("请输入要修改学员性别\n");scanf("%s", stu->sex);printf("请输入要修改学员学号\n");scanf("%d", &stu->num);printf("请输入要修改学员的位置(从0开始)\n");int index = 0;scanf("%d", &index);//排除错误int len = get_len(head);if (index > len || index < 0){printf("输入位置有误\n");return head;}//为0表示修改第一个位置if (index == 0){//将新节点的next指向原首节点的下一个节点stu->next = head->next;printf("修改成功\n");return head;}//不为0int i = 0;//定义两个指针变量记录当前节点和上一个节点STU *pd1 = head, *pd2;while (i < index){pd2 = pd1;pd1 = pd1->next;i++;}pd2->next = stu;stu->next = pd1->next;printf("修改成功\n");return head;
}//查询指定学员位置
STU *find_student(STU *head)
{printf("请输入要查找学员的位置(从0开始)\n");int index = 0;scanf("%d", &index);//排除错误int len = get_len(head);if (index > len || index < 0){printf("输入位置有误\n");return head;}STU *pd = head, *pd1;//为0表示查找的是第一个学员if (index == 0){//直接打印首节点printf("姓名:%s\t性别:%s\t学号:%d\n\n",pd->name,pd->sex,pd->num);return head;}//不为0,寻找当前节点int i = 0;while (i < index){pd1 = pd;pd = pd->next;i++;}printf("姓名:%s\t性别:%s\t学号:%d\n\n",pd->name,pd->sex,pd->num);return head;
}//菜单函数
void my_menu(int tag)
{switch (tag){case 1:print_link(head);break;case 2:head = add_student(head);break;case 3:head = inster_student(head);break;case 4:head = del_student(head);break;case 5:head = update_student(head);break;case 6:head = find_student(head);break;default:printf("输入有误, 请重新输入\n\n");break;}
}//释放内存
void free_link(STU *head)
{STU *pd = head;while (pd != NULL){//记录其下一个节点STU *next = pd->next;//释放当前节点free(pd);//更换当前节点pd = next;}}int main(int argc, char const *argv[])
{while (1){printf("1,查询所有学员信息\n2,添加学员信息\n3,插入学员信息\n4,删除学员信息\n5,修改学员信息\n6,查找指定位置的学员\n7,退出程序\n\n");printf("请输入本次操作的选项(输入对应数字)\n");int tag = 0;scanf("%d", &tag);if (tag != 7){my_menu(tag);}else{free_link(head);printf("欢迎下次光临!\n");break;}}return 0;
}

相关文章:

C语言-链表_基础

链表-基础 1. 数组 1.1 静态数组 例子:int nums[5] {0};struct person ps[5]; 缺点:1,无法修改地址2,无法动态定义长度3,占用内存过大或过小4,增删速度慢 优点数组的内存是连续开辟的,所以读取速度快1.2 动态数组 例子:int *nums (int *) calloc(5,sizeof(int));struct p…...

Java第二十一章总结

网络编程三要素 ip地址&#xff1a;计算机在网络中的唯一标识 端口&#xff1a;应用程序在计算机中唯一标识 协议&#xff1a;通信协议&#xff0c;常见有UDP和TCP协议 InetAddress类 表示Internet协议地址 //返回InetAddress对象 InetAddress byName InetAddress.…...

【keil备忘录】2. stm32 keil仿真时的时间测量功能

配置仿真器Trace内核时钟为单片机实际的内核时钟&#xff0c;需要勾选Enable设置&#xff0c;设置完成后Enable取消勾选也可以&#xff0c;经测试时钟频率配置仍然生效&#xff0c;此处设置为48MHZ: 时间测量时必须打开register窗口&#xff0c;否则可能不会计数 右下角有计…...

图的存储(邻接矩阵,边集数组,邻接表,链式前向星)

目录 &#x1f33c;图的存储 &#xff08;1&#xff09;邻接矩阵 &#xff08;2&#xff09;边集数组 &#xff08;3&#xff09;邻接表 &#xff08;4&#xff09;链式前向星 &#x1f600;刷题 &#x1f40d;最大节点 &#x1f40d;有向图 D 和 E &#x1f40d;奶牛…...

Linux 基础知识整理(二)

Linux系统目录结构 Linux采用的是树型结构。最上层是根目录&#xff0c;其他的所有目录都是从根目录出发而生成的。微软的DOS和windows也是采用树型结构&#xff0c;但是在DOS和 windows中这样的树型结构的根是磁盘分区的盘符&#xff0c;有几个分区就有几个树型结构&#xff…...

2024年值得关注的8个未来数据库

2024年值得关注的8个未来数据库 关系型数据库管理系统在数据库技术领域占据主导地位已经多年了。当SQL在1970年代首次出现时&#xff0c;关系型数据库管理系统的使用和受欢迎程度迅速提升。很快&#xff0c;MySQL成为了大多数公司和团队首选的数据库。 然而&#xff0c;2023年…...

C++新经典模板与泛型编程:将trait类模板用作模板参数

将trait类模板用作模板参数 template<typename T> struct SumFixedTraits;template<> struct SumFixedTraits<char> {using sumT int;static sumT initValue() {return 0;} };template<> struct SumFixedTraits<int> {using sumT __int64;sta…...

BUUCTF-[GYCTF2020]FlaskApp flask爆破pin

这道题不需要爆破也可以getshell ssti都给你了 {{((lipsum.__globals__.__builtins__[__import__](so[::-1])[popen]("\x63\x61\x74\x20\x2f\x74\x68\x69\x73\x5f\x69\x73\x5f\x74\x68\x65\x5f\x66\x6c\x61\x67\x2e\x74\x78\x74")).read())}} 但是学习记录一下pin…...

web前端实现LED功能、液晶显示时间、数字

MENU 效果演示html部分JavaScript部分css部分 效果演示 html部分 <div id"app"><!-- 页面 --><div class"time-box"><!-- 时 --><div class"house-box"><bit-component :num"houseTem"></bit…...

YOLOv8改进 | 2023 | DiverseBranchBlock多元分支模块(有效涨点)

一、本文介绍 本文带来的改进机制是YOLOv8模型与多元分支模块&#xff08;Diverse Branch Block&#xff09;的结合&#xff0c;Diverse Branch Block (DBB) 是一种用于增强卷积神经网络性能的结构重新参数化技术。这种技术的核心在于结合多样化的分支&#xff0c;这些分支具有…...

Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…...

kubeadm 安装k8s1.28.x 底层走containerd 容器

1. k8s1.28.x 的概述 1.1 k8s 1.28.x 更新 Kubernetes v1.28 是 2023 年的第二个大版本更新&#xff0c;包含了 46 项主要的更新。 而今年发布的第一个版本 v1.27 有近 60 项&#xff0c;所以可以看出来&#xff0c;在发布节奏调整后&#xff0c; 每个 Kubernetes 版本中都会包…...

“分割“安卓用户,对标iOS,鸿蒙崛起~

近期关于**“华为于明年推出不兼容安卓的鸿蒙版本”**的消息传出&#xff0c;引起了业界的热议关注。自从2019年8月&#xff0c;美国制裁下&#xff0c;华为不再能够获得谷歌安卓操作系统相关付费服务&#xff0c;如此情况下&#xff0c;华为“备胎”鸿蒙操作系统一夜转正。 华…...

【Vulnhub 靶场】【hacksudo: ProximaCentauri】【简单 - 中等】【20210608】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/hacksudo-proximacentauri,709/ 靶场下载&#xff1a;https://download.vulnhub.com/hacksudo/hacksudo-ProximaCentauri.zip 靶场难度&#xff1a;简单 - 中等 发布日期&#xff1a;2021年06月08日 文件大小&…...

share pool的组成

share pool的组成 3块区域&#xff1a;free,library cache,row cache 通过查看v$librarycache视图&#xff0c;可以监控library cache的活动情况&#xff0c;进一步衡量share pool设置是否合理; 其中reloads列&#xff0c;表示对象被重新加载的次数&#xff0c;在一个设置合…...

应用案例 | 基于三维视觉的汽车零件自动化拧紧解决方案

​Part.1 引言 随着人们生活水平的提高&#xff0c;汽车作为理想的代步工具&#xff0c;逐渐成为人们生活中不可或缺的一部分。汽车的广泛应用&#xff0c;大大增加了汽车制造业的负荷。因此&#xff0c;如何提高生产效率和汽车性能&#xff0c;成为汽车制造业的首要关注话题。…...

Redis server启动源码

入口main函数 src/redis.c文件main函数 int main(int argc, char **argv) {struct timeval tv;/* We need to initialize our libraries, and the server configuration. */// 初始化库 #ifdef INIT_SETPROCTITLE_REPLACEMENTspt_init(argc, argv); #endif//设置本地时间setl…...

C++基础 强制转换

目录 static_cast&#xff1a;static_cast(expression) const_cast dynamic_cast reinterpret_cast C 提供以下几类转换 static_cast&#xff1a;static_cast<type-id>(expression) tatic_cast 主要用于以下几种情况&#xff1a; 用于显式地将一个表达式转换为另一…...

【python、opencv】opencv仿射变换原理及代码实现

opencv仿射变换原理 仿射变换是opencv的基本知识点&#xff0c;主要目的是将原始图片经过仿射变换矩阵&#xff0c;平移、缩放、旋转成目标图像。用数学公式表示就是坐标转换。 其中x&#xff0c;y是原始图像坐标&#xff0c;u&#xff0c;v是变换后的图像坐标。将公式转换为…...

mac本地部署stable-diffusion

下载Homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" ①输入“1”选择中科大版本&#xff0c;然后输入Y(YES)&#xff0c;直接输入开机密码&#xff08;不显示&#xff09;然后回车确认&#xff0c;开始下载 ②…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

基于django+vue的健身房管理系统-vue

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.8数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat12开发软件&#xff1a;PyCharm 系统展示 会员信息管理 员工信息管理 会员卡类型管理 健身项目管理 会员卡管理 摘要 健身房管理…...

Yolo11改进策略:Block改进|FCM,特征互补映射模块|AAAI 2025|即插即用

1 论文信息 FBRT-YOLO&#xff08;Faster and Better for Real-Time Aerial Image Detection&#xff09;是由北京理工大学团队提出的专用于航拍图像实时目标检测的创新框架&#xff0c;发表于AAAI 2025。论文针对航拍场景中小目标检测的核心难题展开研究&#xff0c;重点解决…...