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

typedef struct {
    int rank;       // 排名序号
    char num[20];     // 学号
    char name[10];    // 姓名
    int math_score;   // 高数成绩
    int datastruct_score; // 数据结构成绩
    int English_score;    // 英语成绩
    int physics_score;    // 物理成绩
    float average;        // 平均分
} Student;

typedef struct {
    Student *data;
    int length;
} funlist;

// 初始化线性表
void initlist(funlist *l) {
    l->data = (Student *)malloc(100 * sizeof(Student));
    l->length = 0;
}

// 判断是否为空表
int isempty(funlist *l) {
    return l->length == 0;
}

// 取值
int getelem(funlist l, int i, Student *e) {
    if (i < 1 || i > l.length) {
        printf("位置不合法\n");
        return 0;
    }
    *e = l.data[i - 1];
    return 1;
}

// 计算平均分
float calculate_average(Student *s) {
    return (s->math_score + s->datastruct_score + s->English_score + s->physics_score) / 4.0f;
}

// 打印操作（无排名）
void printlist_no_rank(funlist l) {
    int i;
    printf("成绩表为:\n");
    for (i = 0; i < l.length; i++) {
        printf("学号:%s 姓名:%s 高数:%d 数据结构:%d 英语:%d 物理:%d 平均分:%.2f\n",
               l.data[i].num, l.data[i].name, l.data[i].math_score,
               l.data[i].datastruct_score, l.data[i].English_score,
               l.data[i].physics_score, l.data[i].average);
    }
}

// 打印操作（带排名）
void printlist_with_rank(funlist l) {
    int i;
    printf("成绩表为:\n");
    for (i = 0; i < l.length; i++) {
        printf("排名:%d 学号:%s 姓名:%s 高数:%d 数据结构:%d 英语:%d 物理:%d 平均分:%.2f\n",
               l.data[i].rank, l.data[i].num, l.data[i].name, l.data[i].math_score,
               l.data[i].datastruct_score, l.data[i].English_score,
               l.data[i].physics_score, l.data[i].average);
    }
}

// 查找操作（按学号查找） 
int locateelem1(funlist l, char *num) {
    int i;
    for (i = 0; i < l.length; i++) {
        if (strcmp(l.data[i].num, num) == 0)
            return i + 1;
    }
    return -1;
}

// 查找操作（按姓名查找）
int locateelem2(funlist l, char *name) {
    int i;
    for (i = 0; i < l.length; i++) {
        if (strcmp(l.data[i].name, name) == 0)
            return i + 1;
    }
    return -1;
}

// 删除操作
int deleteelem(funlist *l, int i) {
    int j;
    if (i < 1 || i > l->length) {
        printf("位置不合法\n");
        return 0;
    }
    for (j = i; j < l->length; j++) {
        l->data[j - 1] = l->data[j];
    }
    l->length--;
    // 重新调整排名
    for (j = i - 1; j < l->length; j++) {
        l->data[j].rank = j + 1;
    }
    return 1;
}

// 插入操作
int listinsert(funlist *l, int i, Student e) {
    if (i < 1 || i > l->length + 1) {
        printf("位置不合法\n");
        return 0;
    }
    if (l->length >= 100) {
        printf("线性表已满\n");
        return 0;
    }
    int j;
    for (j = l->length - 1; j >= i - 1; j--) {
        l->data[j + 1] = l->data[j];
        // 向后移动排名
        l->data[j + 1].rank = l->data[j].rank + 1;
    }
    // 计算并保存平均分
    e.average = calculate_average(&e);
    e.rank = i;
    l->data[i - 1] = e;
    l->length++;
    return 1; // 返回1表示成功
}

// 按平均分排序
void sort_by_average(funlist *l) {
    if (l->length <= 1) return; // 无需排序
    
    int i, j;
    for (i = 0; i < l->length - 1; i++) {
        for (j = 0; j < l->length - i - 1; j++) {
            if (l->data[j].average < l->data[j + 1].average) {
                Student temp = l->data[j];
                l->data[j] = l->data[j + 1];
                l->data[j + 1] = temp;
            }
        }
    }
    // 更新排名
    for (i = 0; i < l->length; i++) {
        l->data[i].rank = i + 1;
    }
    printf("学生已按平均分降序排列\n");
}

int main() {
    funlist L;
    initlist(&L); 

    int choice;
    char num[20];
    char name[10];
    int math_score;
    int datastruct_score;
    int English_score;
    int physics_score;
    int i;

    printf("1.插入学生\n");
    printf("2.通过学号查询学生\n");
    printf("3.通过姓名查询学生\n");
    printf("4.删除学生\n");
    printf("5.按平均分排序学生\n");
    printf("6.退出\n");

    while (1) { 
        printf("请输入操作选项:");
        scanf("%d", &choice);
        switch (choice) {
            case 1: {
                Student e;
                printf("请输入姓名:");
                scanf("%s", name);
                strcpy(e.name, name);
                
                printf("请输入学号:");
                scanf("%s", num);
                strcpy(e.num, num);
                
                printf("请输入高数成绩:");
                scanf("%d", &math_score);
                e.math_score = math_score;
                
                printf("请输入数据结构成绩:");
                scanf("%d", &datastruct_score);
                e.datastruct_score = datastruct_score;
                
                printf("请输入英语成绩:");
                scanf("%d", &English_score);
                e.English_score = English_score;
                
                printf("请输入物理成绩:");
                scanf("%d", &physics_score);
                e.physics_score = physics_score;
                
                printf("请输入想插入的位置(1-%d):\n", L.length + 1);
                scanf("%d", &i);
                
                if (listinsert(&L, i, e)) {
                    printf("插入成功\n");
                } else {
                    printf("插入失败\n");
                }
                printlist_no_rank(L);
                printf("\n");
				break;
            }
            
            case 2: {
                printf("输入想查找的学生学号:");
                scanf("%s", num);
                i = locateelem1(L, num);
                if (i != -1) {
                    Student e;
                    getelem(L, i, &e);
                    printf("找到学生: 学号:%s 姓名:%s 平均分:%.2f\n", 
                           e.num, e.name, e.average);
                } else {
                    printf("未找到学号为%s的学生\n", num);
                }
                  printf("\n");
                break;
            }
            
            case 3: {
                printf("输入想查找的学生姓名:");
                scanf("%s", name);
                i = locateelem2(L, name);
                if (i != -1) {
                    Student e;
                    getelem(L, i, &e);
                    printf("找到学生: 学号:%s 姓名:%s 平均分:%.2f\n", 
                           e.num, e.name, e.average);
                } else {
                    printf("未找到姓名为%s的学生\n", name);
                }
                  printf("\n");
                break;
            }
            
            case 4: {
                printf("输入想删除的学生位置:");
                scanf("%d", &i);
                if (deleteelem(&L, i)) {
                    printf("删除成功\n");
                } else {
                    printf("删除失败\n");
                }
                printlist_no_rank(L);
                  printf("\n");
				break;
            }
            
            case 5: {
                sort_by_average(&L);
                printlist_with_rank(L);
                  printf("\n");
				break;
            }
            
            case 6: {
                printf("退出系统\n");
                free(L.data); 
				return 0;
            }   
            default:
                printf("无效选项，请重新输入\n");
        }
    }

    return 0;
}
