初步链表的实现:建立链表的函数creat 输出链表的函数print 删除链表中结点的函数del 插入结点的函数insert,再编写一个主函数, 先后调用

#include<stdio.h>
#include<stdlib.h>//这个头文件提供了一些常用的函数,例如内存分配、伪随机数生成、整数转换等。
//常见的函数包括malloc(内存分配)、free(释放内存)、rand和srand(产生伪随机数)
//以及一些实用的类型转换函数,比如atoi和atof等
#define LEN sizeof(struct Student)
/*这段代码使用了`sizeof`运算符来计算`struct Student`类型的大小,并将结果定义为`LEN`
`sizeof`运算符用于计算数据类型或变量在内存中所占用的字节数
在这里,`sizeof(struct Student)`返回的是结构体`Student`的大小。
通过`#define`预处理指令,将`LEN`定义为`sizeof(struct Student)`的结果
可以在后续代码中使用`LEN`来表示结构体`Student`的大小,避免了直接写硬编码的字节数。
注意,这段代码只是定义了`LEN`的值,并没有给出`struct Student`的具体定义和使用场景
在实际使用中,必须在代码中定义`struct Student`并赋予合适的值才能得到准确的结果
*/

struct Student{
	long num;
	float score;
	struct Student *next;
};

int n;//用于记录链表中结点的个数

//创建链表
//定义一个名为creat的函数,该函数接受一个指向Student结构体的指针head作为参数
//并返回一个指向Student结构体的指针
struct Student *creat(struct Student *head)
{
	struct Student *p1, *p2;
	n = 0;
	p1 = p2 = (struct Student *)malloc(LEN);
	//动态分配内存空间,使得p1和p2都指向一个新的Student结构体
	//然后将其赋值给head指针所指向的结构体的next成员,即将这个结构体设为头结点
	scanf("%ld,%f", &p1->num, &p1->score);
	while (p1->num != 0)
	{
		n = n + 1;
		if (n == 1)head->next = p1;//如果是第一个结点,将其设为头结点。否则,执行下一步
		else p2->next = p1;//将当前结点连接到上一个结点的后面
		p2 = p1;//将p2指向当前结点,以备下一次循环使用
		p1 = (struct Student *)malloc(LEN);//动态分配内存空间,使得p1指向一个新的Student结构体,准备读入下一个学生的信息
		scanf("%ld,%f", &p1->num, &p1->score);
	}
	p2->next = NULL;//将最后一个结点的next成员设为NULL,表示链表的末尾
	return (head);//返回头结点的指针
}
//输出链表 
//定义了一个名为print的函数,该函数接受一个指向Student结构体的指针head作为参数
//并且不返回任何数值。
void print(struct Student *head)
{
	struct Student *p;
	printf("\nNow,These %d records are:\n", n);
	p = head->next;//将指针p指向链表中的第一个实际数据节点,即跳过头结点
	if (head != NULL)//首先检查头结点是否为空,防止空指针错误
	{
		do
		{
			printf("%ld %5.1lf\n", p->num, p->score);
			p = p->next; //将指针p移动到下一个节点
		} while (p != NULL);//使用do-while循环来遍历链表
	}
}
//删除链表中节点
//定义了一个名为del的函数,该函数接受一个指向Student结构体的指针head和一个long类型参数a作为输入
//并且不返回任何值。
void del(struct Student *head, long a)
{
	struct Student *p, *q;
	p = q = head;//将p和q都指向链表的头结点
	int flag = 0; //用于标记是否找到要删除的学生信息
	while (p)
	{
		if (head->num == a)// 如果头结点的学号等于要删除的学号`a`
		{
			q = head->next; //则将`q`指向头结点的下一个节点
			head = q;//然后更新`head`指针为`q`
		}//相当于删除了头结点
		if (p->num == a)//如果当前节点的学号等于要删除的学号`a`
		{//则进入内部循环
			while (q->next != p)//则进入内部循环
				q = q->next;//将`q`移动到要删除节点的前一个节点
			q->next = p->next; //然后将其`next`指针指向要删除节点的下一个节点
			flag = 1;//相当于删除了当前节点
		}
		p = p->next;// 将指针`p`移动到下一个节点
	}
	if (flag == 0)
	{
		printf("no find!\n");
	}
	else
	{
		printf("succeed!");
		n = n - 1;//注意不要遗漏链表节点数减一
	}
}
//插入结点 
//定义了一个名为insert的函数,该函数接受一个指向Student结构体的指针head、一个指向要插入的节点的指针p,以及一个整型变量site表示要插入的位置
//该函数不返回任何值
void insert(struct Student *head, struct Student *p, int site)
{
	struct Student *q;
	q = head; //将指针q指向链表的头结点
	int flag = 0, m;
	if (site >= 1)
	{
		//找到插入位置的前一个结点 
		for (m = 1; m < site; m++)//使用for循环找到要插入位置的前一个节点。
		{
			q = q->next;//循环体内部将指针q移动到目标位置的前一个节点。
		}
		//开始插入
		p->next = q->next; //将要插入的节点p的next指针指向q节点的下一个节点,即将p插入到q之后
		q->next = p;//将q节点的next指针指向要插入的节点p,完成插入操作
		flag = 1;
	}
	if (flag == 0)
	{
		printf("no find!\n");
	}
	else
	{
		printf("succeed!");
		n = n + 1;
	}

}
int main()
{
	struct Student *head;
	long a;
	struct Student *p;
	int site;

	head = (struct Student *)malloc(LEN);
	//为head分配了内存空间,大小为LEN。并且初始化了头结点的学号和分数为0,next指针为NULL
	head->num = 0;
	head->score = 0;
	head->next = NULL;
	creat(head);
	print(head);

	printf("please enter the student's student number to delete:");
	scanf("%ld", &a);
	del(head, a);
	print(head);

	printf("please enter the student's data to insert:");
	p = (struct Student *)malloc(LEN);
	scanf("%ld,%f", &p->num, &p->score);
	printf("please enter the loction to insert:");
	scanf("%d", &site);
	insert(head, p, site);
	print(head);
}

运行结果: 

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值