同志们好,以下是本人对建立学生信息链表题目的个人看法,有不足之处,烦请斧正。
ps:这篇文章应该是我耗时最长的一篇,干货满满
题目来源:PTA
编程语言:C
题目类型:函数题
题目重述:
本题要求实现一个将输入的学生成绩组织成单向链表的简单函数。
函数接口定义:
void input();
该函数利用scanf
从输入中获取学生的信息,并将其组织成单向链表。链表节点结构定义如下:
struct stud_node {
int num; /*学号*/
char name[20]; /*姓名*/
int score; /*成绩*/
struct stud_node *next; /*指向下个结点的指针*/
};
单向链表的头尾指针保存在全局变量head
和tail
中。
输入为若干个学生的信息(学号、姓名、成绩),当输入学号为0时结束。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stud_node {
int num;
char name[20];
int score;
struct stud_node *next;
};
struct stud_node *head, *tail;
void input();
int main()
{
struct stud_node *p;
head = tail = NULL;
input();
for ( p = head; p != NULL; p = p->next )
printf("%d %s %d\n", p->num, p->name, p->score);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
1 zhang 78
2 wang 80
3 li 75
4 zhao 85
0
输出样例:
1 zhang 78
2 wang 80
3 li 75
4 zhao 85
解题过程:
解题思路:
1.由节点结构定义知,每个节点存储四个信息,分别为学号,姓名,成绩,指向下个节点的指针
2.我们在函数中首先定义一个指向某一节点的指针node,开辟节点空间,并使该链表为空表,一个节点都没有
3.首先,输入一个节点的学号,若非0,则进入while循环,再输入姓名和分数
4.此时通过判断此链表的尾指针是否为NULL,若是,则说明此时链表为空表,无节点,head和tail均为NULL,则使node节点为头节点(同时也是尾节点,此时只有一个节点),根据单向链表定义,再令尾节点的next指向NULL。此时一个节点的循环结束,再为下一个节点开辟节点空间,并输入该节点储存学号,开启下一个循环
5.下一次循环开始,if语句判断尾指针不为NULL了,则插入节点2在节点1之后,再使节点2储存的next指针指向NULL,此时节点2变成尾节点
ps:我个人认为不用head是否为NULL判断的原因是指针要遍历的次数太多,造成段错误
所求函数:
void input()
{
struct stud_node* node;//先定义一个指针,指向node节点
node = (struct stud_node*)malloc(sizeof(struct stud_node));
//开辟节点空间
scanf("%d", &node->num);
//先输入第一个节点的学号
while (node->num != 0)
{
scanf("%s%d", &node->name, &node->score);
//再输入该节点的姓名,分数
if (tail == NULL)//第一个节点的情况,此时链表为空表
//头节点与尾节点都为空
{
head = node;//使node节点成为头节点同时也是尾节点
//因为只有一个节点
head->next = NULL;//尾节点指向的下一个指针为NULL
}
if (tail != NULL)tail->next = node;//第2,3...n个节点的情况
//此时使用尾插法,在节点1前插入一个节点2
tail = node;//再把尾指针往后遍历一位,尾节点从节点1变成节点2
tail->next = NULL;
node = (struct stud_node*)malloc(sizeof(struct stud_node));
//为新节点开辟空间
scanf("%d", &node->num);
}
}
完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stud_node {
int num;
char name[20];
int score;
struct stud_node* next;
};
struct stud_node* head, * tail;
void input();
int main()
{
struct stud_node* p;
head = tail = NULL;
input();
for (p = head; p != NULL; p = p->next)
printf("%d %s %d\n", p->num, p->name, p->score);
return 0;
}
void input()
{
struct stud_node* node;//先定义一个指针,指向node节点
node = (struct stud_node*)malloc(sizeof(struct stud_node));
//开辟节点空间
scanf("%d", &node->num);
//先输入第一个节点的学号
while (node->num != 0)
{
scanf("%s%d", &node->name, &node->score);
//再输入该节点的姓名,分数
if (tail == NULL)//第一个节点的情况,此时链表为空表
//头节点与尾节点都为空
{
head = node;//使node节点成为头节点同时也是尾节点
//因为只有一个节点
head->next = NULL;//尾节点指向的下一个指针为NULL
}
if (tail != NULL)tail->next = node;//第2,3...n个节点的情况
//此时使用尾插法,在节点1前插入一个节点2
tail = node;//再把尾指针往后遍历一位,尾节点从节点1变成节点2
tail->next = NULL;
node = (struct stud_node*)malloc(sizeof(struct stud_node));
//为新节点开辟空间
scanf("%d", &node->num);
}
}
谢谢观看。