【C语言】一个学生信息排序程序(学生信息表)【注释详细】【链表】
生活随笔
收集整理的這篇文章主要介紹了
【C语言】一个学生信息排序程序(学生信息表)【注释详细】【链表】
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目
一、編寫一個(gè)學(xué)生信息排序程序。要求:
1、可隨時(shí)輸入n個(gè)學(xué)生的信息和成績(jī)(n不設(shè)置上限)。
2、學(xué)生信息包括:學(xué)號(hào)、姓名、性別、專業(yè)、學(xué)院;三門課程成績(jī)。
3、為用戶提供一個(gè)排序選擇列表,使得用戶能夠按照上述所列信息(學(xué)號(hào)、姓名、性別、專業(yè)、學(xué)院、自定義的三門課程)中的至少一個(gè)字段進(jìn)行排序,并顯示其結(jié)果。
解題思路
本題因?yàn)閚不設(shè)置上限,數(shù)據(jù)量過(guò)大就無(wú)法使用數(shù)組了,所以下面提供一種鏈表的思路。首先定義一個(gè)結(jié)構(gòu)體用于存放單個(gè)學(xué)生的數(shù)據(jù),結(jié)構(gòu)體中定義一個(gè)結(jié)構(gòu)體變量指針指向下一個(gè)學(xué)生,構(gòu)成鏈表,每一次新加入一個(gè)學(xué)生就為其分配一塊內(nèi)存空間,并加入到鏈表串中。
完整代碼
#include<stdio.h> #include <stdlib.h> #include<string.h> typedef struct student//定義一個(gè)鏈表數(shù)據(jù)類型,不用每次都寫struct了 {char* number;//學(xué)號(hào)char* name;//姓名char* sex; //性別char* major;//專業(yè)char* college;//學(xué)院int score1;//高數(shù)成績(jī)int score2;//英語(yǔ)成績(jī)int score3;//c語(yǔ)言成績(jī)struct student* next;//鏈表的下一個(gè)元素 }student; void sortmenu();//打印排序選擇菜單 void menu();//打印選擇菜單 void add(student* p);//增加一個(gè)學(xué)生 void print(student* p);//打印數(shù)據(jù)表 student* findend(student* head);//返回新鏈表的結(jié)尾元素 student* sort(int number, student* head, int(*com) (student* p));//排序函數(shù) int compare_number(student* p);//比較相鄰兩個(gè)鏈表元素的學(xué)號(hào) int compare_name(student* p);//比較相鄰兩個(gè)鏈表元素的姓名 int compare_sex(student* p);//比較相鄰兩個(gè)鏈表元素的性別 int compare_major(student* p);//比較相鄰兩個(gè)鏈表元素的專業(yè) int compare_college(student* p);//比較相鄰兩個(gè)鏈表元素的學(xué)院 int compare_score1(student* p);//比較相鄰兩個(gè)鏈表元素的高數(shù)成績(jī) int compare_score2(student* p);//比較相鄰兩個(gè)鏈表元素的英語(yǔ)成績(jī) int compare_score3(student* p);//比較相鄰兩個(gè)鏈表元素的c語(yǔ)言成績(jī) void clearlist(student* head);//刪除數(shù)據(jù)表 int main() {int choose = 0, sortchoose = 0,number = 0;//choose選擇的序號(hào) sortchoose選擇的排序序號(hào) number統(tǒng)計(jì)現(xiàn)有學(xué)生人數(shù)student* now, * pre;//*now當(dāng)前鏈表元素的指針 *pre前一個(gè)鏈表元素的指針student* head = NULL;//鏈表頭do{menu();//打印選擇菜單scanf("%d", &choose);//讀入選項(xiàng)switch (choose){case 1://增加一個(gè)學(xué)生now = (student*)malloc(sizeof(student));//為當(dāng)前鏈表元素分配地址if (head == NULL)head = now ;//如果鏈表頭為空,則當(dāng)前鏈表元素為鏈表頭else pre->next = now;//把上個(gè)鏈表元素的next指向現(xiàn)在的鏈表元素的地址,即把當(dāng)前元素接入鏈表now->next = NULL;//當(dāng)前元素的下一個(gè)元素定為空add(now);//增加一個(gè)元素pre = now;//為下一個(gè)元素增加做準(zhǔn)備number++;//鏈表元素增加,學(xué)生人數(shù)增加break;case 2://排序sortmenu();//打印排序選擇菜單scanf("%d", &sortchoose);//讀入選項(xiàng)switch (sortchoose){case 1:head = sort(number, head, compare_number);//按學(xué)號(hào)排序并讀入新鏈表的鏈表頭pre = findend(head);//讀入新鏈表的鏈表尾printf("\n按學(xué)號(hào)排序:\n");print(head);//打印信息表break;case 2:head = sort(number, head, compare_name);pre = findend(head);printf("\n按姓名排序:\n");print(head);break;case 3:head = sort(number, head, compare_sex);pre = findend(head);printf("\n按性別排序:\n");print(head);break;case 4:head = sort(number, head, compare_major);pre = findend(head);printf("\n按專業(yè)排序:\n");print(head);break;case 5:head = sort(number, head, compare_college);pre = findend(head);printf("\n按學(xué)院排序:\n");print(head);break;case 6:head=sort(number, head, compare_score1);pre = findend(head);printf("\n按高數(shù)成績(jī)排序:\n");print(head);break;case 7:head = sort(number, head, compare_score2);pre = findend(head);printf("\n按英語(yǔ)成績(jī)排序:\n");print(head);break;case 8:head = sort(number, head, compare_score3);pre = findend(head);printf("\n按c語(yǔ)言成績(jī)排序:\n");print(head);break;default:printf("請(qǐng)重新選擇\n\n");}break;case 3:print(head);//打印信息表break;case 0: break;default:printf("請(qǐng)重新選擇\n\n"); break;}} while (choose);//當(dāng)chose為真不為零(退出為零)printf("\n正在刪除數(shù)據(jù)表...\n");clearlist(head);//刪除數(shù)據(jù)表printf("刪除成功\n");//面子工程,像模像樣,嘿嘿printf("已退出程序\n");return 0; } void menu()//打印選擇菜單 {printf("請(qǐng)選擇序號(hào):\n");printf("1:增加一個(gè)學(xué)生\n");printf("2:排序\n");printf("3:打印數(shù)據(jù)表\n");printf("0:退出\n");printf("在此輸入:"); } void sortmenu()//打印排序選擇菜單 {printf("請(qǐng)選擇排序方式:\n");printf("1:學(xué)號(hào) ");printf("2:姓名 ");printf("3:性別 ");printf("4:專業(yè) ");printf("5:學(xué)院\n");printf("6:高數(shù)成績(jī) ");printf("7:英語(yǔ)成績(jī) ");printf("8:c語(yǔ)言成績(jī)\n");printf("在此輸入:"); } void add(student* p)//增加一個(gè)學(xué)生 {p->number = (char*)malloc(100);//為新學(xué)生的學(xué)號(hào)分配內(nèi)存p->sex = (char*)malloc(10);p->name = (char*)malloc(100);p->major = (char*)malloc(100);p->college = (char*)malloc(100);printf("請(qǐng)輸入學(xué)號(hào):\n");scanf("%s", p->number);//讀入學(xué)號(hào)printf("請(qǐng)輸入姓名:\n");scanf("%s", p->name);printf("請(qǐng)輸入性別(nan或nv):\n");scanf("%s", p->sex);printf("請(qǐng)輸入專業(yè):\n");scanf("%s", p->major);printf("請(qǐng)輸入學(xué)院:\n");scanf("%s", p->college);printf("請(qǐng)輸入高數(shù)成績(jī):\n");scanf("%d", &p->score1);printf("請(qǐng)輸入英語(yǔ)成績(jī):\n");scanf("%d", &p->score2);printf("請(qǐng)輸入c語(yǔ)言成績(jī):\n");scanf("%d", &p->score3); } student* findend(student* head)//返回新鏈表的結(jié)尾元素 {student* p = head;while (p!=NULL&&p->next!= NULL)//尋找新鏈表的結(jié)尾元素{p = p->next;}return p;//返回新鏈表的結(jié)尾元素 } void print(student* head)//打印數(shù)據(jù)表 {student* p = head;int count = 1;//排名序號(hào)printf("序號(hào)\t學(xué)號(hào)\t姓名\t性別\t專業(yè)\t學(xué)院\t高數(shù)\t英語(yǔ)\tc語(yǔ)言\n");while (p != NULL){printf("%d\t%s\t%s\t%s\t%s\t%s\t%d\t%d\t%d\n",count,p->number,p->name,p->sex,p->major,p->college,p->score1,p->score2,p->score3);p = p->next;//下一個(gè)學(xué)生count++;//序號(hào)加1}printf("\n"); } student* sort(int number, student* head,int(* compare) (student* p))//按某關(guān)鍵字排序 本程序最難的代碼 //number 學(xué)生人數(shù) * head鏈表頭 int(* compare) (student* p) 排序的關(guān)鍵字,函數(shù)指針,指向比較兩個(gè)相鄰學(xué)生的函數(shù) {student* p, * q, * temp;//* p是前面的指針(探路比較大小用) * q是后面的指針(存儲(chǔ)p的前一個(gè)元素,鏈表元素交換用)* temp 中間商指針,交換元素用int i, j;//冒泡排序的兩次循環(huán)參數(shù)for (i = 0; i < number - 1; i++)//冒泡排序的趟數(shù){p = head;//p,q歸位,指向鏈表頭q = head;for (j = 0; j < number - 1 - i ; j++)//冒泡排序一趟的比較{ if (compare(p)<0)//調(diào)用compare指向的比較函數(shù){//如果現(xiàn)在的元素的某項(xiàng)數(shù)據(jù)小于下一個(gè)元素的某項(xiàng)數(shù)據(jù),則兩個(gè)鏈表元素交換位置//以下代碼比較玄學(xué),不容易講清楚,建議自己手動(dòng)代入數(shù)據(jù)或通過(guò)調(diào)試一步一步研究//本人小菜雞一枚,水平有限,代碼太復(fù)雜,希望大佬能簡(jiǎn)化下面的代碼,把兩種情況統(tǒng)一if (p == head)//如果現(xiàn)在的元素是鏈表頭{head = p->next;//新鏈表頭變?yōu)楝F(xiàn)在的元素的下一個(gè)元素q->next = p->next;temp = p->next->next;//中間變量暫存p->next->next = p;p->next = temp;p = head;q = head;}else{q->next = p->next;temp = p->next->next;p->next->next = p;p->next = temp;p = q->next;}}q = p;p = p->next;//p指向下一個(gè)元素}}return head; } int compare_number(student* p)//比較相鄰兩個(gè)鏈表元素的學(xué)號(hào),為了字母升序排列所以strcmp前面加符號(hào) {return -strcmp(p->number, p->next->number); } int compare_name(student* p)//比較相鄰兩個(gè)鏈表元素的姓名 {return -strcmp(p->name, p->next->name); } int compare_sex(student* p)//比較相鄰兩個(gè)鏈表元素的性別 {return -strcmp(p->sex, p->next->sex); } int compare_major(student* p)//比較相鄰兩個(gè)鏈表元素的專業(yè) {return -strcmp(p->major, p->next->major); } int compare_college(student* p)//比較相鄰兩個(gè)鏈表元素的學(xué)院 {return -strcmp(p->college, p->next->college); } int compare_score1(student* p)//比較相鄰兩個(gè)鏈表元素的高數(shù)成績(jī) {return (p->score1) - (p->next->score1); } int compare_score2(student* p)//比較相鄰兩個(gè)鏈表元素的英語(yǔ)成績(jī) {return (p->score2) - (p->next->score2); } int compare_score3(student* p)//比較相鄰兩個(gè)鏈表元素的c語(yǔ)言成績(jī) {return (p->score3) - (p->next->score3); } void clearlist(student* head)//刪除數(shù)據(jù)表 {student* p, * q;//* p當(dāng)前要?jiǎng)h除的鏈表元素 * q暫存p的下一個(gè)元素 p = head;//從鏈表頭開始刪除while (p != NULL){q = p->next;//暫存p的下一個(gè)元素free(p);//釋放內(nèi)存p = q;//p指向下一個(gè)元素} }運(yùn)行截圖
?//qq長(zhǎng)截圖長(zhǎng)度受限了,再補(bǔ)一張
//非法輸入或未輸入信息??
總結(jié)
以上是生活随笔為你收集整理的【C语言】一个学生信息排序程序(学生信息表)【注释详细】【链表】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 开启春光撼路者的深夜博客
- 下一篇: java版gbc模拟器怎么用,GBA/G