365 lines
9.5 KiB
C++
365 lines
9.5 KiB
C++
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
|
||
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;i<j;i++)
|
||
{
|
||
current=current->next;
|
||
}
|
||
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;
|
||
}
|