数据结构课程设计报告算术表达式求值演示程序优质资料_第1页
数据结构课程设计报告算术表达式求值演示程序优质资料_第2页
数据结构课程设计报告算术表达式求值演示程序优质资料_第3页
数据结构课程设计报告算术表达式求值演示程序优质资料_第4页
数据结构课程设计报告算术表达式求值演示程序优质资料_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数据结构课程设计报告-算术表达式求值演示程序优质资料(可以直接使用,可编辑优质资料,欢迎下载)

数据结构课程设计报告-算术表达式求值演示程序优质资料(可以直接使用,可编辑优质资料,欢迎下载)软件学院课程设计报告书课程名称数据结构设计题目算术表达式求值演示程序专业班级学号姓名指导教师2021年12月目录1.设计时间22.设计目的23.设计任务24.设计内容24.1需求分析24.2总体设计24.2.1抽象数据类型定义24.2.2函数模块说明3主函数流程图4函数模块调用关系54.2.5运算符间的优先关系54.3详细设计64.3.1数据类型的定义6函数调用关系8主要模块的算法描述84.4测试与分析104.4.1测试104.4.2分析114.5附录115.总结与展望16参考文献17成绩评定171设计时间.32设计目的掌握栈的使用和把一个表达式翻译成能够正确求值的一个机器指令序列的原理。3设计任务设计一个程序,演示用算符优先法对算术表达式求值的过程。4设计内容4.1需求分析1、程序所能达到的功能:能够处理以字符序列的形式输入的不含变量的实数表达式,正确处理负数与小数,判断表达式是还语法正确(包含分母不能为零的情况),正确实现对算术四则混合运算表达式的求值,能够将计算中遇到的问题和结果以文件的形式予以存储。2、输入的形式和输入值的范围:以字符串的形式输入表达式,以“#”结束。3、输出的形式:在计算过程中遇到的问题或最终的答案将显示在屏幕上,同时所计算的表达式的最终的结果也将保存在文件中。4、测试数据:输入“3*(7-2)#”时,输出“15.000000”,测试正确;输入“!(9-2)#”时,输出“输入错误!”,测试正确。4.2总体设计抽象数据类型定义ADTStack{数据对象:D={|∈ElemSet,i=1,2,…,n,n≧0}数据对象:R1={<>|,,i=2,…,n}约定端为栈顶,端为栈底。基本操作:InitStack(&S)操作结果:构造一个空栈S。GetTop(S)初始条件:栈S已存在。操作结果:用P返回S的栈顶元素。Push(&S,ch)初始条件:栈S已存在。操作结果:插入元素ch为新的栈顶元素。Pop(&S)初始条件:栈S已存在。操作结果:删除S的栈顶元素。In(ch)操作结果:判断字符是否是运算符,运算符即返回1。Precede(c1,c2)初始条件:c1,c2为运算符。操作结果:判断运算符优先权,返回优先权高的。Operate(a,op,b)初始条件:a,b为整数,op为运算符。操作结果:a与b进行运算,op为运算符,返回其值。num(n)操作结果:返回操作数的长度。EvalExpr()初始条件:输入表达式合法。操作结果:返回表达式的最终结果。}ADTStack4.2.2函数模块说明为实现算符优先算法,可以使用两个工作栈。一个称做OPTR,用以寄存运算符;另一个称做OPND,用以寄存操作数或运算结果。算法的基本思想是:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈底元素(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。算法中还调用了两个函数。其中Precede是判定运算符栈顶运算符θ1与读入的运算符θ2之间优先关系的函数;Operateo为进行二元运算aθb的函数,如果是编译表达式,则产生这个运算的一组相应指令并返回存放结果的中间变量名;如果是解释执行表达式,则直接进行该运算,并返回运算结果。4.2.3主函数流程图4.2.4函数模块调用关系4.2.5运算符间的优先关系θ1θ2+-*/()#+>>><<>>->>><<>>*>>>><>>/>>>><>>(<<<<<=)>>>>>>#<<<<<=4.3详细设计4.3.1数据类型的定义及基本操作//=====ADTStack的表示与实现=====//-----栈的顺序存储表示-----#defineSTACK_INIT_SIZT100;#defineSTACKINCREMENT10typedefstruct{SElemType*base;SElemType*top;intstacksize;}SqStack;//-----基本操作的算法描述-----StatusInitStack(SqStack&S){S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!S.base)exit(OVERFLOW);S.top=S.base;S.stacksize=STACK_INIT_SIZE;returnOK;}StatusGetTop(SqStackS,SElemType&e){if(S.top==S.base)returnERROR;e=*(S.top-1);returnOK;}StatusPush(SqStack&S,SElemTypee){if(S.top-S.base>=S.stacksize){S.base=(SElemType*)realloc(S.base,(S.StackSize+STACKINCREMENT)*sizeof(SElemType));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;returnOK;}StatusPop(SqStack&S,SElemType&e){if(S.top==S.base)returnERROR;e=*--S.top;returnOK;}OperandTypeEvaluateExpession(){InitStack(OPTR);Push(OPTR,’#’);InitStack(OPND);c=getchar();while(c!’#’||GetTop(OPTR)!=’#’){if(!In(c,OP)){Push((OPND,c);c=getchar();)elseswitch(Precede(GetTop(OPTR),c)){case’<’:Push(OPTR,c);c=getchar();break;case’=’:Pop(OPTR,x);c=getchar();break;case’>’:Pop(OPTR,theta);Pop(OPND,b);Pop(OPND,a);Push(OPND,Operate(a,theta,b));break;}}}4.3.2函数调用关系4.3.3主要模块的算法描述voidmain(){SqStack_TOPTR;SqStack_NOPND;floata,b,i;chartheta,c,x;InitStack_T(&OPTR);Push_T(&OPTR,’#’);InitStack_N(&OPND);printf(“请输入表达式关以’#’结尾:\n”);c=getchar();if(c==35||(c>=40&&c<=43)||c==45||(c>=47&&c<=57)){while(c!=’#’||GetTop_T(&OPTR)!=’#’){if(c>=48&&c<=57){i=(float)c-48;Push_N(&OPND,i);c=getchar();}else{switch(Precede(GetTop_T(&OPND),c)){case’<’:Push_T(&OPTR,c);c=getchar();break;case’=’:x=Pop_T(&OPTR);c=getchar();break;case’>’:theat=Pop_T(&OPTR);b=Pop_N(&OPND);a=Pop_N(&OPND);Push_N(&OPND,Operate(a,theta,b));break;}}}printf(“结果是%f\n”,GetTop_N(&OPND));}elseprintf(“输入错误!\n”);}4.4测试与分析测试加法测试,输入正确,输出正确,测试正确:减法测试,输入正确,输出正确,测试正确:乘法测试,输入正确,输出正确,测试正确:除法测试,输入正确,输出正确,测试正确:输入表达式正确,输出正确,测试正确:输入表达式错误,能正确判断,测试正确:4.4.2分析内容包括:1、调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分析:遇到的问题:调试过程中遇到了输入非法字符不输出“错误!”的情况。解决的办法:查ASCII码表得知运算符’+’,’-‘,’*’,’/’,’(‘,’)’,’#’和运算数’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’相应的ASCII值。在主程序中加入了判断语句,判断输入的是否为运算符或运算数。如果是,则进行正常运算;如果不是,则返回错误。2、算法的时间复杂度和空间复杂度的分析:中缀表达式运算时间主要用在字符串扫描和算符优先权的比较上。把#看作运算符,操作数与运算符个数相同,最坏情况下优先级比较是n/2次,即运算顺序完全是逆序的,每个字符扫描一遍是O(n)的,所以整个算法复杂度是O(n2)的。算法中用到两个栈,分别为O(n/2),其算法空间复杂度是O(n)。4.5附录#include"stdio.h"#include"stdlib.h"#defineOK1#defineERROR0#defineOVERFLOW0#defineSTACK_INIT_SIZE100#defineSTACKINCREMENT10typedefstruct{char*base;char*top;intstacksize;}SqStack_T;typedefstruct{float*base;float*top;intstacksize;}SqStack_N;voidInitStack_T(SqStack_T*S){ (*S).base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));if(!(*S).base)exit(OVERFLOW); (*S).top=(*S).base; (*S).stacksize=STACK_INIT_SIZE;}voidInitStack_N(SqStack_N*S){ (*S).base=(float*)malloc(STACK_INIT_SIZE*sizeof(float));if(!(*S).base)exit(OVERFLOW); (*S).top=(*S).base; (*S).stacksize=STACK_INIT_SIZE;}charGetTop_T(SqStack_T*S){chare;if((*S).top==(*S).base)returnERROR; e=*((*S).top-1);returne;}floatGetTop_N(SqStack_N*S){floate;if((*S).top==(*S).base)returnERROR; e=*((*S).top-1);returne;}charPush_T(SqStack_T*S,chare){if((*S).top-(*S).base>=(*S).stacksize){(*S).base=(char*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(char));if(!(*S).base)exit(OVERFLOW); (*S).top=(*S).base+(*S).stacksize; (*S).stacksize+=STACKINCREMENT;}*((*S).top)++=e;returnOK;}floatPush_N(SqStack_N*S,floate){if((*S).top-(*S).base>=(*S).stacksize){ (*S).base=(float*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(float));if(!(*S).base)exit(OVERFLOW); (*S).top=(*S).base+(*S).stacksize; (*S).stacksize+=STACKINCREMENT;}*((*S).top)++=e;returnOK;}charPop_T(SqStack_T*S){chare;if((*S).top==(*S).base)returnERROR; e=*(--(*S).top);returne;}floatPop_N(SqStack_N*S){floate;if((*S).top==(*S).base)returnERROR; e=*(--(*S).top);returne;}charm[7]="+-*/()#";charn[7][7]={">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<=",">>>>>>","<<<<<="};charPrecede(chara,charb){inti=0,j=0;while(m[i]!=a) i++;while(m[j]!=b) j++;return(n[i][j]);}floatOperate(floata,chartheta,floatb){floatr;switch(theta){case'+':r=a+b;break;case'-':r=a-b;break;case'*':r=a*b;break;case'/':if(b!=0)r=a/b;elseprintf("输入错误!");break;}returnr;}voidmain(){SqStack_TOPTR; SqStack_NOPND;floata,b,i;chartheta,c,x; InitStack_T(&OPTR);Push_T(&OPTR,'#'); InitStack_N(&OPND); printf("请输入表达式并以'#'结尾:\n"); c=getchar();if(c==35||(c>=40&&c<=43)||c==45||(c>=47&&c<=57)){while(c!='#'||GetTop_T(&OPTR)!='#'){if(c>=48&&c<=57){ i=(float)c-48; Push_N(&OPND,i); c=getchar();}else{switch(Precede(GetTop_T(&OPTR),c)){case'<':Push_T(&OPTR,c);c=getchar();break;case'=':x=Pop_T(&OPTR);c=getchar();break;case'>':theta=Pop_T(&OPTR);b=Pop_N(&OPND);a=Pop_N(&OPND);Push_N(&OPND,Operate(a,theta,b));break;}}}printf("结果是%f\n",GetTop_N(&OPND));}elseprintf("输入错误!\n");}}5总结与展望通过这段时间的课程设计,本人对计算机的应用、数据结构的作用以及C语言的使用都有了更深的了解。当然也遇到不少问题,也正是国为这些问题引发的思考给我带来了收获。从当初不喜欢上机写程序到现在能主动写程序,从当初拿着程序不知从何下手到现在知道如何分析问题,如何用专业知识解决实际问题的转变。我发现无论是专业知识还是动手能力,自己都有很大程度的提高。在实际上机操作过程中,不仅是让我们了解数据结构的理论知识,更重要的是培养解决实际问题的能力,为后续课程的学习及实践打下良好的基础。这次课程设计让我更加了解大一学到的C和这个学期学到的数据结构的紧密联系。设计题目不仅要求设计者对课本知识有较深刻的了解,同时要有较强的思维动手能力。这次的课程设计让我有一个深刻的体会:严谨!编程最需要的就是严谨,往往检查到的错误是在某个括号、分号、引号等不应该犯错的地方上。程序设计时难免遇到错误,但这不是坏事情,它可以让我发现自己的薄弱环节,在具体操作中还可以巩固所学的C及数据结构。更加体会到了C的语句简洁、使用灵活、执行效率高等特点。参考文献[1]严蔚敏.吴伟民.数据结构(C语言版).北京:清华大学出版社,2007[2]谭浩强著.C程序设计(第二版).北京:清华大学出版社,2005成绩评定成绩教师签字//要求用C语言完成课程设计职工信息管理系统—单链表实现#include<stdio.h>#include<stdlib.h>#include<string.h>intsaveflag=0;/*是否需要存盘的标志变量*/structemployee{ charname[15]; charnum[10];/*工号*/ charsex[4]; charbm[15]; charzc[20]; intgz;};typedefstructnode{ structemployeedata; structnode*next;}Node,*Link;//Linkl(注意是:字母l不是数字1)voidadd(Linkl);voiddisp(Linkl);//查看职工所有信息voiddel(Linkl);//删除功能Node*Locate(Linkl,charfindmess[],charnameornum[]);voidQur(Linkl);//查询功能voidTongji(Linkl);//统计voidSort(Linkl);//排序voidModify(Linkl);//修改功能voidsave(Linkl);//将单链表l中的数据写入文件voidprinte(Node*p);//本函数用于打印链表中某个节点的数据内容*///以下4个函数用于输出中文标题voidprintstart();voidWrong();voidNofind();voidprintc();voidmenu(){ printf("\t*****************************************************************\n"); printf("\t**\n"); printf("\t*职工信息管理系统_结构体数组实现*\n"); printf("\t**\n") printf("\t*[1]增加职工信息[2]删除职工信息*\n"); printf("\t*[3]查询职工信息[4]修改职工信息*\n"); printf("\t*[5]插入职工记录[6]统计职工记录*\n"); printf("\t*[7]排序[8]保存职工信息*\n"); printf("\t*[9]显示数据[0]退出系统*\n"); printf("\t**\n"); printf("\t*****************************************************************\n");}//voidmenu菜单结束voidDisp(Linkl)//显示单链表l中存储的职工记录,内容为employee结构中定义的内容{ intcount=0; Node*p; p=l->next;//l存储的是单链表中头结点的指针,该头结点没有存储职工信息,指针域指向的后继结点才有职工信息 if(!p)/*p==NULL,NUll在stdlib中定义为0*/ { printf("\n=====>提示:没有职工记录可以显示!\n"); return; } printf("\t\t\t\t显示结果\n"); printstart();//打印横线 printc();//打印各学科标题 printf("\n"); while(p)//逐条输出链表中存储的职工信息 { printe(p); p=p->next; } printstart(); printf("\n");}//voidDisp结束voidprintstart(){ printf("-----------------------------------------------------------------------\n");}voidWrong(){ printf("\n=====>提示:输入错误!\n");}voidNofind(){ printf("\n=====>提示:没有找到该职工!\n");}voidprintc()/*本函数用于输出中文*/{ printf("工号\t姓名性别部门职称工资总工资平均工资\n");}voidprinte(Node*p)/*本函数用于打印链表中某个节点的数据内容*/{ printf("%-12s%s\t%s\t%d\t%d\t%d\t%d\t%d\n", p->data.num,p->,p->data.sex,p->data.bm,p->data.zc,p->data.gz);}//Locate(l,findmess,"num");/*该函数用于定位连表中符合要求的结点,并返回该指针*/Node*Locate(Linkl,charfindmess[],charzcornum[]){ Node*r; if(strcmp(zcornum,"num")==0)/*按工号查询*/ { r=l->next; while(r!=NULL) { if(strcmp(r->data.num,findmess)==0)/*若找到findmess值的工号*/ returnr; r=r->next; } } elseif(strcmp(zcornum,"zc")==0)/*按职称查询*/ { r=l->next; while(r!=NULL) { if(strcmp(r->data.zc,findmess)==0)/*若找到findmess值的职工职称*/ returnr; r=r->next; } } return0;/*若未找到,返回一个空指针*/}//add()函数中,无节点时,r指向list头,有节点时,r指向末尾节点voidAdd(Linkl)/*增加职工*/{ Node*p,*r,*s;/*实现添加操作的临时的结构体指针变量*/ charnum[10]; intflag=0; r=l; s=l->next;//链表没有节点时,s=null;/链表有节点时,指向第一个职工节点 while(r->next!=NULL)//如果存在后继结点时,r指针后移一个 r=r->next;/*将指针移至于链表最末尾,准备添加记录*/ while(1) { printf("请你输入工号(以'0'返回上一级菜单:)"); scanf("%s",num); if(strcmp(num,"0")==0)//输入'0',跳出while(1),即跳出add()函数 break; s=l->next;//作用?每次从第一个节点开始找,看num是否重复。 while(s)//工号重复时,返回主菜单 { if(strcmp(s->data.num,num)==0) { printf("=====>提示:工号为'%s'的职工已经存在,若要修改请你选择'4修改'!\n",num); flag=1;//break; return; } s=s->next; }//while(s) p=(Node*)malloc(sizeof(Node));//生成没赋值的新节点p strcpy(p->data.num,num); printf("请你输入姓名:"); scanf("%s",p->); getchar(); printf("请你输入性别:"); scanf("%s",p->data.sex); getchar(); printf("请你输入职工所在部门:"); scanf("%d",&p->data.bm); getchar(); printf("请你输入职工职称:"); scanf("%d",&p->data.zc); getchar(); printf("请你输入职工工资:"); scanf("%d",&p->data.gz); getchar(); /*信息输入已经完成*/ p->next=NULL;/*表明这是链表的尾部结点*/ r->next=p;/*将新建的结点加入链表尾部中*/ r=p; saveflag=1; }//while(1)} //voidAdd增加结束voidDel(Linkl)/*删除*/{ intsel; Node*p,*r;/*实现删除操作的临时的结构体指针变量*/ charfindmess[20]; if(!l->next)//当list无后继结点时,提示和结束返回del() { printf("\n=====>提示:没有记录可以删除!\n"); return; } printf("\n=====>1按工号删除\n=====>2按姓名删除\n"); scanf("%d",&sel); if(sel==1)//按工号删除 { printf("请你输入要删除的工号:"); scanf("%s",findmess); p=Locate(l,findmess,"num"); if(p) { r=l; while(r->next!=p) r=r->next;//从第一个结点找起,直到发现r->next=p,是待删除结点,跳出循环 r->next=p->next;//r r->next(p)p->next free(p); printf("\n=====>提示:该职工已经成功删除!\n"); saveflag=1; } else Nofind();//显示一句话 }//if(sel==1) elseif(sel==2)//按姓名删除 { printf("请你输入要删除的姓名:"); scanf("%s",findmess); p=Locate(l,findmess,"name"); if(p) { r=l; while(r->next!=p) r=r->next; r->next=p->next;//r r->next(p)p->next free(p); printf("\n=====>提示:该职工已经成功删除!\n"); saveflag=1; } else Nofind(); }//if(sel==2) else Wrong();//显示输入错误的话}//voidDel删除结束voidQur(Linkl)//查询功能{ intsel; charfindmess[20]; Node*p;//实现查询操作的临时的结构体指针变量 if(!l->next) { printf("\n=====>提示:没有资料可以查询!\n"); return; } printf("\n=====>1按工号查找\n=====>2按职称查找\n"); scanf("%d",&sel); if(sel==1)/*工号*/ { printf("请你输入要查找的工号:"); scanf("%s",findmess); p=Locate(l,findmess,"num"); if(p) { printf("\t\t\t\t查找结果\n"); printstart();//打印横线 printc();//打印各学科标题 printe(p);//打印p结点各个数据成员的值 printstart();//打印横线 } else Nofind(); }//if(sel==1) elseif(sel==2)/*职称*/ { printf("请你输入要查找的职称:"); scanf("%s",findmess); p=Locate(l,findmess,"zc"); if(p) { printf("\t\t\t\t查找结果\n"); printstart(); printc(); printe(p); printstart(); } else Nofind(); } else Wrong();}//voidQur查询结束voidModify(Linkl)//修改功能{ Node*p; charfindmess[20]; if(!l->next) { printf("\n=====>提示:没有资料可以修改!\n"); return; } printf("请你输入要修改的职工工号:"); scanf("%s",findmess); p=Locate(l,findmess,"num"); if(p) { printf("请你输入新工号(原来是%s):",p->data.num); scanf("%s",p->data.num); printf("请你输入新姓名(原来是%s):",p->); scanf("%s",p->); getchar(); printf("请你输入新性别(原来是%s):",p->data.sex); scanf("%s",p->data.sex); getchar(); printf("请你输入新的部门(原来是%s):",p->data.bm); scanf("%d",&p->data.bm); printf("请你输入新的职称(原来是%s):",p->data.zc); scanf("%d",&p->data.zc); getchar(); printf("请你输入新的工资(原来是%d):",p->data.gz); scanf("%d",&p->data.gz); printf("\n=====>提示:资料修改成功!\n"); //shoudsave=1; } else Nofind();//if(p)结束}//voidModify(Linkl)//修改功能结束//插入记录:按工号查询到要插入的节点的位置,然后在该工号之后插入一个新节点。voidInsert(Linkl){ Node*s,*r,*p;/*p指向插入位置,p指新插入记录节点*/ charch,new_num[10],old_num[10]; //old_num[]保存插入点位置之前的工号,new_num[]保存输入的新记录的工号 intflag=0; s=l->next; system("cls"); Disp(l); while(1) { //stringinput(s,10,"pleaseinputinsertlocationaftertheNumber:"); printf("请你输入已存在的工号(以'0'返回上一级菜单:)"); scanf("%s",old_num); if(strcmp(old_num,"0")==0)//输入'0',跳出while(1),即跳出Insert()函数 return; s=l->next;//作用?每次从第一个节点开始找 flag=0; while(s)/*查询该工号是否存在,flag=1表示该工号存在*/ { if(strcmp(s->data.num,old_num)==0) { flag=1; break; } s=s->next; } if(flag==1) break;/*若工号存在,则进行插入之前的新记录的输入操作*/ else { getchar(); printf("\n=====>Thenumber%sisnotexisting,tryagain?(y/n):",old_num); scanf("%c",&ch); if(ch=='y'||ch=='Y') {continue;} else {return;}//回主菜单 } }//while(1) /*以下新记录的插入新节点,工号不能跟已存在的工号相同,操作与Add()相同*/ printf("请你输入待插入的工号(以'0'返回上一级菜单:)"); scanf("%s",new_num); if(strcmp(new_num,"0")==0)//输入'0',跳出while(1),即跳出add()函数 return; s=l->next;//作用?每次从第一个节点开始找,看num是否重复。 while(s)//工号重复时,返回主菜单 { if(strcmp(s->data.num,new_num)==0) { printf("=====>提示:工号为'%s'的职工已经存在'!\n",new_num); flag=1; return; } s=s->next; }//while(s) p=(Node*)malloc(sizeof(Node)); if(!p) { printf("\nallocatememoryfailure");/*如没有申请到,打印提示信息*/ return;/*返回主界面*/ } strcpy(p->data.num,new_num); printf("请你输入姓名:"); scanf("%s",p->); getchar(); printf("请你输入性别:"); scanf("%s",p->data.sex); getchar(); printf("请你输入部门:"); scanf("%d",&p->data.bm); getchar(); printf("请你输入职称:"); scanf("%d",&p->data.zc); getchar(); printf("请你输入工资:"); scanf("%d",&p->data.gz); getchar(); //信息输入已经完成 p->next=NULL;/*表明这是链表的尾部结点*/ saveflag=1;/*在main()有对该全局变量的判断,若为1,则进行存盘操作*/ /*将指针赋值给r,因为l中的头节点的下一个节点才实际保存着学生的记录*/ r=l->next; while(1) { if(strcmp(r->data.num,old_num)==0)/*在链表中插入一个节点*/ { p->next=r->next; r->next=p; break; } r=r->next; }// while(1),r作为查询指针,依次从第一个节点找起,找到后跳出while(1)循环 Disp(l); printf("\n\n"); //getchar();}voidTongji(Linkl)//统计{ Node*max,*min;/*用于指向工资最高的节点*/ Node*t=l->next; if(!t) { system("cls"); printf("\n=====>Notemployeerecord!\n"); getchar(); return; } system("cls"); Disp(l); max=min=t; while(t) { if(t->data.gz>=max->data.gz)max=t; if(t->data.gz<=min->data.gz)min=t; t=t->next; printf("最高工资为:%d\n",max); printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",t->data.num,t->,t->data.sex,t->data.bm,t->data.zc,t->data.gz);printf("最低工资为:%d\n",min); printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",t->data.num,t->,t->data.sex,t->data.bm,t->data.zc,t->data.gz); }}voidSort(Linkl)//排序{ Linkll; Node*p,*rr,*s; inti=0; if(l->next==NULL) {system("cls"); printf("\n=====>Notemployeerecord!\n"); getchar(); return; } ll=(Node*)malloc(sizeof(Node));/*用于创建新的节点*/ if(!ll) { printf("\nallocatememoryfailure");/*如没有申请到,打印提示信息*/ return;/*返回主界面*/ } ll->next=NULL; system("cls"); Disp(l);/*显示排序前的所有职工记录*/ p=l->next; while(p)/*p!=NULL*/ { s=(Node*)malloc(sizeof(Node));/*新建节点用于保存从原链表中取出的节点信息*/ if(!s)/*s==NULL*/ { printf("\nallocatememoryfailure");/*如没有申请到,打印提示信息*/ return;/*返回主界面*/ } s->data=p->data;/*填数据域*/ s->next=NULL;/*指针域为空*/ rr=ll; /*rr链表于存储插入单个节点后保持排序的链表,ll是这个链表的头指针,每次从头开始查找插入位置*/ while(rr->next!=NULL&&rr->next->data.gz>=p->data.gz) {rr=rr->next;}/*指针移至总分比p所指的节点的总分小的节点位置*/ if(rr->next==NULL)/*若新链表ll中的所有节点的总分值都比p->data.gz大时,就将p所指节点加入链表尾部*/ rr->next=s; else/*否则将该节点插入至第一个总分字段比它小的节点的前面*/ { s->next=rr->next; rr->next=s; } p=p->next;/*原链表中的指针下移一个节点*/ } l->next=ll->next;/*ll中存储是的已排序的链表的头指针*/ Disp(l); saveflag=1; printf("\n=====>sortcomplete!\n");}voidSave(Linkl){ FILE*fp; Node*p;//实现保存操作的临时的结构体指针变量 intflag=1,count=0; fp=fopen("employee.txt","wb"); if(fp==NULL) { printf("\n=====>提示:重新打开文件时发生错误!\n"); return; } p=l->next;//p指向第一个记录结点 while(p) { if(fwrite(p,sizeof(Node),1,fp)==1)//将第一个记录结点值写入文件 { p=p->next;//依次写入第二个结点的值, count++;//文件的记录数+1 } else { flag=0; break; } }//while(p) if(count>0) { printf("\n=====>提示:文件保存成功.(有%d条记录已经保存.)\n",count); saveflag=0; } else { system("cls"); printf("保存文件失败,'0'条记录被保存!\n"); } fclose(fp);}//voidSave结束voidmain(){ Linklist;/*定义链表*///structnode*list; FILE*fp;/*文件指针*/ intchoose;/*保存选择结果变量*/ charch;/*保存(y,Y,n,N)*/ intcount=0;/*保存文件中的记录条数(或结点个数)*/ structnode*p,*r;/*定义记录指针变量*/ printf("\t\t\t\t职工信息管理系统\n\t\t\t\t\n"); list=(structnode*)malloc(sizeof(structnode)); if(!list) { printf("\nallocatememoryfailure");/*如没有申请到,打印提示信息*/ return;/*返回主界面*/ } list->next=NULL; r=list; fp=fopen("employee.txt","rb"); if(fp==NULL) { printf("\n=====>提示:文件还不存在,是否创建?(y/n)\n"); scanf("%c",&ch); if(ch=='y'||ch=='Y') fp=fopen("employee.txt","ab+"); else exit(0); }// if(fp==NULL) printf("\n=====>提示:文件已经打开,正在导入记录......\n"); while(!feof(fp))//没有到文件尾时,循环 { p=(structnode*)malloc(sizeof(structnode)); if(!p) { printf("memorymallocfailure!\n");/*没有申请成功*/ exit(0);/*退出*/ } if(fread(p,sizeof(structnode),1,fp))/*读文件的已有内容放入结点中*/ { p->next=NULL; r->next=p; r=p;/*将该结点挂入链表中,r指向最后的节点*/ count++; } }//while(!feof(fp)) fclose(fp);/*关闭文件*/ printf("\n=====>提示:记录导入完毕,共导入%d条记录.\n",count); while(1) { menu(); printf("\t\t====>请选择:"); scanf("%d",&choose); if(choose==0) { if(saveflag==1) { getchar(); printf("\n=====>提示:资料已经改动,是否将改动保存到文件中(y/n)?\n"); scanf("%c",&ch); if(ch=='y'||ch=='Y') Save(list); }//if printf("\n=====>提示:你已经退出系统,再见!\n"); break; }//if switch(choose) { case1:Add(list); break;/*增加职工记录*/ case2:Del(list); break;/*删除职工记录*/ case3: Qur(list); break;/*查询职工记录*/ case4: Modify(list); break;/*修改职工记录*/ case5: Insert(list); break;/*插入职工记录*/ case6: Tongji(list); break;/*统计职工记录*/ case7: Sort(list); break;/*排序职工记录*/ case8: Save(list); break;/*保存职工记录*/ case9: system("cls"); Disp(list); break;/*显示职工记录*/ default: Wrong(); getchar(); break; }//switch(choose) }//while(1)}//main()/**/HUNAN课程实习报告题目:哈希表学生姓名唐鹏学生学号202108080216专业班级物联2班指导老师吴帆2021年4月2日本程序来自于图书馆靠书名来检索想要查找的书问题。本程序要求:(1)根据输入建立图书名称表,采用创建散列表实现。(2)建散列表后,如果想要查找的数据在散列表中输出yes否则输出no。结构中存在关键字和K相等的记录,则必定存储在f(K)的位置上。由此,不需比较便可直接取得所查记录。这个对应关系f称为散列函数(Hashfunction),按这个思想建立的表为散列表。*对不同的关键字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),这种现象称冲突。具有相同函数值的关键字对该散列函数来说称做同义词。*综上所述,根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象”,作为这条记录在表中的存储位置,这种表便称为散列表,这一映象过程称为散列造表或散列,所得的存储位置称散列地址。这个现象也叫散列桶,在散列桶中,只能通过顺序的方式来查找,一般只需要查找三次就可以找到。科学家计算过,当负载因子(loadfactor)不超过75%,查找效率最高。*若对于关键字集合中的任一个关键字,经散列函数映象到地址集合中任何一个地址的概率是相等的,则称此类散列函数为均匀散列函数(UniformHashfunction),这就是使关键字经过散列函数得到一个“随机的地址”,从而减少冲突。程序设计流程程序思想哈希函数unsignedinthash_BK

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论