本文最后更新于 35 天前,其中的信息可能已经有所发展或是发生改变。
本题来自 PTA 浙江大学 C课程组
题面
题要求实现两个函数,一个将输入的学生成绩组织成单向链表;另一个将成绩低于某分数线的学生结点从链表中删除。
函数接口定义:
struct stud_node *createlist();
struct stud_node *deletelist( struct stud_node *head, int min_score );
函数createlist
利用scanf
从输入中获取学生的信息,将其组织成单向链表,并返回链表头指针。链表节点结构定义如下:
struct stud_node {
int num; /*学号*/
char name[20]; /*姓名*/
int score; /*成绩*/
struct stud_node *next; /*指向下个结点的指针*/
};
输入为若干个学生的信息(学号、姓名、成绩),当输入学号为0时结束。
函数deletelist
从以head
为头指针的链表中删除成绩低于min_score
的学生,并返回结果链表的头指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
struct stud_node {
int num;
char name[20];
int score;
struct stud_node *next;
};
struct stud_node *createlist();
struct stud_node *deletelist( struct stud_node *head, int min_score );
int main()
{
int min_score;
struct stud_node *p, *head = NULL;
head = createlist();
scanf("%d", &min_score);
head = deletelist(head, min_score);
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
80
输出样例:
2 wang 80
4 zhao 85
个人解法
按照班级教师指导思路填写,仅供参考
struct stud_node *createlist(){
struct stud_node *this,*head;//head为头指针,this为操作游标
this = NULL;
head = NULL;
while(1){
int nnum,nscore;
char nname[20];
scanf("%d",&nnum);
if(nnum == 0){
break; //如果输入0则跳出循环,链表构建完毕
}
scanf(" %s %d\n",nname,&nscore);
//创建新节点
struct stud_node *newNode;
newNode = (struct stud_node *)malloc(sizeof(struct stud_node));
//构建节点数据
newNode->num = nnum;
strcpy(newNode->name,nname);
newNode->score = nscore;
//将节点接入链表
if (head == NULL){
head = newNode;//如果head头指针为空,则说明刚才创建的是第一个节点,那么将head头指针指向刚才创建的新节点
} else {
this->next = newNode;//如果head头指针不为空,则将上一个游标所在节点的下一个节点,设置为我们刚才创建的新节点
}
this = newNode;//游标移动到刚创建的新节点
}
//输入结束,链表构建完毕,返回头指针
return head;
}
struct stud_node *deletelist( struct stud_node *head, int min_score ){
struct stud_node *this,*prev,*nhead;//nhead为新链表头指针,this为操作游标,prev为上次操作游标
this = head;//默认从第一个节点开始处理
nhead = head;//默认不改变原链表头指针,除非有其他情况(见下)
prev = NULL;//初始没有上一个游标
while(this != NULL){//循环直到游标为空,即循环到链表最后一项
if (this->score < min_score){
if(this == nhead){
nhead = this->next;//如果要删除的一项在链表头,则将头指针指向下一位,否则头指针会指向不存在的一项
} else {
prev->next = this->next;//将上一项与下一项连接起来,当前游标处理项被跨越
}
} else {
prev = this;//如果不需要删除这一项,则跳过处理,移动游标
}
this = this->next;//移动游标
}
return nhead;//返回实际头指针
}