#include #include #include #include typedef struct Student { char name[40]; int eng; int math; struct Student *prev; struct Student *next; } Student; Student *head = NULL, *tail = NULL, *current; // 新增節點到鏈結串列尾部 void addToList(const char *name, int eng, int math) { // 配置新節點記憶體 Student *newStudent = (Student*)malloc(sizeof(Student)); // 複製資料到新節點 strncpy(newStudent->name, name, sizeof(newStudent->name) - 1); newStudent->name[sizeof(newStudent->name) - 1] = '\0'; newStudent->eng = eng; newStudent->math = math; newStudent->next = NULL; // 如果是第一個節點 if (head == NULL) { newStudent->prev = NULL; head = tail = newStudent; } else // 加入到尾部 { newStudent->prev = tail; tail->next = newStudent; tail = newStudent; } } // 顯示所有學生資料 void displayList() { //Student * current = head; printf("學生資料列表(從頭開始):\n\n"); printf("姓名\t\t\t\t英文\t數學\n"); printf("---------------------------------------------\n"); for(int i=0; current!=NULL; current=current->next,i++) { printf("%d.\t%-16s\t%d\t%d\n\n", i+1, current->name, current->eng, current->math); } printf("---------------------------------------------\n"); } // 從尾開始列印 void displayList_inverse() { Student *current = tail; printf("學生資料列表(從尾開始):\n\n"); printf("姓名\t\t\t\t英文\t數學\n"); printf("---------------------------------------------\n"); for(int i=0; current!=NULL; current=current->prev,i++) { printf("%d.\t%-16s\t%d\t%d\n\n", i+1, current->name, current->eng, current->math); } printf("---------------------------------------------\n"); } // 釋放所有動態分配的節點 void cleanup() { Student *current = head; while (current != NULL) { Student *temp = current; current = current->next; free(temp); } head = tail = NULL; } // 更新後的刪除函數 void deletedate(const char *name, int eng, int math) { Student *current = head; while(current != NULL) { if(strcmp(current->name, name) == 0) { if(current->prev != NULL) current->prev->next = current->next; else head = current->next; if(current->next != NULL) current->next->prev = current->prev; else tail = current->prev; free(current); return; } current = current->next; } } // 移除字串前後的空格 void trim(char *str) { char *end; while(isspace(*str)) str++; if(*str == 0) return; end = str + strlen(str) - 1; while(end > str && isspace(*end)) end--; end[1] = '\0'; } //void displayOriginal(Student **array, int length) //{ // printf("\n原始資料列表:\n\n"); // printf("姓名\t\t\t\t英文\t數學\n"); // printf("---------------------------------------------\n"); // for(int i = 0; i < length; i++) { // printf("%d.\t%-16s\t%d\t%d\n\n", i+1, array[i]->name, array[i]->eng, array[i]->math); // } // printf("---------------------------------------------\n"); //}//如果想在排序後看還有switch,就把下面的註釋調 void displayOriginal() { //Student * current = head; printf("\n原始資料列表:\n\n"); printf("姓名\t\t\t\t英文\t數學\n"); printf("---------------------------------------------\n"); for(int i = 0; current != NULL; i++) { printf("%d.\t%-16s\t%d\t%d\n\n", i+1, current->name, current->eng, current->math); current = current->next; } printf("---------------------------------------------\n"); } // 排序函數 void bubble_name() { int length = 0; Student *current = head; // 計算鏈表長度 while(current != NULL) { length++; current = current->next; } // 創建指針數組 Student **array = (Student**)malloc(length * sizeof(Student*)); current = head; for(int i = 0; i < length; i++) { array[i] = current; current = current->next; } // 顯示原始資料 //displayOriginal(array, length); // 按名字排序 for(int i = 0; i < length-1; i++) { for(int j = 0; j < length-1-i; j++) { if(strcmp(array[j]->name, array[j+1]->name) > 0) { Student *temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } // 顯示排序後的結果 printf("學生資料列表(依名字排序):\n\n"); printf("姓名\t\t\t\t英文\t數學\n"); printf("---------------------------------------------\n"); for(int i = 0; i < length; i++) { printf("%d.\t%-16s\t%d\t%d\n\n", i+1, array[i]->name, array[i]->eng, array[i]->math); } printf("---------------------------------------------\n"); free(array); } // 按英文成績排序 void bubble_eng() { int length = 0; Student *current = head; // 計算鏈表長度 while(current != NULL) { length++; current = current->next; } // 創建指針數組 Student **array = (Student**)malloc(length * sizeof(Student*)); current = head; for(int i = 0; i < length; i++) { array[i] = current; current = current->next; } // 顯示原始資料 //displayOriginal(array, length); // 按英文成績排序 for(int i = 0; i < length-1; i++) { for(int j = 0; j < length-1-i; j++) { if(array[j]->eng < array[j+1]->eng) { Student *temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } // 顯示排序後的結果 printf("學生資料列表(依英文成績排序):\n\n"); printf("姓名\t\t\t\t英文\t數學\n"); printf("---------------------------------------------\n"); for(int i = 0; i < length; i++) { printf("%d.\t%-16s\t%d\t%d\n\n", i+1, array[i]->name, array[i]->eng, array[i]->math); } printf("---------------------------------------------\n"); free(array); } // 按數學成績排序 void bubble_math() { int length = 0; Student *current = head; // 計算鏈表長度 while(current != NULL) { length++; current = current->next; } // 創建指針數組 Student **array = (Student**)malloc(length * sizeof(Student*)); current = head; for(int i = 0; i < length; i++) { array[i] = current; current = current->next; } // 顯示原始資料 //displayOriginal(array, length); // 按數學成績排序 for(int i = 0; i < length-1; i++) { for(int j = 0; j < length-1-i; j++) { if(array[j]->math < array[j+1]->math) { Student *temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } // 顯示排序後的結果 printf("學生資料列表(依數學成績排序):\n\n"); printf("姓名\t\t\t\t英文\t數學\n"); printf("---------------------------------------------\n"); for(int i = 0; i < length; i++) { printf("%d.\t%-16s\t%d\t%d\n\n", i+1, array[i]->name, array[i]->eng, array[i]->math); } printf("---------------------------------------------\n"); free(array); } void select() { Student *current=head; int j; printf("請選擇查看第幾名的資料\n\n"); scanf("%d",&j); for(int i=1;inext; } printf("\n%d. Name = %s Eng = %d\tMath = %d",j,current->name,current->eng,current->math); } int main() { FILE *file; char line[100]; char name[40]; int eng, math; char op; file = fopen("YunTechStudents.txt", "r"); while(fgets(line, sizeof(line), file)) { if(strstr(line, "****") != NULL) break; if(sscanf(line, "%[^\t]%d%d", name, &eng, &math) == 3) { trim(name); addToList(name, eng, math); } } displayList(); displayList_inverse(); while(fgets(line, sizeof(line), file)) { op = line[0]; if(op == '+' || op == '-') { char fullname[40]; if(sscanf(line + 1, " %[^0-9]%d%d", fullname, &eng, &math) == 3) { trim(fullname); if(op == '+') { addToList(fullname, eng, math); printf("\n新增資料為:\t%s\t%d\t%d\n\n", fullname, eng, math); } else { deletedate(fullname, eng, math); printf("\n刪除資料為:\t%s\t%d\t%d\n\n", fullname, eng, math); } displayList(); displayList_inverse(); } } } int choice; while(1) { printf("\n\n請輸入選擇\n\n"); printf("1. 以名字排列\t2. 以英文分數排列\t3. 以數學分數排列\t4. 顯示原本資料\t5. 離開\n\n"); scanf("%d",&choice); switch(choice) { case 1: bubble_name(); select(); break; case 2: bubble_eng(); select(); break; case 3: bubble_math(); select(); break; case 4: displayOriginal(); break; case 5: printf("\n歡迎再來"); cleanup(); exit(0); break; } } fclose(file); return 0; }