1. 程式人生 > >學生成績管理系統(連結串列的實現)

學生成績管理系統(連結串列的實現)

/*所使用的標頭檔案*/
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>

/*所呼叫的函式*/
struct LINK_NODE *creat(struct LINK_NODE *head);    //建立新結點
int Count_Node(struct LINK_NODE *head);     //結點計數
void Delete_Node_Num(struct LINK_NODE *head);    //刪除第某個結點
//void Delete_Node_Data(struct LINK_NODE *head);    //按資料刪除結點
void Cut_Node_In(struct LINK_NODE *head); //插入結點 void Display_Node(struct LINK_NODE *head); //顯示當前的結點內容 void fun(); /*綜合功能函式*/ /*結構體*/ struct LINK_NODE { long id; char name[10]; float yuwen; float shuxue; float yingyu; struct LINK_NODE *next; }; /*主函式*/ int main() { int
ID; int keywords; printf("\t請輸入使用者名稱:"); scanf(" %d",&ID); printf("\t請輸入使用者密碼:"); scanf(" %d",&keywords); if(ID == 123 && keywords == 123) { fun(); } else { printf("\a使用者名稱或密碼錯誤!系統拒絕訪問!\n\n請按任意鍵退出!\n\n"); } system("pause"
); return 0; } /*綜合功能函式*/ void fun() { int c; char ch; struct LINK_NODE *head = NULL; system("cls"); while(1) { printf("\n\t\t--\t 歡迎使用學生成績管理系統 \t --\n"); printf("\t\t---------------------------------------------------\n"); printf("\t\t|\t\t 0.輸入學生資訊\t\t |\n\n"); printf("\t\t|\t\t 1.刪除資料資訊\t\t |\n\n"); printf("\t\t|\t\t 2.插入學生資訊\t\t |\n\n"); printf("\t\t|\t\t 3.顯示學生資訊\t\t |\n\n"); printf("\t\t|\t\t 4.------------\t\t |\n\n"); printf("\t\t|\t\t 5.------------\t\t |\n\n"); printf("\t\t|\t\t 6.------------\t\t |\n\n"); printf("\t\t|\t\t 7.------------\t\t |\n\n"); printf("\t\t|\t\t 8.------------\t\t |\n\n"); printf("\t\t|\t\t 9.--- 退出 ---\t\t |\n"); printf("\t\t---------------------------------------------------\n"); printf("請選擇欄目(輸入序號):"); scanf(" %d",&c); getchar(); switch(c) { case 0: system("cls"); head = creat(head); printf("是否輸入資料?(y/n):"); scanf(" %c",&ch); //%c前加空格 while(ch == 'y'||ch == 'Y') //用於迴圈輸入資料 { head = creat(head); printf("是否輸入資料?(y/n):"); scanf(" %c",&ch); //%c前加空格 } system("pause"); system("cls"); break; case 1: Delete_Node_Num(head); system("cls"); break; case 2: Cut_Node_In(head); system("pause"); system("cls"); break; case 3: system("cls"); Display_Node(head); system("pause"); system("cls"); break; case 4: system("pause"); system("cls"); break; case 5: system("pause"); system("cls"); break; case 6: system("pause"); system("cls"); break; case 7: system("pause"); system("cls"); break; case 8: system("pause"); system("cls"); break; case 9: system("cls"); printf("\n\t感謝您的使用!\n\n"); system ("pause"); exit(0); } } } /*建立新的結點*/ struct LINK_NODE *creat(struct LINK_NODE *head) { char s[10]; long i; float score1,score2,score3; struct LINK_NODE *p1 = NULL,*p2 = head; p1 = (struct LINK_NODE *)malloc(sizeof(struct LINK_NODE)); //動態申請(分配)記憶體,用來建立新的結點 if(!head) //檢查頭結點指標是否為空 { head = p1; head->next = NULL; return head; } else { while(p2->next != NULL) { p2 = p2->next; } p2->next = p1; p1->next = NULL; printf("請輸入學號:"); scanf(" %d",&i); //%d前加空格 p1->id = i; getchar(); printf("請輸入姓名:"); gets(p1->name); printf("請輸入數學成績:"); scanf(" %f",&score1); //%d前加空格 p1->shuxue = score1; printf("請輸入語文成績:"); scanf(" %f",&score2); //%d前加空格 p1->yuwen = score2; printf("請輸入英語成績:"); scanf(" %f",&score3); //%d前加空格 p1->yingyu = score3; } return head; } /*結點計數*/ int Count_Node(struct LINK_NODE *head) { int i = 1; //結點數從1開始,是因為頭結點不錄入資料 struct LINK_NODE *p = head; do { p = p->next; ++i; } while(p->next != NULL); //直到指標指向最後一個結點時,停止移動 return i; //返回結點個數給函式 } /*刪除第某個結點*/ void Delete_Node_Num(struct LINK_NODE *head) { int i, Count; int a = 1; struct LINK_NODE *p1 = head,*p2 = NULL; system("cls"); Display_Node(head); Count = Count_Node(head); printf("\n請輸入想要刪除第幾個資料資訊:"); scanf(" %d",&i); //%d前加空格 if(i <= 0) //頭結點不允許刪除,若刪除將影響接下來的鏈 { printf("頭結點不可刪除!!\n"); } else if(i >= Count) //所要刪除的結點數不可以大於連結串列的長度 { printf("輸入結點數有誤!!\n"); } else if(i == Count) //若刪除的是尾結點,則將倒數第二個的 next 賦值為 NULL { while(p1->next) { p1 = p1->next; } p2 = head; while((p2->next)!=p1) { p2 = p2->next; } p2->next = NULL; free(p1); //刪除結點後,釋放之前所佔用的記憶體 } else //所刪除的結點在連結串列中(非首非尾) { while(!(i==a)) { p1 = p1->next; ++a; } p2 = p1->next; p1->next = p2->next; free(p2); //刪除結點後,釋放之前所佔用的記憶體 } printf("操作成功!!\n"); Display_Node(head); system("pause"); } /*按資料刪除結點*/ //功能未建設完全,存在BUG void Delete_Node_Data(struct LINK_NODE *head) { int num = 0,i = -1; struct LINK_NODE *p1 = head, *p2 = NULL; printf("\n請輸入要刪除的資料:"); scanf(" %d",&num); if(head->next == NULL) { printf("\n連結串列中不存在任何資料!!\n"); exit(0); } p2 = p1->next; while(p2->next != NULL) { p2 = p1->next; i = p2->id; if(p2->id == num ) { break; } } if(i != num) { printf("\n連結串列中沒有您要刪除的資料!!\n"); exit(0); } p1->next = p2->next; free(p2); //結點刪除後要釋放掉所刪除結點佔用的記憶體空間,達到節約記憶體的目的 } /*插入結點*/ void Cut_Node_In(struct LINK_NODE *head) { int n = -1, i, Count = Count_Node(head),a; float score1,score2,score3; system("cls"); Display_Node(head); struct LINK_NODE *p1 = head, *p2 = NULL; p2 = (struct LINK_NODE *)malloc(sizeof(struct LINK_NODE)); if(p2 == NULL) { printf("記憶體空間不夠,無法新增新的資料!!\n"); exit(0); } else { printf("請輸入學號:"); scanf(" %d",&i); //%d前加空格 p2->id = i; getchar(); printf("請輸入姓名:"); gets(p2->name); printf("請輸入語文成績:"); scanf(" %f",&score2); //%d前加空格 p2->yuwen = score2; printf("請輸入數學成績:"); scanf(" %f",&score1); //%d前加空格 p2->shuxue = score1; printf("請輸入英語成績:"); scanf(" %f",&score3); //%d前加空格 p2->yingyu = score3; printf("將資料插入為第哪個數:"); scanf(" %d",&n); if(n <= 0) { printf("此處不可插入資料!!\n"); exit(0); } else if(n > Count) { printf("此處不可插入資料!!\n"); exit(0); } for(i = 0; i <= Count; ) { i++; if(i == n) { p2->next = p1->next; p1->next = p2; break; } else { p1 = p1->next; } } printf("操作成功!!\n"); Display_Node(head); } } /*顯示當前的結點內容*/ void Display_Node(struct LINK_NODE *head) { int i = 1; //迴避頭結點(不列印頭結點) struct LINK_NODE *p = head; if(head == NULL) //若傳進來的連結串列頭指標為 NULL,則做出錯誤判斷 { printf("\n使用者尚未錄入任何資料!!\n"); } else if( p->next == NULL) { printf("\該系統內未找到任何資料!!\n"); } else { system("cls"); printf("當前全部學生資訊如下:\n"); do //1傳進來的連結串列頭指標不為 NULL,則挨個列印,直到尾結點 { p = p -> next; printf("\t%d------------------------\n",i); printf("\t 學號:%d\n",p->id); printf("\t 姓名:%s\n",p->name); printf("\t 語文:%.2f\n",p->yuwen); printf("\t 數學:%.2f\n",p->shuxue); printf("\t 英語:%.2f\n",p->yingyu); i++; } while(p -> next != NULL); } }