學生成績管理系統(連結串列的實現)
阿新 • • 發佈:2019-02-12
/*所使用的標頭檔案*/
#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);
}
}