一,介绍
此次属于是上强度了,键盘一次性输入n个学生链表信息:学号,姓名,分数。让它从小到大排序后输出
二,代码
#include <stdio.h>
#include <stdlib.h>
typedef struct stu // 结构体取别名为STU
{
int num;
char name[32];
float score;
struct stu *next;//指针域
} STU;
STU *insert_link(STU *head, STU *tmp, int n)
//用这整个函数把链表给按顺序填好,也把链表头指针head给弄出来
{
for (int i = 0; i < n; i++)
{
STU *pi = (STU *)malloc(sizeof(STU));
if (pi == NULL)//如果申请的空间为空,则返回
{
printf("malloc error\n");
return head;
}
*pi = tmp[i];//外边键盘输入学生信息给到pi
pi->next = NULL;//定义pi的指针域为空
if (head == NULL)//如果头指针为空
{
head = pi;//那么head就给pi,这部分就循环一次,后面这个就不循环了
//第一次必循环,让head指向pi
}
else//此处则是第一次之后的循环才执行这一步,这个时候链表有两个值了,头指针也不为空
{
STU *pb = head, *pf = head;
while ((pb->num < pi->num) && (pb->next != NULL))
//此处while循环,第一个循环条件是链表从小到大排序
//第二个循环条件是指针指向空了
{
pf = pb;//pf在后
pb = pb->next;//pb在前
}
if (pb->num >= pi->num)//如果插入值在头中部,也分下面两种情况
{
if (pb == head)//在头部
{
pi->next = head;//指针指向(连线)
head = pi;
}
else//在中部
{
pi->next = pb;//指针指向(连线)
pf->next = pi;//指针指向(连线)
}
}
else//在尾部
{
pb->next = pi;//指针指向(连线)
}
}
}
return head;//循环到这了,说明循环结束了
//链表里边各个位指针的指向都从从小到大指向好了,把头指针head返回出去
}
void test01()
{
int n;
printf("请输入学员个数:");
scanf("%d", &n);
STU *head = NULL;
STU tmp[n];
printf("请输入%d个学员信息\n", n);
for (int i = 0; i < n; i++)
{
scanf("%d %s %f", &tmp[i].num, tmp[i].name, &tmp[i].score);
}
head = insert_link(head, tmp, n);
//head值有了,开始循环遍历
if (head == NULL)//也要分两种情况,第一种,head为空地址
{
printf("link not exist\n");
}
STU *pb = head;
while (pb != NULL)//2.head不为空,开始遍历
{
printf("%d %s %f\n", pb->num, pb->name, pb->score);
pb = pb->next;
}
}
int main(int argc, char const *argv[])
{
test01();
return 0;
}
三,输出结果
四,详细解析
代码里边复制下来,里边都有我个人观点,下边是一个大致框架
-
首先,定义了一个结构体
stu
,表示学生的信息,包括学号、姓名和分数。结构体中还有一个指针域next
,用于指向下一个节点。 -
insert_link
函数用于将学生信息按照学号的顺序插入链表中,并返回链表的头指针head
。该函数接受三个参数:链表的头指针head
、学生信息数组tmp
和学生个数n
。 -
在
insert_link
函数中,首先使用malloc
函数为新节点pi
分配内存空间,并将学生信息复制给新节点。 -
如果链表为空(头指针为
NULL
),则将新节点指定为头节点。 -
如果链表不为空,则需要找到合适的位置插入新节点。通过循环遍历链表,并使用两个指针
pb
和pf
来记录当前节点和前一个节点。 -
在循环中,比较当前节点的学号和新节点的学号,找到合适的位置插入新节点。如果新节点的学号小于当前节点的学号,则需要将新节点插入到当前节点的前面。
-
如果新节点需要插入到头部,则将新节点的
next
指针指向原来的头节点,并将新节点设为新的头节点。 -
如果新节点需要插入到中间或尾部,则将新节点的
next
指针指向当前节点,并将前一个节点的next
指针指向新节点。 -
在
test01
函数中,首先获取学生个数,并声明一个链表的头指针head
和一个临时数组tmp
来存储学生信息。 -
然后,通过循环从键盘输入学生信息,并将学生信息存储在临时数组
tmp
中。 -
调用
insert_link
函数将学生信息按照学号顺序插入链表,并将返回的头指针赋值给head
。 -
最后,根据头指针
head
的值判断链表是否存在。如果链表为空,则输出提示信息;否则,通过循环遍历链表,并输出每个节点的学生信息。