【计导作业】链表——成绩统计2

题目

问题描述:

定义一个学生信息结构,包括姓名、学号和总成绩。从键盘上输入若干学生的信息,学生个数未知,当输入的姓名为“#####”时表示输入结束;学生的总成绩为整数,范围是0—1600,不会出现非法输入。你的任务是分别统计出1400分以上同学的具体信息与人数。学生的姓名中只能包含大小写字母与空格字符,不会超过20个字符;学生的学号是个长度不会超过20的字符串,只包含数字字符。

要求:

在本题中,你要建立一个单链表,并使用该链表存储所有学生的信息。假设最初建立的链表名为ListA,你要将链表ListA中成成绩在1400分以上(含1400分)的节点从ListA中删去,并把这些节点插入到新链表ListB中,最后输出链表ListB中的信息。注意这里不要释放ListA中的节点,然后新建节点插入到ListB中,应该只修改链表节点的指针域。本题所有定义的函数,函数参数与返回值均可根据需要自行定义。程序结束后要释放所有节点占据的空间。

输入与输出要求:输入若干个学生的信息,输入顺序为姓名、学号、总成绩,学生个数未知,当学生姓名为“#####”代表输入结束。输出最终的统计信息,具体格式见样例。注意这里的单词students等一律使用复数形式。

程序运行效果:

Please input the information of the students: 

小王同学

0821131699999

1490

Liu Mengmeng

0821131666666

1495

Albert Einstein

0821131477777

1350

Bill Gates

0821131588888

1101

#####

输出

There are 2 students' score higher than 1400.They are:

Name:小王同学 ID:0821131699999 Score:1490

Name:Liu Mengmeng ID:0821131666666 Score:1495

分析

这题是计导作业,就是要我们写单链表,平时没写过这样的,写这个程序也调了半天-_-||

 

2016.3.24:真是打脸啊,cc同学帮我发现bug了,怎么办,发了好几份有bug的代码给同学们!!

/*
    明天就要去欢乐谷啦!虽然有好多好多没完成的事情,可是总要放松一下啊,忘记所有烦恼地玩玩吧~
*/
#include<stdio.h>
#include<string.h>

//字符串最多字符个数
#define N 25
typedef struct Student
{
    char name[N];
    char id[N];
    int score;
    struct Student *next;
} stu;

//p为当前节点,HeadA为ListA的头节点,HeadB为ListB的头节点
//ListA、ListB指向尾节点
stu *ListA,*ListB,*p,*HeadA,*HeadB;

//读一行字符串
void read(char *s)
{
    char c;
    while((c=getchar())!='\n')
        *s++=c;
}

int solve()
{

    //tg为目标值
    //ans为达到tg的人数
    int tg=1400;
    int ans=0;

    //先处理前面的节点
    while(HeadA!=NULL&&HeadA->score>=tg)
    {
        ans++;
        printf("in");
        //插入到ListB的后面
        if(ListB!=NULL)
            ListB->next=HeadA;
        else
            HeadB=HeadA;
        ListB=HeadA;

        //处理下一个
        HeadA=HeadA->next;
    }
    /*
    因为删除单链表的元素,是删除当前节点的下一个,即p->next
    所以对第一个不能插入ListB的元素,即现在的HeadA,开始处理nx即它的下一个(看看要不要删除)
    */
    if(HeadA==NULL)return ans;
    p=HeadA;
    stu *nx=p->next;
    while(nx!=NULL)
    {
        if(nx->score>=tg)
        {
            ans++;
            //nx插入到ListB的后面
            if(ListB!=NULL)
                ListB->next=nx;
            else
                HeadB=nx;
            ListB=nx;
            p->next=nx->next;//删除ListA的元素
        }

        p=nx;nx=nx->next;
    }

    //ListB最后一个的next设置为NULL(我最后找到的BUG,打脸了,又找到BUG↓)
    //当ListB不为空时,才有ListB->next(我最后找到的BUG)
    if(ListB!=NULL)ListB->next=NULL;
    return ans;
}
int main()
{
    printf("Please input the information of the students:\n");
    char s[N];
    while(1)
    {
        //记得要清空数组再读
        memset(s,0,sizeof s);
        read(s);
        if(strcmp(s,"#####")==0)
        {

            //全部读完了,开始处理,把ListA最后一个节点的next置为NULL。
            ListA->next=NULL;
            printf("There are %d students' score highter than 1400.They are:\n",solve());
            p=HeadB;
            while(p!=NULL)
            {
                printf("Name: %s ID:%s Score:%d\n",p->name,p->id,p->score);
                stu* tmp=p;
                p=p->next;
                free(tmp);
            }
            p=HeadA;
            while(p!=NULL)
            {
                stu* tmp=p;
                p=p->next;
                free(tmp);
            }
            break;
        }

        //分配空间给当前节点
        p=malloc(sizeof(stu));
        if(p!=NULL)
        {
            strcpy(p->name,s);
            memset(p->id,0,sizeof (p->id));
            read(p->id);
            scanf("%d ",&p->score);

            //p插入到ListA的后面
            if(ListA!=NULL)
                ListA->next=p;
            else
                HeadA=p;
            ListA=p;
        }
    }
    return 0;
}

 

  

  

posted @ 2016-03-18 23:07  水郁  阅读(724)  评论(0编辑  收藏  举报
……