1. 程式人生 > >連結串列《5》使用連結串列實現學生成績管理系統

連結串列《5》使用連結串列實現學生成績管理系統

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

struct Student//學生結構
{
	char Name[10];//姓名
	int Age;//年齡
	int No;//學號
	float Score[3];//三科的成績
	float Total;//總分
	float Ave;//平均分
};


typedef struct Node//結點
{
	struct Student st;//資料域

	struct Node *pNext;//指標域
}NODE, *PNODE;
/*
NODE等價於struct Student st
PNODE等價於struct Node *pNext
*/

//輸入函式,用於輸入學生資訊
PNODE InputStudent(void);

//輸出學生資訊
void OutputStudent(PNODE pHead);

//刪除學生資訊
void DeleteStudent(PNODE pHead);

//查詢學生資訊
void SearchStudent(PNODE pHead);

//修改學生資訊
void ChangeStudent(PNODE pHead);

//增加學生資訊
void InsertStudent(PNODE pHead);

//對學生的語文成績排序
void ScortByChinese(PNODE pHead);

//對學生的數學成績排序
void ScortByMath(PNODE pHead);

//對學生的英語成績排序
void ScortByEnglish(PNODE pHead);

//對學生的總分排序
void ScortByTotal(PNODE pHead);

void main()
{
	printf("================================================================================\n\n");
	printf("================================================================================\n\n");
	printf("*************************歡迎使用學生成績管理系統*******************************\n\n");
	printf("-----------------------------------------------------------------製作人:梅沙小子\n\n");
	printf("********************************************************************************\n\n");
	printf("================================================================================\n\n");


	printf("請按任意將進入學生管理系統:\n");
	getchar();
	system("cls");

	printf("================================================================================\n\n");
	printf("------------------------ 請選擇要操作的命令:-----------------------------------\n\n");
	printf("-------------------------- 1  輸入學生資訊--------------------------------------\n\n");
	printf("-------------------------- 2  輸出學生資訊--------------------------------------\n\n");
	printf("-------------------------- 3  刪除學生資訊--------------------------------------\n\n");
	printf("-------------------------- 4  查詢學生資訊--------------------------------------\n\n");
	printf("-------------------------- 5  修改學生資訊--------------------------------------\n\n");
	printf("-------------------------- 6  增加學生資訊--------------------------------------\n\n");
	printf("-------------------------- 7  將學生的語文成績按從大到小排----------------------\n\n");
	printf("-------------------------- 8  將學生的數學成績按從大到小排----------------------\n\n");
	printf("-------------------------- 9  將學生的英語成績按從大到小排----------------------\n\n");
    printf("-------------------------- 10 將學生的總成績按從大到小排------------------------\n\n");
	printf("================================================================================\n\n");

	int Item;//儲存操作命令

	PNODE pHead = NULL;//定義一個指標

	while(1)
	{
		printf("請選擇操作命令:");
		scanf("%d",&Item);

		system("cls");//清屏

		switch(Item)
		{
		    case 1://輸入學生資訊
			{
				pHead = InputStudent();
			}
			break;

			case 2://輸出學生資訊
			{
				OutputStudent(pHead);
			}
			break;

			case 3://刪除學生資訊
			{
				DeleteStudent(pHead);
			}
			break;

			case 4://查詢學生資訊
			{
				SearchStudent(pHead);
			}
			break;

			case 5://修改學生資訊
			{
				ChangeStudent(pHead);
			}
			break;

			case 6://增加學生資訊
			{
				InsertStudent(pHead);
			}
			break;

			case 7://對學生的語文成績排序
			{
				ScortByChinese(pHead);
				OutputStudent(pHead);
			}
			break;

			case 8://對學生的數學成績排序
			{
				ScortByMath(pHead);
				OutputStudent(pHead);
			}
			break;

			case 9://對學生的英語成績排序
			{
				ScortByEnglish(pHead);
				OutputStudent(pHead);
			}
			break;

			case 10://對學生的總分排序
			{
				ScortByTotal(pHead);
				OutputStudent(pHead);
			}
			break;
			default:
			break;
		}
	}

	system("pause");
}


//輸入函式,用於輸入學生資訊
PNODE InputStudent(void)
{
	int len;//學生的人數

	NODE stu;//學生結構

	//定義一個頭結點並且為頭結點分配記憶體
	PNODE pHead = (PNODE)malloc(sizeof(NODE));

	//判斷記憶體是否為空
	if(NULL == pHead)
	{
		printf("記憶體分配失敗,程式終止!\n");

		exit(-1);
	}

	//定義一個指向頭結點的指標
	PNODE pTail = pHead;
	pTail->pNext = NULL;//清空指標域

	printf("請輸入學生的人數:");
	scanf("%d",&len);

	for(int i=0; i<len; i++)
	{
		system("cls");//清屏

		printf("請輸入第%d個學生的姓名:", i+1);
		scanf("%s", stu.st.Name);

		printf("請輸入第%d個學生的年齡:", i+1);
		scanf("%d", &stu.st.Age);

		printf("請輸入第%d個學生的學號:", i+1);
		scanf("%d", &stu.st.No);

		printf("請輸入第%d個學生的語文成績:", i+1);
		scanf("%f", &stu.st.Score[0]);

		printf("請輸入第%d個學生的數學成績:", i+1);
		scanf("%f", &stu.st.Score[1]);

		printf("請輸入第%d個學生的英語成績:", i+1);
		scanf("%f", &stu.st.Score[2]);

		//計算總分
		stu.st.Total = stu.st.Score[0] + stu.st.Score[1] + stu.st.Score[2];

		//計算平均分
		stu.st.Ave = stu.st.Total / 3.0f;

		//為新節點分配記憶體
		PNODE pNew = (PNODE)malloc(sizeof(NODE));

		//判斷記憶體是否為空
		if(NULL == pNew)
		{
			printf("記憶體分配失敗,程式終止!\n");

			exit(-1);
		}

		//初始化結點的資料域
		pNew->st = stu.st;
		
		//將新結點掛到老結點後
		pTail->pNext = pNew;
		
		//清空新結點的指標域
		pNew->pNext = NULL;
		
		//將pTail移到新結點上
		pTail = pNew;
	}

	return pHead;
}

//輸出學生資訊
void OutputStudent(PNODE pHead)
{
	//定義一個指標用於遍歷學生資訊
	PNODE p = pHead->pNext;

	printf("姓名 年齡  學號  語文  數學  英語  總分 平均分\n");
	
	while(NULL != p)
	{
		printf("%s  %d  %d  %g  %g  %g  %g  %g\n", p->st.Name, p->st.Age, p->st.No, p->st.Score[0], p->st.Score[1], p->st.Score[2], p->st.Total, p->st.Ave);

		p = p->pNext;
	}
}

//刪除學生資訊
void DeleteStudent(PNODE pHead)
{
	PNODE p = pHead;

	int i = 0;

	int pos;

	printf("請輸入你需要刪除的學生的編號:");
	scanf("%d",&pos);

	while(NULL != p->pNext && i<pos-1)
	{
		p = p->pNext;

		i++;
	}

	if(NULL == p->pNext || i>pos-1)
	{
		printf("沒找到需要刪除的學生的編號!\n");

		return;
	}

	PNODE q = p->pNext;

	p->pNext = q->pNext;

	free(q);
	q == NULL;

	printf("你已經成功刪除了第%d個學生的資訊!\n",pos);
}
//查詢學生資訊
void SearchStudent(PNODE pHead)
{
	char Name[10];

	printf("請輸入你需要查詢的學生的姓名:");
	scanf("%s",Name);

	PNODE p = pHead->pNext;

	while(NULL != p)
	{
		if(0 == strcmp(Name,p->st.Name))
		{
			printf("%s %d %d %g %g %g %g %g\n",p->st.Name, p->st.Age, p->st.No, p->st.Score[0], p->st.Score[1], p->st.Score[2], p->st.Total, p->st.Ave);
		}

		p = p->pNext;
	}
}

//修改學生資訊
void ChangeStudent(PNODE pHead)
{
	char Name[10];

	printf("請輸入你需要修改的學生的姓名:");
	scanf("%s",&Name);

	PNODE p = pHead->pNext;//定義一個指標用於遍歷學生資訊


	while(NULL != p)
	{
		if(0 == strcmp(Name, p->st.Name))
		{
			printf("姓名 年齡  學號  語文  數學  英語  總分 平均分\n");
			
			printf("修改前的學生資訊!\n");
			printf("%s %d %d %g %g %g %g %g\n",p->st.Name, p->st.Age, p->st.No, p->st.Score[0], p->st.Score[1], p->st.Score[2], p->st.Total, p->st.Ave);

			system("pause");
			system("cls");//清屏

			printf("請輸入新的學生姓名:");
			scanf("%s", p->st.Name);

			printf("請輸入新的學生年齡:");
			scanf("%d", &p->st.Age);

			printf("請輸入新的學生學號:");
			scanf("%d", &p->st.No);

			printf("請輸入新的學生的語文成績:");
			scanf("%f", &p->st.Score[0]);

			printf("請輸入新的學生的數學成績:");
			scanf("%f", &p->st.Score[1]);
		
			printf("請輸入新的學生的英語成績:");
			scanf("%f", &p->st.Score[2]);

			//計算總分
			p->st.Total = p->st.Score[0] + p->st.Score[1] + p->st.Score[2];
		
			//計算平均分
			p->st.Ave = p->st.Total / 3.0f;

			break;
		}

		p = p->pNext;
	}
}

//增加學生資訊
void InsertStudent(PNODE pHead)
{
	PNODE p = pHead;

	int i = 0;

	struct Student stu;//學生結構

	int pos;//插入結點的位置

	printf("請輸入插入學生的位置:");
	scanf("%d",&pos);

	while(NULL != p && i<pos-1)
	{
		p = p->pNext;

		i++;
	}

	if(NULL == p || i>pos)
	{
		printf("插入結點的位置不存在!\n");

		return;
	}

	printf("你將在第%d個學生後面插入一個學生\n",pos-1);

	printf("請輸入第%d個學生的姓名:",pos);
	scanf("%s",stu.Name);

	printf("請輸入第%d個學生的年齡:",pos);
	scanf("%d",&stu.Age);

	printf("請輸入第%d個學生的學號:",pos);
	scanf("%d",&stu.No);

	printf("請輸入第%d個學生的語文成績:",pos);
	scanf("%f",&stu.Score[0]);

	printf("請輸入第%d個學生的數學成績:",pos);
	scanf("%f",&stu.Score[1]);

	printf("請輸入第%d個學生的英語成績:",pos);
	scanf("%f",&stu.Score[2]);

	//計算總分
	stu.Total = stu.Score[0] + stu.Score[1] + stu.Score[2];

	//計算平均分
	stu.Ave = stu.Total / 3.0f;

	PNODE pNew = (PNODE)malloc(sizeof(NODE));

	if(NULL == pNew)
	{
		printf("動態記憶體分配失敗,程式終止!\n");

		exit(-1);
	}

	pNew->st = stu;
	PNODE q = p->pNext;
	p->pNext = pNew;
	pNew->pNext = q;
}

//對學生的語文成績排序
void ScortByChinese(PNODE pHead)
{
	PNODE p, q;//定義兩個指標
	
	NODE temp;

	for(p=pHead->pNext; NULL != p; p=p->pNext)
	{
		for(q=p->pNext; NULL !=q; q=q->pNext)
		{
			if(p->st.Score[0] < q->st.Score[0])//當前一個學生的語文成績小於後一個學生的語文成績時
			{
				temp.st  = p->st;//交換學生的位置
				p->st =  q->st;
				q->st = temp.st;
			}
		}
	}
}

//對學生的數學成績排序
void ScortByMath(PNODE pHead)
{
	PNODE p, q;//定義兩個指標
	
	NODE temp;

	for(p=pHead->pNext; NULL != p; p=p->pNext)
	{
		for(q=p->pNext; NULL !=q; q=q->pNext)
		{
			if(p->st.Score[1] < q->st.Score[1])//當前一個學生的數學成績小於後一個學生的數學成績時
			{
				temp.st  = p->st;//交換學生的位置
				p->st =  q->st;
				q->st = temp.st;
			}
		}
	}
}

//對學生的英語成績排序
void ScortByEnglish(PNODE pHead)
{
	PNODE p, q;//定義兩個指標
	
	NODE temp;

	for(p=pHead->pNext; NULL != p; p=p->pNext)
	{
		for(q=p->pNext; NULL !=q; q=q->pNext)
		{
			if(p->st.Score[2] < q->st.Score[2])//當前一個學生的英語成績小於後一個學生的英語成績時
			{
				temp.st  = p->st;//交換學生的位置
				p->st =  q->st;
				q->st = temp.st;
			}
		}
	}
}

//對學生的總分排序
void ScortByTotal(PNODE pHead)
{
	PNODE p, q;//定義兩個指標
	
	NODE temp;

	for(p=pHead->pNext; NULL != p; p=p->pNext)
	{
		for(q=p->pNext; NULL !=q; q=q->pNext)
		{
			if(p->st.Total < q->st.Total)//當前一個學生的總分小於後一個學生的總分時
			{
				temp.st  = p->st;//交換學生的位置
				p->st =  q->st;
				q->st = temp.st;
			}
		}
	}
}