PTA | 结构体链表相关题目

2-1

对于以下结构定义,p->str++中的++加在( )。

struct { int len; char * str; } *p;

  1. 指针str

  2. 指针p

  3. str指针指向的内容上

  4. 语法错误

GPT

在这个结构体定义中,p 是一个指向该结构体的指针。结构体包含一个整型成员 len 和一个字符指针 str。当执行 p->str++ 时,这个操作会影响到:

C. str指针指向的内容上

解释如下:

p->str 访问的是 p 所指向的结构体中的 str 成员。

++ 操作符应用在 p->str 上,意味着增加 str 指针的值。在这种情况下,str 是一个字符指针,所以 ++ 会使它前进到它当前指向的字符串中的下一个字符。

因此,p->str++ 操作会改变 str 指针的值,使其指向下一个字符。所以正确答案是 C. str指针指向的内容上

2-2

下面定义结构变量的语句中错误的是( )。

  1. struct student { int num; char name[20]; } s;

  2. struct { int num; char name[20]; }s;

  3. struct student { int num; char name[20]; }; struct student s;

  4. struct student {int num; char name[20]; }; student s;

GPT

在这些选项中,错误的定义语句是:

D. struct student {int num; char name[20]; }; student s;

这个选项中的错误在于,当在C语言中定义一个结构体变量时,需要在类型名前加上关键字 struct,除非使用了 typedef 创建了一个别名。在选项D中,student 后面没有 struct 关键字,这在标准C语言中是不正确的。正确的声明应该是 struct student s;

其他选项的解释如下:

A. 正确地定义了一个名为 sstruct student 类型的变量。

B. 正确地定义了一个匿名结构体,并创建了这个结构体类型的一个变量 s

C. 首先定义了一个名为 struct student 的结构体类型,然后创建了这个类型的一个变量 s

所以,错误的选项是 D。

2-3

下列关于typedef 的叙述错误的是()。

  1. typedef可以增加新类型

  2. typedef只是将已存在的类型用一个新的名字来代表

  3. typedef可以为各种类型说明一个新名, 但不能用来为变量说明一个新名

  4. typedef为类型说明一个新名, 通常可以增加程序的可读性

GPT

在这些关于 typedef 的叙述中,错误的是:

A. 用 typedef可以增加新类型

解释如下:

A. typedef 并不创建一个新的类型,它只是为已经存在的类型提供了一个新的名称。这是一种方便的别名机制,但并不引入新的数据类型。

B. 正确。这是 typedef 的基本功能——为已经存在的类型定义一个新的名字。

C. 正确。typedef 用于为类型定义新名字,而不是用于变量。例如,你不能用 typedef 直接为一个特定的变量赋予别名。

D. 正确。typedef 的一个主要用途是增加代码的可读性和可维护性,特别是对于复杂的类型定义,如函数指针或复杂的结构体。

因此,错误的叙述是 A.

6-1 结构体数组中按关键字查找满足条件的数据节点

struct student{
    int num;
    char name[20];
    int score;
};

typedef struct student stu;

有上面面学生记录类型定义,定义函数在一组学生记录中找成绩最低的学生信息,最低分唯一

函数接口定义:

stu fun( stu  a[] )

数组a里存储N个学生记录,返回值是最低分记录

裁判测试程序样例:

在这里给出函数被调用进行测试的例子。例如:

#include <stdio.h>
#define N  10
stu fun( stu  a[] )int main()
{
    stu a[N], min;
    int i;
    for (i=0;i<N;i++)
        scanf("%d%s%d",&a[i].num,a[i].name,&a[i].score);
    min=fun(a);
printf("%d %s %d",min.num,,min.name,min.score);
}


/* 请在这里填写答案 */

输入样例:

在这里给出一组输入。例如:

1 a01 62
2 a02 56
3 a03 77
4 aaa 66
5 bbb 78
11 a01 62
12 a02 57
13 a03 77
14 aaa 96
15 bbb 78

输出样例:

在这里给出相应的输出。例如:

2 a02 56

Code

#include <stdio.h>
#define N 10
struct student{
    int num;
    char name[20];
    int score;
};

typedef struct student stu;

stu fun(stu a[]);

int main()
{
    stu a[N], min;
    int i;
    for (i = 0; i < N; i++)
        scanf("%d%s%d", &a[i].num, a[i].name, &a[i].score);
    min = fun(a);
    printf("%d %s %d", min.num, min.name, min.score);
}

stu fun(stu a[])
{
    stu min;
    min.score=100;
    for(int i=0;i<N;i++){
        if(a[i].score<min.score){
            min=a[i];
        }
    }
    return min;
}

6-2 学生成绩的统计

有N名学生,每个学生的数据包括学号、姓名、数学成绩、语文成绩,从键盘输入N名学生的数据,并计算出每个学生的平均成绩,最后显示最高平均分的学生的信息,包括学号,姓名,两门课的成绩,平均分数(保留小数点后一位)。需要完成两个函数;

函数接口定义:

void InputData(STU *p,int num);
STU *FindMaxIndex(STU *p,int num);

裁判测试程序样例:

在这里给出函数被调用进行测试的例子。例如:

#include <stdio.h>
#define N 5
typedef struct
{
    int id;
    char name[20];
    int math;
    int chinese;
    double aver;
}STU;
void InputData(STU *p,int num);
STU *FindMaxIndex(STU *p,int num);
int main(void)
{
    STU classone[N];
    STU *pmax;
    InputData(classone,N);
    pmax=FindMaxIndex(classone,N);
    printf("maxinfo:%d %s %d %d %.1f\n",pmax->id,pmax->name,pmax->math,pmax->chinese,pmax->aver);
    return 0;
}

/* 请在这里填写答案 */

输入样例:

2 张 78 34
1 李 67 89
4 王 90 67
3 刘 85 95
5 赵 56 89

输出样例:

maxinfo:3 刘 85 95 90.0

Code

#include <stdio.h>
#define N 5
typedef struct
{
    int id;
    char name[20];
    int math;
    int chinese;
    double aver;
}STU;

void InputData(STU *p,int num);
STU *FindMaxIndex(STU *p,int num);

int main(void)
{
    STU classone[N];
    STU *pmax;
    InputData(classone,N);
    pmax=FindMaxIndex(classone,N);
    printf("maxinfo:%d %s %d %d %.1f\n",pmax->id,pmax->name,pmax->math,pmax->chinese,pmax->aver);
    return 0;
}

void InputData(STU *p,int num){
    for(STU *i=p;i<p+num;i++){
        scanf("%d%s%d%d",&i->id,i->name,&i->math,&i->chinese);
        i->aver=(i->chinese+i->math)/2.0;
    }
}

STU *FindMaxIndex(STU *p,int num){
    STU *res=p;
    for(STU *i=p;i<p+num;i++){
        if(i->aver>res->aver) res=i;
    }
    return res;
}

6-3 链表-创建链表

本题要求实现一个函数,建立一个链表,返回头指针(即头节点地址)

head是链表的头指针,链表上节点的定义如下:

struct node
{char ch;
struct node * next;}

链表上节点的数据成员ch按顺序赋值0,1,2,3......至n-1

函数接口定义:

在这里描述函数接口。例如:

struct node *setlink(int n);

n 是节点个数,返回值是头指针

裁判测试程序样例:

在这里给出函数被调用进行测试的例子。例如:

#include <stdio.h>
#include<stdlib.h>
struct  node
{int ch;
struct node * next;}; 
int countnode(struct node * head);//此函数功能遍历链表,已定义

struct node *setlink(int N);//在代码区定义此函数

int main()
{
int i,N;
struct node *head; 
scanf("%d",&N); 
head=setlink(N);
printf("%d", countnode(head));
return 0;
}
  

/* 请在这里填写答案 */

输入样例:

在这里给出一组输入。例如:

5

输出样例:

在这里给出相应的输出。例如:

10

Code

#include <stdio.h>
#include <stdlib.h>
struct node
{
    int ch;
    struct node *next;
};
int countnode(struct node *head); // 此函数功能遍历链表,已定义

struct node *setlink(int N); // 在代码区定义此函数

int main()
{
    int i, N;
    struct node *head;
    scanf("%d", &N);
    head = setlink(N);
    printf("%d", countnode(head));
    return 0;
}

struct node *setlink(int n)
{
    struct node *p = (struct node *)malloc(sizeof(struct node));
    if (n > 0)
    {
        p->ch = n-1;
        p->next = setlink(n - 1);
    }
    else
    {
        p->ch = n;
        p->next = NULL;
    }
    return p;
}

6-4 删除链表中的重复数据

程序的功能是:逆序创建一个键值为整数的链表 L,编程实现将其中绝对值重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须按照原来顺序保存在另一个链表中。例如给定 链表L的各键值为 21→-15→-15→-7→15,则输出去重后的链表: 21→-15→-7,以及被删除的结点链表: -15→15。

函数接口定义:

struct ListNode *Createlist(int n);
struct ListNode *Del_absrepeat( struct ListNode **head );
void Printlist(struct ListNode *head);

其中 nhead 都是用户传入的参数。 n 的值不超过int的范围,表示创建的链表结点数; head 是链表的头指针。 输入时在第一行给出 L 的结点总数n。随后输入n个整数值,链表按输入数据的逆序建立。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *Createlist(int n);
struct ListNode *Del_absrepeat( struct ListNode **head );
void Printlist(struct ListNode *head);
int main()
{
    struct ListNode *head = NULL,*head2=NULL;
    int n;
    scanf("%d",&n);
    head = Createlist(n);
    printf("原始链表:");
    Printlist(head);
        
   head2=Del_absrepeat( &head );
   printf("删除重复结点的链表:");
   Printlist(head);
    
   printf("被删除的结点组成的链表:");
   Printlist(head2);
   return 0;
}

void Printlist(struct ListNode *head)
{
    struct ListNode *p;
    for ( p = head; p != NULL; p = p->next )
            printf("%d ", p->data);
        printf("\n");
}

/* 请在这里填写答案 */

输入样例:

5
21 -15 -15 -7 15

输出样例:

原始链表:15 -7 -15 -15 21 
删除重复结点的链表:15 -7 21 
被删除的结点组成的链表:-15 -15 

输入样例:

7
15 -15 -15 -15 15 -15 15 

输出样例:

原始链表:15 -15 15 -15 -15 -15 15 
删除重复结点的链表:15 
被删除的结点组成的链表:-15 15 -15 -15 -15 15 

Code

#include <stdio.h>
#include <stdlib.h>
struct ListNode
{
    int data;
    struct ListNode *next;
};

struct ListNode *Createlist(int n);
struct ListNode *Del_absrepeat(struct ListNode **head);
void Printlist(struct ListNode *head);
int main()
{
    struct ListNode *head = NULL, *head2 = NULL;
    int n;
    scanf("%d", &n);
    head = Createlist(n);
    printf("原始链表:");
    Printlist(head);

    head2 = Del_absrepeat(&head);
    printf("删除重复结点的链表:");
    Printlist(head);

    printf("被删除的结点组成的链表:");
    Printlist(head2);
    return 0;
}

void Printlist(struct ListNode *head)
{
    struct ListNode *p;
    for (p = head; p != NULL; p = p->next)
        printf("%d ", p->data);
    printf("\n");
}

struct ListNode *Createlist(int n){
    struct ListNode *later=(struct ListNode *)malloc(sizeof(struct ListNode));
    scanf("%d",&later->data);
    later->next=NULL;
    for(int i=1;i<n;i++){
        struct ListNode *node=(struct ListNode *)malloc(sizeof(struct ListNode));
        node->next=later;
        scanf("%d",&node->data);
        later=node;
    }
    return later;
}

struct ListNode *Del_absrepeat(struct ListNode **head){
    int repeated[1000],index=0;
    struct ListNode *res=NULL,*cur=*head;
    struct ListNode *pre;
    while(cur!=NULL){
        int i;
        for(i=0;i<index;i++){
            if(abs(cur->data)==repeated[i]){
                break;//删除节点
            }
        }
        if(i!=index){
            pre->next=cur->next;//删除该节点
            if(res==NULL){
                res=cur;
            }else{
                struct ListNode *temp=res;
                while(temp->next!=NULL){
                    temp=temp->next;
                }
                temp->next=cur;
            }
            cur->next=NULL;
            cur=pre->next;
        }else{
            repeated[index++]=abs(cur->data);
            pre=cur;
            cur=cur->next;
        }
    }
    return res;
}

7-1 学车费用

小明学开车后,才发现他的教练对不同的学员收取不同的费用。

小明想分别对他所了解到的学车同学的各项费用进行累加求出总费用,然后按下面的排序规则排序并输出,以便了解教练的收费情况。排序规则:

  • 先按总费用从多到少排序,若总费用相同则按姓名的ASCII码序从小到大排序,若总费用相同而且姓名也相同则按编号(即输入时的顺序号,从1开始编)从小到大排序。

输入格式:

测试数据有多组,处理到文件尾。每组测试数据先输入一个正整数\(n(n≤20)\),然后是\(n\)行输入,第\(i\)行先输入第\(i\)个人的姓名(长度不超过10个字符,且只包含大小写英文字母),然后再输入若干个整数(不超过10个),表示第i个人的各项费用(都不超过13000),数据之间都以一个空格分隔,第i行输入的编号为\(i\)

输出格式:

对于每组测试,在按描述中要求的排序规则进行排序后,按顺序逐行输出每个人费用情况,包括:费用排名(从1开始,若费用相同则排名也相同,否则排名为排序后的序号)、编号、姓名、总费用。每行输出的数据之间留1个空格。

输入样例:

3
Tom 2800 900 2000 500 600
Jack 3800 400 1500 300
Tom 6700 100
3
Tom 2800 400 100
Jack 3800 800
mary 3300

输出样例:

1 1 Tom 6800
1 3 Tom 6800
3 2 Jack 6000
1 2 Jack 4600
2 1 Tom 3300
2 3 mary 3300

Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct stu{
    int index;
    char name[100];
    int cost;
}stu[30];

int cmp(const void *aa,const void *bb){
    struct stu *a=(struct stu*)aa;
    struct stu *b=(struct stu*)bb;
    if(a->cost == b->cost){
        return strcmp(a->name,b->name);
    }
    return a->cost < b->cost;
}

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        getchar();
        for(int i=0;i<n;i++){
            int sum=0;
            char line[1000];
            stu[i].index=i;
            fgets(line,1000,stdin);
            strcpy(stu[i].name,strtok(line," "));
            char *token;
            while((token=strtok(NULL," \n"))!=NULL){
                sum+=atoi(token);
            }
            stu[i].cost=sum;
        }
        qsort(stu,n,sizeof(struct stu),cmp);
        if(n>0){
            int pre_cost=stu[0].cost,pre_rank=1,rank=1;
            for(int i=0;i<n;i++){
                if(pre_cost==stu[i].cost){
                    rank=pre_rank;
                }else{
                    rank=i+1;
                    pre_rank=rank;
                }
                printf("%d %d %s %d\n",rank,stu[i].index+1,stu[i].name,stu[i].cost);
                pre_cost=stu[i].cost;
            }
        }
        
    }
    
    return 0;
}

7-2 学生成绩录入及查询

学生成绩表中,一名学生的信息包含如下信息:

学号(11位)、姓名、数学成绩、英语成绩、程序设计成绩、物理成绩。

本题要求编写程序,录入N条学生的信息,并且按查询要求显示学生成绩等信息。

输入格式:

输入在第一行给出正整数N(N<=10);随后N行,每行按格式:

学号 姓名 数学成绩 英语成绩 程序设计成绩 物理成绩

给出一名学生的信息。

其中学号是11位数字;姓名是不超过10个字符、不包含空格的非空字符串;成绩是<=100的非负整数;

在学生信息输入完成后,给出要查询的姓名。

输出格式:

对查询的姓名的每一名学生,在一行中按照如下格式输出:

学号  姓名 数学成绩 英语成绩 程序设计成绩 物理成绩

如果有相同姓名的同学,输出全部同学的信息,每名同学一行; 如果要查询的学生不存在,则输出:

Not Found!

输入样例:

在这里给出一组输入。例如:

4
20201003012 LiWen 68 90 78 86
20201003012 HeHua 91 88 80 82
20201002121 WangFang 78 78 82 90
20201002112 ZhengYi 56 83 77 80
ZhengYi

输出样例:

在这里给出相应的输出。例如:

20201002112 ZhengYi 56 83 77 80

Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct stu{
    char num[20];
    char name[20];
    int s1,s2,s3,s4;
}stu[20];

int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%s%s%d%d%d%d",stu[i].num,stu[i].name,&stu[i].s1,&stu[i].s2,&stu[i].s3,&stu[i].s4);
    }
    char name[20];
    while(scanf("%s",name)!=EOF){
        int flag=0;
        for(int i=0;i<n;i++){
            if(!strcmp(name,stu[i].name)){
                printf("%s %s %d %d %d %d\n",stu[i].num,stu[i].name,stu[i].s1,stu[i].s2,stu[i].s3,stu[i].s4);
                flag=1;
            }
        }
        if(flag==0)
            printf("Not Found!\n");
    }
    return 0;
}

7-3 座位安排

在某次上机考试时,座位安排规则如下:

  • 先按考生姓名的字典序排列,若姓名相同则再按学号升序排序;在排好序之后依次从1号机位开始安排座位;
  • 若某个机位的电脑损坏了,则原来安排在该位置上的考生从当前最后一位考生之后的机位开始重新安排。

请根据输入的学生信息及电脑损坏的机位,安排好该次考试的学生座位。

输入格式:

首先输入一个正整数T,表示测试数据的组数。对于每组测试数据,首先输入一个整数 \(n(1<n<=80)\) ,表示考生数;然后输入\(n\)行,每行包含2个以一个空格间隔的字符串,分别表示一个考生的学号(长度不超过10,且仅包含数字字符,可能以0开头)和姓名(长度不超过15,且仅包含英文字母);最后输入一行整数,其中第一个整数\(m(1<=m<=20)\)表示损坏电脑的数量,接着是\(m\)个电脑损坏的机位(不超过\(n\))。

输出格式:

对于每组测试,输出\(n+1\)行,第1行是“Case i:”,其中i是该组测试的序号(从1开始),接着输出\(n\)个座位安排信息“xxx:sno sname”,其中xxx表示以3位整数表示的座位号(不足3位则左补0),sno、sname分别表示该座位上考生的学号和姓名。另外,要求每两组测试之间留一个空行。

输入样例:

2
5
01004 Zhangsan
01002 Lisi
01003 Wangwu
01005 Zhaoliu
01001 Lisi
3 5 1 3
5
1004 Zhangsan
1002 Lisi
1003 Wangwu
1005 Zhaoliu
1001 Lisi
1 5

输出样例:

Case 1:
002:01002 Lisi
004:01004 Zhangsan
006:01001 Lisi
007:01003 Wangwu
008:01005 Zhaoliu

Case 2:
001:1001 Lisi
002:1002 Lisi
003:1003 Wangwu
004:1004 Zhangsan
006:1005 Zhaoliu

提示:

对于样例1

初始安排:

1号位:01001 Lisi
2号位:01002 Lisi
3号位:01003 Wangwu
4号位:01004 Zhangsan
5号位:01005 Zhaoliu

损坏的电脑编号:1 3 5

因1号电脑损坏,01001 Lisi排6号位
因3号电脑损坏,01003 Wangwu排7号位
因5号电脑损坏,01005 Zhaoliu排8号位

最终安排:

2号位:01002 Lisi
4号位:01004 Zhangsan
6号位:01001 Lisi
7号位:01003 Wangwu
8号位:01005 Zhaoliu

Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct stu{
    char name[20];
    char num[15];
}stu[100];

int cmp(const void *aa,const void *bb){
    struct stu *a=(struct stu *)aa;
    struct stu *b=(struct stu *)bb;
    if(!strcmp(a->name,b->name)){
        return strcmp(a->num,b->num);
    }else{
        return strcmp(a->name,b->name);
    }
}

int cmp2(const void *aa, const void *bb){
    int *a=(int*)aa;
    int *b=(int*)bb;
    return *a > *b;
}

int check(int *b,int b_size,int *seat,int seat_size,int stu_size){
    for(int i=0;i<b_size;i++){
        if(*(seat+*(b+i)-1)!=-1){
            *(seat+*(b+i)-1)=-1;
            return *(b+i);
        }
    }
    return -1;
}

int main(){
    int T;
    scanf("%d",&T);
    for(int k=1;k<=T;k++){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%s %s",stu[i].num,stu[i].name);
        }
        qsort(stu,n,sizeof(struct stu),cmp);
        // for(int i=0;i<n;i++){
        //     printf("%s %s\n",stu[i].num,stu[i].name);
        // }
        int m;
        scanf("%d",&m);
        int b[100];
        for(int i=0;i<m;i++){
            scanf("%d",&b[i]);
            b[i]-=1;
        }
        qsort(b,m,sizeof(int),cmp2);
        // for(int i=0;i<m;i++){
        //     printf("%d ",b[i]);
        // }
        int seat[200],index=0;
        memset(seat,-1,sizeof(seat));
        for(int i=0;i<n;i++){
            seat[index++]=i;
        }
        // int temp;
        // while((temp=check(b,m,seat,200,n))!=-1){
        //     seat[index++]=temp;
        // }
        int tomove;
        tomove=b[0];
        while(seat[tomove]!=-1){
            seat[index++]=seat[tomove];
            seat[tomove]=-1;
            int i;
            for(i=0;i<m;i++){
                if(seat[b[i]]!=-1){
                    tomove=b[i];
                    break;
                }
            }
            if(i==m){
                tomove=-1;
                break;
            }
        }
        printf("Case %d:\n",k);
        for(int i=0;i<index;i++){
            if(seat[i]!=-1){
                printf("%03d:%s %s\n",i+1,stu[seat[i]].num,stu[seat[i]].name);
            }
        }
        if(k!=T)
            printf("\n");
    }
    return 0;
}

7-4 单链表基本操作

请编写程序实现单链表插入、删除结点等基本算法。给定一个单链表和一系列插入、删除结点的操作序列,输出实施上述操作后的链表。单链表数据域值为整数。

输入格式:

输入第1行为1个正整数n,表示当前单链表长度;第2行为n个空格间隔的整数,为该链表n个元素的数据域值。第3行为1个正整数m,表示对该链表施加的操作数量;接下来m行,每行表示一个操作,为2个或3个整数,格式为0 k d或1 k。0 k d表示在链表第k个结点后插入一个数据域值为d的结点,若k=0则表示表头插入。1 k表示删除链表中第k个结点,此时k不能为0。注:操作序列中若含有不合法的操作(如在长度为5的链表中删除第8个结点、删除第0个结点等),则忽略该操作。n和m不超过100000。

输出格式:

输出为一行整数,表示实施上述m个操作后的链表,每个整数后一个空格。输入数据保证结果链表不空。

输入样例:

5
1 2 3 4 5
5
0 2 8
0 9 6
0 0 7
1 0 
1 6

输出样例:

7 1 2 8 3 5 

Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define NL struct Nodelist

NL{
    int data;
    NL *next;
};

int main(){
    int n,m,op,k,d;
    scanf("%d",&n);
    NL *head=NULL;
    if(n!=0){
        head=(NL*)malloc(sizeof(NL));
        scanf("%d",&head->data);
        head->next=NULL;
        NL *cur=head;
        for(int i=1;i<n;i++){
            cur->next=(NL*)malloc(sizeof(NL));
            cur=cur->next;
            cur->next=NULL;
            scanf("%d",&cur->data);
        }
    }
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%d",&op);
        if(op==0){
            scanf("%d%d",&k,&d);
            if(k==0){
                NL *node=(NL*)malloc(sizeof(NL));
                node->data=d;
                node->next=head;
                head=node;
            }else{
                NL *cur=head;
                int flag=1;
                for(int i=1;i<k;i++){
                    if(cur==NULL){
                        flag=0;
                        break;
                    }
                    cur=cur->next;
                }
                if(flag){
                    NL *node=(NL*)malloc(sizeof(NL));
                    node->data=d;
                    node->next=cur->next;
                    cur->next=node;
                }
            }
        }
        if(op==1){
            scanf("%d",&k);
            if(k==1){
                head=head->next;
            }else if(k>1){
                NL *cur=head;
                int flag=1;
                for(int i=1;i<k-1;i++){
                    if(cur->next==NULL){
                        flag=0;
                        break;
                    }
                    cur=cur->next;
                }
                if(flag){
                    cur->next=cur->next->next;
                }
            }
        }
    }
    NL *cur=head;
    while(cur!=NULL){
        printf("%d ",cur->data);
        cur=cur->next;
    }
    return 0;
}

7-5 单链表基础应用(4)--单链表逆置

编程实现一个简易学生信息管理系统,按如下步骤分别用自定义函数实现:

    1. 根据输入信息创建单链表并输出所有结点信息。每个学生的信息包括姓名和成绩;
    1. 将上一步创建的单链表逆置后并输出所有结点信息。

输入格式:

根据输入的若干个学生信息创建单链表。每一行代表一个学生信息,以成绩-1作为输入的结束。

输出格式:

每个学生信息占一行,姓名和成绩之间以空格分隔,成绩保留一位小数。 创建链表输出加提示信息:Original 逆置后输出加提示信息:Reversed

输入样例:

在这里给出一组输入。例如:

Wang 87.3
Wang 60.1
Wang 89.5
Li 93.2
Fu 87.5
Wang 78.6
Cheng 89.1
Tang 71.9
Wang 63.1
Fang 81.9
tt -1

输出样例:

在这里给出相应的输出。例如:

Original:
Wang 87.3
Wang 60.1
Wang 89.5
Li 93.2
Fu 87.5
Wang 78.6
Cheng 89.1
Tang 71.9
Wang 63.1
Fang 81.9

Reversed:
Fang 81.9
Wang 63.1
Tang 71.9
Cheng 89.1
Wang 78.6
Fu 87.5
Li 93.2
Wang 89.5
Wang 60.1
Wang 87.3

Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct stu{
    char name[20];
    char score[10];
}stu[100];

int main(){
    int index=0;
    while(scanf("%s%s",stu[index].name,stu[index].score)){
        if(!strcmp(stu[index].score,"-1")){
            break;
        }
        index++;
    }
    printf("Original:\n");
    for(int i=0;i<index;i++){
        printf("%s %s\n",stu[i].name,stu[i].score);
    }
    printf("\nReversed:\n");
    for(int i=index-1;i>=0;i--){
        printf("%s %s\n",stu[i].name,stu[i].score);
    }
    return 0;
}

PTA | 结构体链表相关题目
https://acm.nanyan.cc/posts/3355.html
作者
nanyan
发布于
2023年12月19日
许可协议