C语言数据结构之链表的增删改查

2023-11-06

C语言数据结构之链表的增删改查

tips:昨天学习了c语言结构体,今天来看看c语言数据结构之链表(单链表)的增删改查操作


首先我们创建一个简单的学生信息结构体,作为后面增删改查的主体
student结构体包含
数据域:学号,分数;
指针域:一个指向后继结点的pNext指针;

typedef struct student {
	int num;
	int score;
	struct student *pNext;
}stu, *pstu;

链表测试输出函数

//链表打印
void list_print(pstu phead)
{
	while (phead)//循环终止条件
	{
		printf("%d:%d分\n", phead->num,phead->score);
		phead = phead->pNext;//打印下一个结点
	}
	printf("-------------------------------------\n");
}
一、链表的新增

链表的新增分为3种方式
1、头插法:新增的结点作为原链表的头结点,原链表头结点顺序后移
2、尾插法:新增的结点作为原链表的尾结点,原链表尾结点变为倒数第二个结点
3、有序插入:新增的结点按照一定顺序,有序的插入链表中


tips:在链表操作中用二级指针操作一级指针,并且为链表定义两个指针:phead头指针,ptail尾指针


1.头插法
思路:
1.1创建新结点,并将其初始化
1.2当原链表为空时,插入新结点后,原链表头指针和尾指针要同时指向新结点
1.3当原链表不为空时,插入新结点后,原链表头指针指向新结点,新结点的pNext指针指向原头结点

在这里插入图片描述
具体实现:

//头插法
void list_head_insert(pstu *pphead, pstu *pptail, int i)
{
	pstu pnew = (pstu)malloc(sizeof(stu));//给新结点申请空间
	
	//给新结点初始化
	pnew->num = i;
	pnew->score = 90;//每个同学90分,保证公平!
	pnew->pNext = NULL;

	//初始化完成后就开始插入
	if (*pphead == NULL)//判断链表为空(头指针为空,链表就为空)
	{
		//如果链表为空,头指针和尾指针都指向新结点
		//头尾指针同时指向新结点
		*pphead = pnew;
		*pptail = pnew;
	}
	else
	{
		//不为空,往前插入新结点
		pnew->pNext = *pphead;//将现有头结点放在新结点之后
		*pphead = pnew;//pnew成为新的头结点,ptail不变,头指针指向新结点
	}
}//头插法,输出的是逆序

输出测试方法及结果:

	//测试循环插入
	pstu phead = NULL, ptail = NULL;
	int i;
	while (scanf("%d", &i) != EOF)
	{
		list_head_insert(&phead, &ptail, i);
	}
	list_print(phead);

在这里插入图片描述


2.尾插法
思路:
2.1创建新结点,并将其初始化
2.2当原链表为空时,插入新结点后,原链表头指针和尾指针要同时指向新结点
2.3当原链表不为空时,插入新结点后,原链表尾结点的pNext指向新结点,原链表的尾指针指向新结点

在这里插入图片描述
具体实现:

//尾插法
void list_tail_insert(pstu *pphead, pstu *pptail, int i)
{
	pstu pnew = (pstu)malloc(sizeof(stu));//给新节点申请一个结构体大小的空间

	//新节点初始化
	pnew->num = i;
	pnew->score = 90;//每个同学90分,保证公平!
	pnew->pNext = NULL;

	//开始插入
	if (*pphead==NULL)//判断原有链表是否为空
	{
		//为空,新结点插入进来,头尾指针指向新结点
		*pphead = pnew;
		*pptail = pnew;
	}
	else
	{
		//不为空,往后插入新结点
		(*pptail)->pNext = pnew;//将原结点的最后一个连接上新结点
		*pptail = pnew;//新结点变成尾节点
	}

}//尾插法输出的是顺序

输出测试方法及结果:

	//测试循环插入
	pstu phead = NULL, ptail = NULL;
	int i;
	while (scanf("%d", &i) != EOF)
	{
		list_tail_insert(&phead, &ptail, i);
	}
	list_print(phead);

在这里插入图片描述


3.有序插入
思路:
3.1创建新结点,并将其初始化
3.2当原链表为空时,插入新结点后,原链表头指针和尾指针要同时指向新结点
3.3当原链表不为空时,根据插入结点学号i的大小确定新结点插入的位置:
     · 如果新结点学号小于头结点学号,则插入头部;
     · 如果新结点学号大于头结点学号则插入位置时中间或者尾部;
循环遍历整个链表,为新结点找位置,当前指针指向的结点的i>新结点时,那么也可以说明前一个结点的i小于新结点,则说明新结点找到中间位置插入。(这里需要定义一个指针pcur指向循环遍历当前结点,还需定义一个指针ppre指向当前结点的前一个结点,说白了就是两个工具人!)找到位置后,当前结点的前一个结点的pNext指向新结点,新结点的pNext指向当前结点;
如果遍历完整个链表都没有找到位置插入,则插入尾部;

在这里插入图片描述
具体实现:

//有序插入链表
void list_sort_insert(pstu *pphead, pstu *pptail, int i)
{
	pstu pcur;//保存当前结点信息;
	pstu ppre;//保留pcur前一个结点信息;

	//新建一个结点
	pstu pnew = (pstu)malloc(sizeof(stu));

	//对新结点初始化
	pnew->num = i;
	pnew->score = 90;//每个同学90分,保证公平!
	pnew->pNext = NULL;

	pcur = *pphead;//当前结点指针,初始化等于头指针
	ppre = *pphead;

	if (pcur == NULL)//判断链表是否为空
	{
		//链表为空,插入后头指针尾指针指向插入的结点
		*pphead = pnew;
		*pptail = pnew;
	}
	else if (i < pcur->num)//是否插入头部.当插入的结点小于头结点时候插入头部
	{
		//新结点变成头结点
		pnew->pNext = *pphead;
		*pphead = pnew;
	}
	else {
		//插入中间和尾部
		while (pcur)//遍历整个链表,找中间位置插入
		{
			if (pcur->num > i)//链表当前结点值大于要插入结点的值
			{
				//新结点插入两个结点之间
				pnew->pNext = pcur;
				ppre->pNext = pnew;

				break;//插入后跳出循环
			}
			ppre = pcur;//将当前位置信息赋给ppre

			pcur=pcur->pNext;

		}
		if (pcur==NULL)//中间没有位置插入,往最后插入
		{
			//新结点变成最后一个结点,原来尾指针新结点
			(*pptail)->pNext = pnew;
			//尾指针重新指向新结点	
			*pptail = pnew;
		}
	}
}

输出测试方法及结果:

	//测试循环插入
	pstu phead = NULL, ptail = NULL;
	int i;
	while (scanf("%d", &i) != EOF)
	{
		list_sort_insert(&phead, &ptail, i);
	}
	list_print(phead);

在这里插入图片描述


二、链表的删除

思路
1.当链表为空时,输出链表为空
2.当链表不为空时
    2.1删除的是头结点:头指针指向头结点的下一个结点,释放原头结点空间,还需判断删完后,原链表是否为空,若为空,则尾指针要置位NULL;
    2.2删除的是中间结点或者尾结点:循环遍历整个链表,找到要删除结点的位置,当前指针指向的结点的i==新结点时,则说明位置找到。(这里需要定义一个指针pcur指向循环遍历当前结点,还需定义一个指针ppre指向当前结点的前一个结点,说白了就是两个工具人!!)找到位置后,当前结点的前一个结点的pNext指向当前结点的pNext,释放当前结点空间;当遍历到达尾结点找到位置,则删除尾结点,将尾指针指向当前结点的前一个结点;当遍历完链表没有找到删除位置,则链表中没有符合条件的结点;

在这里插入图片描述
具体实现:

//根据i删除链表结点
void list_delete(pstu *pphead, pstu *pptail, int i) 
{
	//首先判断链表是否为空
	pstu pcur = *pphead;//用来当工具人
	pstu ppre = *pphead;//工具人,用来保存当前结点前一个结点的信息
	if (pcur == NULL)
	{
		printf("当前链表为空!\n");
	}
	else if(pcur->num==i)//删除的是头结点
	{
		(*pphead)->pNext = pcur->pNext;
		//释放结点空间
		free(pcur);
		//删完后判断链表是否为空,如果链表为空*pptail=NULL
		if ((*pphead) == NULL)
		{
			*pptail = NULL;
		}
	}
	else//删除中间或尾结点
	{
		//删除的是中间结点,循环遍历
		while (pcur)//循环遍历找到结点值为i的
		{
			if (pcur->num == i)
			{
				//找到符合条件的结点就删除该结点
				ppre->pNext = pcur->pNext;
				free(pcur);//释放掉当前被删除结点的空间
				break;
			}
			ppre = pcur;//先将此结点信息保存到ppre,pcur再往后移
			pcur = pcur->pNext;

		}
		//删除的是尾结点
		if (pcur == *pptail)
		{
			*pptail = ppre;//尾指针前移
		}
		if (pcur == NULL)//删除的结点不在链表中
		{
			printf("该链表中没有结点值为%d的结点!\n", i);
		}
	}

}

输出测试及结果:

	pstu phead = NULL, ptail = NULL;//定义头尾指针,描述链表
	int i;
	while (printf("请输入要删除结点的值(num):"), scanf("%d", &i) != EOF)
	{
		list_delete(&phead, &ptail, i);
		list_print(phead);
	}

在这里插入图片描述

三、链表的修改

思路:
1.当链表为空时,输出链表为空。
2.当链表不为空时,循环遍历链表找到符合条件的结点,修改值。若找不到符合条件的结点,则输出该结点不在链表。

具体实现:

void list_modify(pstu phead, int i, int score)
{
	//判断链表是否为空
	if (phead == NULL)
	{
		printf("当前链表为空!\n");
	}
	else
	{
		//遍历寻找符合条件的结点
		while (phead)
		{
			if (phead->num == i)
			{
				phead->score = score;
				break;
			}
			phead=phead->pNext;
		}
		if(phead==NULL)
		{
			printf("该链表中没有结点值为%d的结点!\n", i);
		}

	}
}

输出测试及结果:

	pstu phead = NULL, ptail = NULL;//定义头尾指针,描述链表
	int i,score;
	while (printf("请输入要改变结点的值(num score):"), scanf("%d %d", &i,&score) != EOF)
	{
		list_modify(phead,i,score);
		list_print(phead);
	}

在这里插入图片描述

四、链表的查找

思路:
1.当链表为空时,输出链表为空。
2.当链表不为空时,循环遍历链表找到符合条件的结点,输出值。若找不到符合条件的结点,则输出该结点不在链表。

具体实现:


//查找对应结点i的信息
void list_search(pstu phead, int i)
{
	//判断链表是否为空
	if (phead == NULL)
	{
		printf("当前链表为空!\n");
	}
	else
	{
		//遍历寻找符合条件的结点
		while (phead)
		{
			if (phead->num == i)
			{
				printf("%d:%d分\n", phead->num, phead->score);
				break;
			}
			phead = phead->pNext;
		}
		if (phead == NULL)
		{
			printf("该链表中没有结点值为%d的结点!\n", i);
		}

	}
}

输出测试及结果:

	pstu phead = NULL, ptail = NULL;//定义头尾指针,描述链表
	int i;
	while (printf("请输入要查询结点的值(num):"), scanf("%d", &i) != EOF)
	{
		list_search(phead,i);
	}

在这里插入图片描述


链表的增删改成至此已经完成了,希望大家看了能有收获!
tips:在这个世界上取得成就的人,都努力去寻找他们想要的机会,如果找不到机会,他们便自己创造机会。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言数据结构之链表的增删改查 的相关文章

  • D (1173) : A DS二叉树_合并二叉树

    文章目录 一 题目描述 二 输入与输出 1 输入 2 输出 三 参考代码 一 题目描述 给定两个二叉树 输出这两个二叉树合并后形成的二叉树 依次输出前序遍历 中序遍历 后序遍历 二 输入与输出 1 输入 第一行输入t 表示有t个测试样例 第
  • C语言,求取数组的序亏:已知一个整数数组,求出个数组中每个元素在整个 数组的排序。

    要求获取整数数组中每个元素的排序 可以使用以下方法 1 定义一个结构体数组 其中每个结构体包含数组元素的值和索引 2 遍历整数数组 将每个元素与其索引一起存储到结构体数组中 3 对结构体数组进行排序 按照元素的值进行升序排序 4 遍历排序后
  • 八大排序(插入排序 | 选择排序 | 冒泡排序)

    在我们内存中我们一般会有一些没有顺序的数据 我们成为内排序 而今天分享八大排序的是时间复杂度为O N 2 的插入排序 选择排序和教学意义比较强的冒泡排序 插入排序 这是插入排序的动图 通过动图我们也是可以看到我们的插入排序的思想 从当前的位
  • c 关于数组几个查序程序

    1 查询某元素是否在数组中 int main void char i 10 2 1 7 2 10 5 2 0 1 4 10 10 1 3 1 0 8 char z 10 1 2 3 4 1 4 6 8 0 9 int zz 0 标志位 0
  • 【数据结构】双链表的定义和操作

    目录 1 双链表的定义 2 双链表的创建和初始化 3 双链表的插入节点操作 4 双链表的删除节点操作 5 双链表的查找节点操作 6 双链表的更新节点操作 7 完整代码 嗨 我是 Filotimo 很高兴与大家相识 希望我的博客能对你有所帮助
  • C语言之变量的存储方式和生存周期

    一 变量的存储方式 C语言变量的存储有两种方式 静态存储方式和动态存储方式 相应的生产期也有两种 静态生存期和自动生存期 静态存储方式 在程序运行前为变量内存分配内存 在程序结束后回收变量的内存 静态生存期 动态存储方式 在程序运行过程中
  • 代码随想录算法训练营Day3 | 203.移除链表元素、707.设计链表、59.螺旋矩阵II

    LeetCode 203 移除链表元素 本题思路 就是常规的移除链表中的元素的操作 需要注意的点 头节点 head val val 的情况的处理 如果 head val val 就要继续往后 head head next 因此我们要遍历到第
  • 数据结构 数组与字符串

    介绍 数组的基础 定义和声明 基本定义 在C语言中 数组可以被定义为一系列相同类型的元素的集合 每个元素在内存中连续排列 可以通过索引 通常是从0开始的整数 来访问 数组的声明 数组在C语言中的声明包括元素类型 数组名和大小 例如 声明一个
  • 深度学习目标检测全连接层什么意思

    在深度学习目标检测中 通常我们使用卷积神经网络 Convolutional Neural Network CNN 进行特征提取 CNN 的主要结构包括卷积层和池化层 用于从输入图像中提取特征 然而 为了最终输出目标的类别和位置信息 通常在网
  • 华为OD机试 Python 【最大载货量】

    描述 在火车站旁的货运站 小明负责调度2K辆中转车 其中K辆用于干货 K辆用于湿货 每批到站的货物来自不同的供货商 需要按照顺序装入中转车 注意 一个供货商的货物只能装在一辆车上 不能分开 但是 一辆车可以放多个供货商的货物 问题是 要让所
  • 华为OD机试 C++【最大载货量】

    描述 在火车站旁的货运站 小明负责调度2K辆中转车 其中K辆用于干货 K辆用于湿货 每批到站的货物来自不同的供货商 需要按照顺序装入中转车 注意 一个供货商的货物只能装在一辆车上 不能分开 但是 一辆车可以放多个供货商的货物 问题是 要让所
  • 【华为OD】给定一个整数数组nums,请你在该数组中找出两个数,使得这两个数 的和的绝对值abs(nums[x] + nums[y])为最小值并按从小到大返回这 两个数以及它们和的绝对值

    题目描述 给定一个整数数组nums 请你在该数组中找出两个数 使得这两个数 的和的绝对值abs nums x nums y 为最小值并按从小到大返回这 两个数以及它们和的绝对值 每种输入只会对应一个答案 数组中同一 个元素不能使用两遍 输入
  • 【数据结构和算法】 K 和数对的最大数目

    其他系列文章导航 Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一 题目描述 二 题解 2 1 方法一 双指针排序 三 代码 3 1 方法一 双指针排序 3
  • LeetCode 1901. 寻找峰值 II

    一 题目 1 题目描述 一个 2D 网格中的 峰值 是指那些 严格大于 其相邻格子 上 下 左 右 的元素 给你一个 从 0 开始编号 的 m x n 矩阵 mat 其中任意两个相邻格子的值都 不相同 找出 任意一个 峰值 mat i j
  • 数据结构学习笔记(七)搜索结构

    文章目录 1 前言 2 概念 3 静态搜索结构 3 1 静态搜索表 3 2 顺序搜索表 3 2 1 基于有序顺序表和顺序搜索和折半搜索 4 二叉搜索树
  • 《LeetCode力扣练习》代码随想录——双指针法(反转链表---Java)

    LeetCode力扣练习 代码随想录 双指针法 反转链表 Java 刷题思路来源于 代码随想录 206 反转链表 双指针 Definition for singly linked list public class ListNode int
  • 冒泡排序/选择排序/插入排序/快速排序/归并排序/桶排序/堆排序/希尔排序/计数排序/基数排序/二分查找/广度优先搜索/深度优先搜索

    排序算法 冒泡排序 Bubble Sort 通过重复地比较相邻的元素并交换它们 使得最大 或最小 的元素逐渐移动到列表的一端 从而实现排序 选择排序 Selection Sort 在未排序的部分中 选择最小 或最大 的元素 并将其放置在已排
  • 搜索二叉树(BSTree)

    一 搜索二叉树的概念 二叉搜索树又称为做二叉排序树 二叉查找树 其要么是一棵空树 要么是一个满足以下性质的二叉树 若它的左子树不空 则左子树上所有结点的关键字均小于根结点关键字 若它的右子树不空 则右子树上所有结点的关键字均大于根结点关键字
  • 矩阵基本操作3

    题目描述 问题描述 定义一个N M N M lt 100 的矩阵 将一个该矩阵的行和列的元素互换 存到另一个二维数组中 输入格式 一行两个整数 N M 中间用空格隔开 表示矩阵有N行 M列 接下来共N行M列表示矩阵 输出格式 输出转置以后的
  • 数据结构——排序

    前言 哈喽小伙伴们好久不见 也是顺利的考完试迎来了寒假 众所周知 不怕同学是学霸 就怕学霸放寒假 假期身为弯道超车的最佳时间 我们定然是不能懒散的度过 今天我们就一起来学习数据结构初阶的终章 七大排序 本文所有的排序演示都为升序排序 目录

随机推荐

  • python中的pygame使用_python 中的pygame的一些基本使用总结

    什么是pygame pygame是一个python中的一个游戏库 用于2D游戏的开发 下面是关于pygame的一些常用方法 首先 需要导入 import pygame 窗口的相关操作 创建一个窗口 screen pygame display
  • verilog HDL +UART实验+数码管动态显示

    功能 板子接受通过RS232接受串口调试助手发送的一个字节数据 然后将其转化成0 255的十进制数 在4位数码管上 显示出来 只用到了3位 不用的位熄灭 只有有数字的位才显示 说明 UART部分还是参考特权的Verilog程序 谢谢前辈啊
  • 人脸图像数据增强

    为什么要做数据增强 在计算机视觉相关任务中 数据增强 Data Augmentation 是一种常用的技术 用于扩展训练数据集的多样性 它包括对原始图像进行一系列随机或有规律的变换 以生成新的训练样本 数据增强的主要目的是增加模型的泛化能力
  • 技术前言 - 芯片制造工序详解

    制造工序 芯片简介 工序简介 硅片制造 生产流程 行业壁垒 IC设计 设计流程 行业壁垒 芯片制造 封装测试 制造流程 封装测试 行业壁垒 九大核心设备 参考文档 芯片简介 种类 1 按照性质 数字 模拟芯片 2 按照用途 计算机 家电 手
  • 对象检测工具包mmdetection简介、安装及测试代码

    mmdetection是商汤和港中文大学联合开源的基于PyTorch的对象检测工具包 属于香港中文大学多媒体实验室open mmlab项目的一部分 该工具包提供了已公开发表的多种流行的检测组件 通过这些组件的组合可以迅速搭建出各种检测框架
  • 常用序列的MATLAB代码(一)

    1 典型序列函数 1 单位冲激序列 function x n impseq n0 ns nf ns 序列的起点 nf 序列的终点 n0 序列在n0处有一个单位脉冲 x 产生的单位采样序列 n 产生序列的位置信息 n ns nf x n n0
  • vue-cli 3.0 使用 npm 报错

    问题 vue cli 3 0 使用 npm 报错 最近 vue 项目打算 使用 vue cli 3 0 生成模板 全部默认 配置 生成模板后 使用了 npm 安装依赖后 项目不能正常运行 看npm install 后的执行 代码 好像在 不
  • 老孙的爬虫(四)-------储存多层次的数据,使用递归不断请求,设置id与p_id确定数据的父子关系

    测试网站 https d qianzhan com xdata list xfyyy0yyIxPyywyy2xDxfd html 数据的储存要求 储存的数据能看出父子关系 思路 因为该网站数据是层层打开的 使用递归不断请求 需要额外储存一些
  • PB错误代码

    string ls msgchoose case error number case 1 by zero ls msg 发生被 0 除错误 case 2 2 Null object reference ls msg 空对象引用 case 3
  • 自动实现的属性-Auto-Implemented Properties

    自动实现的属性 C 编程指南 2015 07 20 作者 在 C 3 0 及更高版本 当属性访问器中不需要任何其他逻辑时 自动实现的属性会使属性声明更加简洁 它们还允许客户端代码创建对象 当你声明以下示例中所示的属性时 编译器将创建仅可以通
  • 影视剪辑,视频剪辑流程,如何进行混剪

    一个人如何在家自学剪辑 今天经验分享来啦 视频剪辑流程 一 建立好项目文件夹 根据时间 地点 大体拍摄内容等分类 在不同的文件夹存入对应的物料和工程 二 获取素材 提前收集好要用的包装素材与音乐网站 进行及时补充素材 三 回看和分类 按照脚
  • 磁链

    1 定义 为通电线圈的匝数与磁通量的乘积 通常用 lambda 或 psi 标记 即 N 或 N 其国际单位制单位与磁通量同为韦伯 由于法拉第对电磁学的解释 一个线圈的磁链也可以表示为通过线圈的电压对其时间的积分 即 因此其单位也可以用伏特
  • 阿里云SDK上传视频

    1 老样子 先看效果图 2 首先到阿里云下载所需要用到的SDK 3 下载好的 解压之后 目录以及运行起来是以下这个样子的 4 在实际项目中引用 先将SDK添加到项目中 放到public目录下 5 在public文件下的index html引
  • GDI映射:设备坐标与逻辑坐标

    1 设备坐标 对显示器而言就是屏幕 其单位是像素 对打印机而言就是打印机的像素点 这个坐标与具体的设备相关 所以叫设备坐标 目前用到的就是显示器的像素 显示器的设备坐标有三种 屏幕坐标 窗口坐标 客户区坐标 屏幕坐标 以整个屏幕为显示区 屏
  • BoT-SORT与Strong-SORT论文对比及思考总结

    BoT SORT与Strong SORT论文对比及思考总结 接上篇BoT SORT论文阅读笔记 并对Strong SORT论文研读与BoT SORT的更新点对比有了以下的思考总结 Strong SORT论文 Strong SORT代码 通过
  • ES学习笔记

    01 REST 指的是客户端和服务器之间的交互在请求之间是无状态的 从客户端到服务器的每个请求都必须包含理解请求所必须的信息 同时在请求之间的任意间隔时间点 若服务器重启 那么客户端是得不到相应的通知的 所以无状态的请求可以由任何可用的服务
  • 在MacOS构建Python深度学习开发环境

    目录 构建环境 Step 1 搭建初始环境 安装Homebrew 安装Pyenv Step 2 构建开发环境 安装多版本Python 设置虚拟环境 Step 3 完善Python开发环境 训练测试 Step 1 下载源代码 Step 2 准
  • python数据挖掘分析案例_基于Python的Titanic【案例分析】

    这次数据分析的案例是 经典的数据分析案例 泰坦尼克号生还预测 本案例的分析思路包括以下三个部分 数据集描述与来源展示 数据分析过程 明确分析问题 理解数据 数据清洗 数据探索性分析 数据建模与分析 模型选择与结果输出 数据分析总结 数据集描
  • python 计算置信区间,计算置信区间(示例代码)

    proc freq data datain by group tables var missprint nowarn binomial level 1 cl exact alpha 0 05 weight n zero 对发生的做置信区间
  • C语言数据结构之链表的增删改查

    C语言数据结构之链表的增删改查 tips 昨天学习了c语言结构体 今天来看看c语言数据结构之链表 单链表 的增删改查操作 首先我们创建一个简单的学生信息结构体 作为后面增删改查的主体 student结构体包含 数据域 学号 分数 指针域 一