题目:

代码:

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

const int maxn = 55;
struct Student{
    char name[maxn], profes[maxn], clas[maxn]; // 姓名,专业,班级
    float score[3]; // 三门课成绩
    int id ; // 学号
    Student *next ;
};
typedef Student Link_List ;
Link_List* h; // 学生链表

void PrintMenu() ; // 输出菜单
void print( Student s ) ; // 输出学生s的信息
void print( Student* s ) ; // 输出学生s的信息
void InPut() ; // 输入学生信息
void CreateList( int n ) ; // 创建链表(逆序输入n个,链表中学号从小到大)
void OutPut( Link_List* head ) ; // 输出全部学生信息

void Save() ; // 保存学生信息到文件
Student Fetch( int stu_id ) ; // 从文件中读取某个学生的信息(输入学号)
Student* SearchNum( int stu_id ) ; // 查找指定学号的学生,返回该学生的指针
void InsertList( Student* s ) ; // 添加一个学生信息到链表中,保持有序性
void DeleteNum( int stu_id ) ; // 删除指定学号的学生
void SearchMajorSubjectScore( char* stu_profes , int score_id , float stu_score ) ; // 查找某个专业某门课程小于某个分数的学生
void DeleteMajorSubject( char* stu_profes , int score_id , float stu_score ) ; // 删除某个专业某门课程小于某个分数的学生(这怕是开除了)

int main()
{
    int op = 0;
    h = new( Student ) ; // 初始化链表h
    h->next = NULL ;
    while( 1 ) {

        PrintMenu() ;
        printf( "请输入选择功能:" ) ;
        scanf( "%d", &op ) ;
        if ( op == 1 ) {
            int n ;
            printf( "请输入学生个数:" ) ;
            scanf( "%d", &n ) ;
            CreateList( n ) ;
        }
        else if ( op == 2 ) {
            OutPut( h ) ;
        }
        else if ( op == 3 ) {
            Save();
            printf( "成功保存到文件“student_list.txt”中\n" ) ;
        }
        else if ( op == 4 ) {
            int stu_id = 0 ;
            printf( "请输入学生学号:" ) ;
            scanf( "%d", &stu_id ) ;
            Student s = Fetch( stu_id ) ;
            if ( s.id !=-1 )
                print( s ) ;
        }
        else if ( op == 5 ) {
            int stu_id = 0 ;
            printf( "请输入学生学号:" ) ;
            scanf( "%d", &stu_id ) ;
            Student* s = SearchNum( stu_id ) ;
            print( s ) ;
        }
        else if ( op == 6 ) {
            printf( "请输入学生信息\n" ) ;
            Student* s = new(Student) ;
            scanf( "%d%s%s%s", &s->id, s->name, s->profes, s->clas ) ;
            scanf( "%f%f%f", &s->score[0], &s->score[1], &s->score[2] ) ;
            InsertList( s ) ;
            printf( "插入完成\n" ) ;
        }
        else if ( op == 7 ) {
            int stu_id = 0 ;
            printf( "请输入学生学号:" ) ;
            scanf( "%d", &stu_id ) ;
            DeleteNum( stu_id ) ;
            printf( "删除成功\n" ) ;
        }
        else if ( op == 8 ) {
            char stu_profes[maxn];
            int score_id ;
            float stu_score ;
            printf( "请输入学生专业\n" ) ;
            scanf( "%s", stu_profes ) ;
            printf( "请输入分数类型( 0 / 1 / 2 )\n" ) ;
            scanf( "%d", &score_id ) ;
            printf( "请输入分数限制\n" ) ;
            scanf( "%f", &stu_score ) ;
            if ( score_id<=2 && score_id>=0 ) {
                SearchMajorSubjectScore(stu_profes, score_id, stu_score) ;
            }
        }
        else if ( op == 9 ) {
            char stu_profes[maxn];
            int score_id ;
            float stu_score ;
            printf( "请输入学生专业\n" ) ;
            scanf( "%s", stu_profes ) ;
            printf( "请输入分数类型( 0 / 1 / 2 )\n" ) ;
            scanf( "%d", &score_id ) ;
            printf( "请输入分数限制\n" ) ;
            scanf( "%f", &stu_score ) ;
            if ( score_id<=2 && score_id>=0 ) {
                DeleteMajorSubject(stu_profes, score_id, stu_score) ;
            }
            printf( "删除成功\n" ) ;
        }
        else if ( op == 0 ) {
            break ;
        }
        else {
            printf( "输入不合法,请重新输入\n" ) ;
        }
        printf( "\n\n\n\n\n\n\n\n" ) ;
    }
    return 0;
}
void PrintMenu(){
    printf( "***********************功能菜单***************************************\n" ) ;
    printf( "1.创建链表(逆序输入n个,链表中学号从小到大)\n" ) ;
    printf( "2.输出全部学生信息\n" ) ;
    printf( "3.保存所有学生信息到文件\n" ) ;
    printf( "4.从文件中读取某个学生的信息(输入学号)\n" ) ;
    printf( "5.查找指定学号的学生,返回该学生的指针\n" ) ;
    printf( "6.添加一个学生信息到链表中,保持有序性\n" ) ;
    printf( "7.删除指定学号的学生\n" ) ;
    printf( "8.查找某个专业某门课程小于某个分数的学生\n" ) ;
    printf( "9.删除某个专业某门课程小于某个分数的学生(这怕是开除了)\n" ) ;
    printf( "0.结束程序\n" ) ;
    printf( "***********************************************************************\n") ;
}
void print( Student s ) {
    printf( "学号: %d\t姓名: %s\t专业: %s\t班级: %s\t", s.id, s.name, s.profes, s.clas ) ;
    printf( "成绩1: %f\t成绩2: %f\t成绩3: %f\n", s.score[0], s.score[1], s.score[2] ) ;
}
void print( Student* s ) {
    if ( s == NULL ) return ;
    printf( "学号: %d\t姓名: %s\t专业: %s\t班级: %s\t", s->id, s->name, s->profes, s->clas ) ;
    printf( "成绩1: %f\t成绩2: %f\t成绩3: %f\n", s->score[0], s->score[1], s->score[2] ) ;
}
void InPut() {
    Student *s = new( Student ) ; // 新建一个节点,用s指向它
    scanf( "%d%s%s%s", &s->id, s->name, s->profes, s->clas ) ;
    scanf( "%f%f%f", &s->score[0], &s->score[1], &s->score[2] ) ;
    s->next = h->next ; // s接到第一个节点前面
    h->next = s ; // s变成第一个
}
void CreateList( int n ) {
    for (int i=0; i<n; i++) {
        InPut() ;
    }
}
void OutPut( Link_List* head ) {
    Student *now = head ; // 新建一个指针指向头结点
    while( now->next != NULL ) {
        now = now->next ;
        print( now ) ;
    }
}
void Save() {
    freopen( "student_list.txt", "w", stdout ) ;
    OutPut( h );
    freopen( "CON", "w", stdout ) ;
}
Student Fetch( int stu_id ) {
    freopen( "student_list.txt", "r", stdin ) ;
    Student ret ;
    ret.id = -1 ; // 初始化
    char temp[maxn];
    while( scanf("%s",temp)!=EOF ) {
        scanf( "%d%s%s%s%s%s%s", &ret.id, temp, ret.name, temp, ret.profes, temp, ret.clas ) ;
        scanf( "%s%f%s%f%s%f", temp, &ret.score[0], temp, &ret.score[1], temp, &ret.score[2] ) ;
        if ( ret.id == stu_id ) {
            freopen( "CON" , "r", stdin ) ;
            return ret ;
        }
    }
    freopen( "CON", "r", stdin ) ;
    return ret ;
}
Student* SearchNum( int stu_id ) {
    Student *ret = h ; // 新建一个指针指向头结点
    while( ret->next != NULL ) {
        ret = ret->next ;
        if ( ret->id == stu_id ) return ret ;
    }
    printf( "没有学号为%d的学生\n" ) ;
    return NULL ;
}
void InsertList( Student* s ) {
    Student *now = h ; // 新建一个指针指向头结点
    Student *pre = h ; // pre为now的前一个指针
    while( now->next != NULL ) { // 遍历链表
        pre = now ;
        now = now->next ; // now沿着链表后移到下一个
        if ( now->id >= s->id ) { // 在pre后面添加一个学生节点s
            s->next = now ;
            pre->next = s ;
            return ;
        }
    }
    // s为最大的学号,在尾结点添加s
    s->next = NULL ;
    now->next = s ;
    return ;
}
void DeleteNum( int stu_id ) {
    Student *now = h ; // 新建一个指针指向头结点
    Student *pre = h ; // pre为now的前一个指针
    while( now->next != NULL ) { // 遍历链表
        pre = now ;
        now = now->next ; // now沿着链表后移到下一个
        if ( now->id == stu_id ) { // 删除now节点
            pre->next = now->next ;
            delete(now) ; // 释放now所占的空间
            return ;
        }
    }
}
void SearchMajorSubjectScore( char* stu_profes , int score_id , float stu_score ) {
    Student *now = h ; // 新建一个指针指向头结点
    while( now->next != NULL ) { // 遍历链表
        now = now->next ; // now沿着链表后移到下一个
        if ( strcmp(now->profes,stu_profes) == 1 ) continue ; // 专业不符合
        if ( now->score[score_id] <= stu_score ) { // 分数小于stu_score
            print( now ) ;
        }
    }
}
void DeleteMajorSubject( char* stu_profes , int score_id , float stu_score ) {
    Student *now = h ; // 新建一个指针指向头结点
    Student *pre = h ; // pre为now的前一个指针
    while( now->next != NULL ) { // 遍历链表
        pre = now ;
        now = now->next ; // now沿着链表后移到下一个
        if ( strcmp(now->profes,stu_profes) == 1 ) continue ; // 专业不符合
        if ( now->score[score_id] <= stu_score ) { // 分数小于stu_score
            pre->next = now->next ; // 删除原now节点
            delete(now) ; // 释放now所占的空间
            now = pre ; // now重新指向pre
        }
    }
}

/* 测试数据: 1 7 222016007 段东杰7 计科 一班 92 93.5 96.9 222016006 段东杰6 计科 四班 93 93.5 96.9 222016005 段东杰5 计科 一班 52 93.5 96.9 222016004 段东杰4 计科 四班 22 93.5 96.9 222016003 段东杰3 计科 三班 32.2 93.5 96.9 222016002 段东杰2 计科 一班 98 93.5 96.9 222016001 段东杰1 计科 二班 84.2 93.5 96.9 2 3 4 2220160922 */