代码改变世界

链表实现学生成绩管理系统

2015-08-21 11:45  1784717631  阅读(1610)  评论(0编辑  收藏  举报

  第一次没有发布真是醉了,昨晚奋斗了四个小时,完成 了九成的功能,难点还是文件的加载,摧残了一个多小时,最后还是请鲁老师出山,半小时疑难杂症全消。发现了几个知识的盲点,以后要多问,有些问题貌似懂了,但是用起来还是疏忽了不少细节,多问才可以不断完善知识点的积累,以下是劳动成果

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 50

typedef struct listnode //定义链表的节点类型,
{
char name[10];
int num;
char sex[5];
int english;
int math;
int total ;
int rank;
struct listnode *next;
}node_t;

typedef struct linklist //定义链表数据类型
{
node_t *head;
node_t *tail;
int length;
}linklist_t;
/*******************************************************************************************/
linklist_t* init_lklist(linklist_t *plklist)
{
plklist->head=NULL;
plklist->tail=NULL;
plklist->length=0;
return (plklist);
}

int tail_inser_lklist(linklist_t *plklist, node_t *pnew)
{
if(plklist->head==NULL)
{
plklist->head = pnew;
plklist->tail = pnew;
plklist->length++;
}
else
{
plklist->tail->next = pnew;
plklist->tail = pnew;
plklist->length++;
}
return 0;
}

int head_inser_lklist(linklist_t *plklist, node_t *pnew)
{
if(plklist->head==NULL)
{
plklist->head = pnew;
plklist->tail = pnew;
plklist->length++;
}
else
{
pnew->next = plklist->head;
plklist->head = pnew;
plklist->length++;
}
}

int sort_list2(linklist_t *plklist)
{
int count = 0;
linklist_t sortlist;
linklist_t *slist= init_lklist(&sortlist);//定义一个新的链表,用来存放排序好的

node_t *pnew = NULL;

while(1)
{

pnew = plklist->head; //定义一个中间节点,取出1 的头结点

if(pnew == NULL) //当pnew 指向空的时候,说明1 已经取完了,跳出循环
break;

count++;

plklist->head = plklist->head->next; //把头结点向后移动,不能移动pnew节点,会死循环
pnew->next = NULL; //把pnew 从1 中断出来

if(slist->head == NULL) // 1,当2 为空的时候就直接就直接插在第一个
{
slist->head = pnew;
slist->tail = pnew;
slist->length++;
}
else // 2, 2不为空的情况
{
if(pnew->total >= slist->head->total) // 1 。2不为空,pnew小于等于2 的头结点的时候直接头插
{
head_inser_lklist(slist, pnew);
}

else if(pnew->total < slist->tail->total) // 2 。2不为空,pnew大于2 的尾节点的时候直接尾插
{
tail_inser_lklist(slist, pnew);
}
else //中间插入的情况
{

node_t *pcur = NULL;
node_t *pre = NULL;

pcur = slist->head->next;
pre = slist->head; //定义两个节点,指向前驱和后驱

while(pcur != NULL) //必须加循环
{
if(pnew->total >= pcur->total) //因为2 已经是有序的了,只要满足这个就可以直接插入了
{
pnew->next = pcur;
pre->next = pnew;
slist->length++;
break; //插入完成后,跳出循环,在1 中再取一个元素
}
else //移动前驱和后驱
{
pre = pcur;
pcur = pcur->next;
}
}
}
}
}
plklist->head = slist->head;//把有序的新链表赋给原来的链表,返回结果
plklist->tail = slist->tail;
plklist->length = slist->length;

return count;
}

int search_lklist(linklist_t *plklist, char name[])
{
int i = 1;
node_t *pcur = plklist->head;

while(pcur != NULL && strcmp(pcur->name,name))
{
pcur = pcur->next;
i++;
}
if(i > plklist->length)
{
printf("can not find anything !\n");
exit(-1);
}

printf("%d\t%s\t %s\t ",pcur->num,pcur->name,pcur->sex);
printf("%d\t\t%d\t %d\t %d\n",pcur->english,pcur->math,pcur->total,pcur->rank);

return i; //返回位置
}

int delete_lklist(linklist_t *plklist, int pos) //瑕佸湪绗簩涓綅缃紑濮嬫彃鍏?
{
int i=1;
node_t *p = plklist->head;

if(pos == 1 ||pos == 0) //删除第一个元素独立处理
{
plklist->head = plklist->head->next;
p->next = NULL;
}
else
{
while(p != NULL && i <pos-1) //绉诲姩娲诲姩鑺傜偣鍒皃os浣嶇疆鐨勫墠涓€涓?
{

p = p->next;
i++;
}
if( i<pos-1 ||p==NULL ) //鍒ゆ柇鏄惁瓒婄晫
{
printf("delete error !\n");
exit(-1);
}

p->next = p->next->next;
}
return 0;
}

 

int show_llist(linklist_t *plklist)
{
node_t *pcur = plklist->head;

while(pcur != NULL)
{
printf("%d\t%s\t %s\t ",pcur->num,pcur->name,pcur->sex);
printf("%d\t\t%d\t %d\t %d\n",pcur->english,pcur->math,pcur->total,pcur->rank);
pcur = pcur->next;
}
}

/**********************************************************************************************/
// 以下是功能模块函数 /
/***********************************************************************************************/
/**************************************1.inputinfo****************************************************/
int inputinfo(linklist_t *plist)
{

printf("********************please input one student information**********************\n");

node_t *pnode;
pnode=(node_t*)malloc(sizeof(node_t));
pnode->next = NULL;

printf("student no. :");
scanf("%d",&pnode->num);

while(pnode->num != 0)
{

printf("student name :");
scanf("%s",pnode->name);

printf("student sex :");
scanf("%s",pnode->sex);

printf("student english :");
scanf("%d",&pnode->english);

printf("student math :");
scanf("%d",&pnode->math);

pnode->total = pnode->english + pnode->math;
pnode->rank = 0;

tail_inser_lklist(plist, pnode);

printf("********************please input one student information**********************\n");

pnode=(node_t*)malloc(sizeof(node_t));
pnode->next = NULL;

printf("student no. :");
scanf("%d",&pnode->num);

}
}

/**************************************2.display****************************************************/
int display_info(linklist_t *plist)
{
int i;

printf("*********************the student information**********************\n");
printf("num name sex english math total rank\n");
printf("*********************************************************************\n");

show_llist(plist);

return 0;
}

/*******************************3.sortinfo**********************************************/
int sort_info(linklist_t *plist)
{
int i = 1;
node_t *pcur = plist->head;

sort_list2(plist); //插入法排序,从大到小

pcur = plist->head;

while(pcur != NULL)
{
pcur->rank=i; //给排名赋值
i++;
pcur = pcur->next;
}

display_info(plist);
}

/****************************************4.search*********************************************************/
int search_info(linklist_t *plist)
{
char name[10];

printf("input student name :");
scanf("%s",name);

printf(" ******************the student information**********************\n");
printf("num name sex english math total rank\n");
printf(" ******************************************************************\n");
search_lklist(plist, name);

}

/****************************************5.delete***********************************************************/


int delete_info(linklist_t *plist)
{
char name[10];
int pos;

printf("input the delete student name :");
scanf("%s",name);

printf("\nthe delete student information :\n");
printf("num name sex english math total rank\n");
printf("********************************************************************\n");

pos = search_lklist(plist, name); //找到所在的位置

delete_lklist(plist, pos); //根据位置删除
}

/*****************************************6.save********************************************************************/
int save_info(linklist_t *plist)
{
FILE *fp;
int count;
int j=0;
node_t *pcur = plist->head;

if((fp=fopen("student2.dat","wb+"))==NULL)
{
printf("open file error and save error !\n");
exit(0);
}
while(pcur != NULL)
{
if(fwrite(pcur,sizeof(node_t),1,fp)!=1)
{
printf("write error\n");
exit(-1);
}
j++;
pcur = pcur->next;
}
printf("save success!\n");
printf("save num =%d \n",j);
fclose(fp);
}

/****************************************7.load****************************************************/

linklist_t * load_info(linklist_t *plist) //必须在主函数把链表传进来,否则执行完子函数后链表就释放了
{
FILE *fp;
//linklist_t plklist;
//linklist_t *pplist = init_lklist(&plklist); //不能定义局部链表,无法返回
int i;

node_t *pcur = (node_t*)malloc(sizeof(node_t));
memset(pcur,0,sizeof(node_t));

printf("num name sex english math total rank\n");
if((fp=fopen("student2.dat","rb+"))==NULL)
{
printf("open file error !\n");
exit(-1);
}
/*
while(!feof(fp))
{
i = fread(pcur, sizeof(node_t), 1, fp);
if(i==0) //如果没有读到内容,就跳出循环,否则就插入了一个空节点
break;
printf("%d\t%s\t %s\t ",pcur->num,pcur->name,pcur->sex);
printf("%d\t\t%d\t %d\t %d\n",pcur->english,pcur->math,pcur->total,pcur->rank);

}
*/


while(feof(fp)==0)
{
i= fread(pcur, sizeof(node_t), 1, fp);//读取成功就返回1,否则返回0

if(i==0) //如果没有读到内容,就跳出循环,否则就插入了一个空节点
break;
tail_inser_lklist(plist, pcur);

pcur = (node_t*)malloc(sizeof(node_t)); //必须创建新的节点才可以插入,节点不能重复使用
memset(pcur,0,sizeof(node_t));

}
//printf("length= %d\n",plist->length); //调试用的,看读取并插入了链表有多少节点

fclose(fp); //操作完之后立即关闭

show_llist(plist);

return 0;
}

/***************************************************************************************************/
int main(int argc, char* argv[])
{
int sele;
linklist_t lklist;
linklist_t *list = init_lklist(&lklist);
while(1)
{
//界面
printf("*****************************************************************************\n");
printf("\t\tstudent score manager syster\n");
printf("*****************************************************************************\n");
printf("1\tinput student score info\n");
printf("2\tdisplay student score info\n");
printf("3\tsort student score info\n");
printf("4\tfind student score info\n");
printf("5\tdelete student score info\n");
printf("6\tsave student score info\n");
printf("7\tload student score info\n");
printf("8\texit\n");
printf("\n");
printf("please input your selection : ");

scanf("%d",&sele);
switch(sele)
{
case 1:
inputinfo(list);
break;
case 2:
display_info(list);
break;
case 3:
sort_info(list);
break;
case 4:
search_info(list);
break;
case 5:
delete_info(list);
break;
case 6:
save_info(list);
break;
case 7:
load_info(list);
break;
case 8:
return 0;
default:
return 0;
}
}
}