数据结构实验实验一.docx
- 文档编号:4014862
- 上传时间:2022-11-27
- 格式:DOCX
- 页数:20
- 大小:272.18KB
数据结构实验实验一.docx
《数据结构实验实验一.docx》由会员分享,可在线阅读,更多相关《数据结构实验实验一.docx(20页珍藏版)》请在冰豆网上搜索。
数据结构实验实验一
《数据结构》
实验报告
题目:
实验一——线性表,栈,队列
班级:
计093组号:
姓名:
蔡乐学号:
10093621
姓名:
李成学号:
100936**
姓名:
陈逢隽学号:
100936**
姓名:
陆海炼学号:
100936**
姓名:
王悦学号:
100936**
姓名:
学号:
姓名:
学号:
姓名:
学号:
姓名:
学号:
姓名:
学号:
华东理工大学
信息学院计算机系
2011年5月
实验一——线性表,栈,队列
一、设计实现一个一元稀疏多项式计算器
1、需求分析
一元稀疏多项式简单计算器的基本功能是:
(1)输入并建立多项式:
先输入项数n,再依次输入各项的系数
和指数;
(2)输出多项式,输出形式为浮点数序列:
n,c1,e1,c2,e2,……cn,en,其中n是多项式的项数,ci,ei,分别是第i项的系数和指数,序列按指数降序排序(这里将数据扩大到浮点数类型了,比原实验要求的范围(整数)有所扩大,由于用了%g格式自动匹配来读入及输出,则原来的项数n和其它整数系数、指数仍保持为整数。
)如果是空多项式(即0),则输出0;
(3)运算:
多项式相加、相减,计算多项式在x处的值。
(4)测试数据:
在
时,
=19.8767
0
2、系统设计
(1)抽象数据类型的定义
#defineERROR-1//错误信息
#defineOK1//正确状态
typedefintStatus;
//Status用来返回函数状态信息
typedeffloatCoefficient;
//定义系数为浮点型
typedeffloatExponent;
//定义指数为浮点型
typedefstructnode{
Coefficientc;
Exponente;
structnode*next;
}EntryNode,*Polynomial;
//定义项结点及多项式头指针
(2)各函数模块的申明
StatusCreatePoly(Polynomial*Poly);
//创建多项式,形参为多项式头指针的地址,返回值为Status类型
StatusDestoryPoly(Polynomial*Poly);
//多项式存在,则销毁多项式,形参为多项式头指针的地址,返回值为Status
类型
StatusPrintPoly(PolynomialPoly);
//多项式存在,则打印多项式,形参为多项式头指针,返回值为Status类型
StatusPolyAdd(Polynomial*Poly1,PolynomialPoly2);
//两多项式均存在,则相加,结果储存为前面那个多项式Poly1,形参为前一个多项式头指针地址和后一个多项式头指针,返回值为Status类型
StatusPolySub(Polynomial*Poly1,PolynomialPoly2);
//两多项式均存在,则相减,结果储存为前面那个多项式Poly1,形参为前一个多项式头指针地址和后一个多项式头指针,返回值为Status类型
floatPolyVal(PolynomialPoly,floatx);
//多项式存在,则求其在变量取值为x时的值,形参为多项式头指针和x值,
返回值为float类型
voidMenuShow();
//功能菜单,功客户选择当前操作,无形参,无返回值
(3)主程序(main函数)执行流程
3、调试分析
(1)调试中主要出现的问题在free()函数上,由于DestoryPoly函数要调用它,而DestoryPoly的形参是*Poly,则不能直接写语句free(Poly);而要写成free(*Poly)的形式,因为实际申请的动态空间是Poly指向的内容;
(2)整个算法的时间复杂度为
,其中
、
为多项式项数,MenuShow的时间复杂度为
,CreatePoly、PolyVal、DestoryPoly的时间复杂度均为
,PrintPoly的时间复杂度为
,PolyAdd、PolySub的时间复杂度均为
;改进设想是在CreatePoly内部就对多项式按指数递减顺序排序,这样DestoryPoly、PrintPoly、PolyAdd、PolySub、PolyVal这些依赖于CreatePoly的算法复杂度将降低;
(3)指针如果申请了动态空间,要注意传指针的引用与传指针的值时释放的方法有区别。
4、测试结果
详细的测试结果见附录2
5、用户手册
1、找到“多项式求值.exe”文件,双击
2、根据界面提示输入测试数据
6、附录
附录一:
源程序清单
多项式求值.c
#defineERROR-1//错误信息
#defineOK0//正确状态
typedefintStatus;
//Status用来返回函数状态信息
typedeffloatCoefficient;
//定义系数为浮点型
typedeffloatExponent;
//定义指数为浮点型
typedefstructnode{
Coefficientc;
Exponente;
structnode*next;
}EntryNode,*Polynomial;
//定义项结点及多项式头指针
StatusCreatePoly(Polynomial*Poly)
{//建立多项式
EntryNode*p,*q;inti;
if(!
p)
exit(OVERFLOW);
printf("请输入多项式的项数:
");
scanf("%g",&((*Poly)->e));
if((*Poly)->e<=0)
exit(ERROR);
for(i=0;i<(*Poly)->e;i++){
q=(EntryNode*)malloc(sizeof(EntryNode));
if(!
q)exit(OVERFLOW);
printf("请输入第%d项的系数和指数:
",i+1);
scanf("%g%g",&(q->c),&(q->e));
p->next=q;
p=p->next;
}
p->next=NULL;
returnOK;
}
StatusDestoryPoly(Polynomial*Poly)
{//销毁多项式
EntryNode*p;
if(!
(*Poly))
returnOK;
while(*Poly){//释放第一项,对子式递归
p=(*Poly)->next;free(*Poly);*Poly=p;
DestoryPoly(Poly);
}
}
StatusPrintPoly(PolynomialPoly)
{//按指数递减排序并打印多项式
EntryNode*p,*q;floatr;inti,j;
if(!
Poly)
exit(ERROR);
printf("有%g项",Poly->e);
p=Poly->next;
for(i=1;i
q=p->next;
for(j=i;j
if(p->e
r=p->c;p->c=q->c;q->c=r;
r=p->e;p->e=q->e;q->e=r;
}
q=q->next;
}
printf("<%g,%g>",p->c,p->e);
p=p->next;
}
printf("<%g,%g>\n",p->c,p->e);
returnOK;
}
StatusPolyAdd(Polynomial*Poly1,PolynomialPoly2)
{//多项式相加,结果储存在第一个多项式中
EntryNode*p,*q,*r;
inti,j,k;
if(!
(*Poly1)||!
Poly2)
exit(ERROR);
for(p=Poly2->next,i=0;i
k=(*Poly1)->e;
for(q=*Poly1,j=0;j r=q->next; if(r->e==p->e){//指数相同 if((r->c+p->c)==0){ q->next=r->next;free(r); ((*Poly1)->e)--; break; }//系数互为相反数则释放该项 r->c+=p->c;//否则进行项归并 break; } q=q->next; } if(j==k){ r=(EntryNode*)malloc(sizeof(EntryNode)); if(! r)exit(OVERFLOW); r->c=p->c;r->e=p->e; q->next=r;q=q->next;q->next=NULL; ((*Poly1)->e)++; } p=p->next; } if((*Poly1)->e==0)*Poly1=NULL; returnOK; } StatusPolySub(Polynomial*Poly1,PolynomialPoly2) {//多项式相减 EntryNode*p,*q,*r; inti,j,k; if(! (*Poly1)||! Poly2) exit(ERROR); for(p=Poly2->next,i=0;i k=(*Poly1)->e; for(q=*Poly1,j=0;j r=q->next; if(r->e==p->e){//指数相同 if(r->c==p->c){ q->next=r->next;free(r); ((*Poly1)->e)--; break; }//系数相同则释放该项 r->c-=p->c;//否则进行项归并 break; }q=q->next; } if(j==k){ r=(EntryNode*)malloc (sizeof(EntryNode)); if(! r)exit(OVERFLOW); r->c=0-p->c;r->e=p->e;q->next=r; q=q->next;q->next=NULL;((*Poly1)->e)++; }p=p->next; } if((*Poly1)->e==0) *Poly1=NULL; returnOK; } floatPolyVal(PolynomialPoly,floatx) {//求多项式在x下的值 floatVal=0.0;EntryNode*p;inti; for(i=0,p=Poly->next;i Val+=(p->c)*pow(x,p->e);p=p->next; } returnVal; } voidMenuShow(){//功能菜单 printf("********************************\n"); printf("一元稀疏多项式简单计算\n"); printf("1.建立多项式\n"); printf("2.输出多项式\n"); printf("3.多项式相加\n"); printf("4.多项式相减\n"); printf("5.多项式求值\n"); printf("6.退出\n"); printf("**************************\n\n"); } intmain(){ PolynomialPoly[10]; intchoice,i,j,n=0; floatx; for(i=0;i<10;i++) Poly[i]=NULL; MenuShow(); printf("请选择正确的操作(1、2、3、4、5、6): "); scanf("%d",&choice); while (1){ switch(choice){ case1: CreatePoly(&Poly[n++]);break; case2: printf("请选择要打印的多项式(1到%d号): ",n);scanf("%d",&i); printf("该多项式(第%d个)为: ",i);PrintPoly(Poly[i-1]);break; case3: printf("请选择参与相加的两个多项式(1到%d号): ",n);scanf("%d%d",&i,&j); PolyAdd(&Poly[i-1],Poly[j-1]); if(! Poly[i-1]) printf("相加结果(存储为第%d个多项式)为: 0\n",i); else{ printf("相加结果(存储为第%d个多项式)为: ",i); PrintPoly(Poly[i-1]); }break; case4: printf("请选择参与相减的两个多项式 (1到%d号): ",n);scanf("%d%d",&i,&j); PolySub(&Poly[i-1],Poly[j-1]); if(! Poly[i-1]) printf("相减结果(存储为第%d个)的值 为: %g\n",i,PolyVal(Poly[i-1],x)); break; case6: for(i=0;i DestoryPoly(&Poly[i]); exit(0); } printf("\n请选择正确的操作(1、2、3、4、5、6): "); scanf("%d",&choice); } return0; } 附录附录二: 测试结果截图 二、算术表达式求值 1、需求分析 算术表达式求值程序的基本功能是: (1)以字符序列的形式从终端输入语法正确的、不含变量的整数表达式。 (2)演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。 (3)最终运算数栈存储的算术表达式的值弹出给形参以供输出。 (4)测试数据: /3 0 (这是数据(128)溢出的情况,该表达式的实际值应为4) 2、系统设计 (1)抽象数据类型的定义 #defineOK0//正确状态 #defineERROR-1//错误信息 #defineOVERFLOW-2//溢出错误 #defineTrue1//是 #defineFalse0//否 typedefintStatus;//Status用于 返回函数状态信息 typedefcharElemType;//元素类型 typedefstructnode{ ElemTypech; structnode*next; }ChNode,*Stack;//定义字符 结点和栈头指针 (2)各函数模块的申明 StatusInitStack(Stack*S); //初始化栈,形参为栈的头指针的地址,返回值为Status类型 StatusStackEmpty(StackS); //判断栈是否为空,形参为栈的头指针,栈空则返回True,非空则返回False StatusPush(Stack*S,ElemTypee); //压栈操作,形参为栈的头指针的地址和压栈元素e,返回值为Status类型 StatusPop(Stack*S,ElemType*e); //出栈操作,形参为栈的头指针的地址和e的地址,返回值为Status类型 StatusDestoryStack(Stack*S); //销毁栈,形参为栈的头指针的地址,返回值为Status类型 StatusEvaluateExpression(ElemType*a); //计算表达式的值,形参a的地址,返回值为Status类型 (3)执行流程 主程序(main函数)流程 EvaluateExpression函数流程 3、调试分析 (1)调试中主要问题在于相邻两运算符情况较多,而且二者的优先级又有三种情况,所以经常会因逻辑表述不严密而造成错误,好在对三种优先级的判断比较简明,而且有些过程在一定的优先级前提下会重复出现,于是想到用goto语句来取代while循环以使程序流向更以控制从而减少逻辑描述量并使代码简洁明了; (2)整个算法的时间复杂度为 其中 为表达式字符串的长度。 InitStack、StackEmpty、Push、Pop的时间复杂度为 ,DestoryStack的时间复杂度为 EvaluateExpression的时间复杂度为 。 改进设想是对相邻两个操作符的优先级关系进行进一步的优化分析,避免使用goto语句; (3)写代码之前要对问题的逻辑层次与逻辑关系进行充分的分析,而且先画出算法的流程图,从流程图可以直观地看出程序的循环或其他重复过程以及各种操作,然后根据流程图写代码将会准确快捷而且代码也会较简洁易读。 4、测试结果 详细的测试结果见附录2 5、用户手册 1、找到“表达式求值.exe”,双击; 2、进入Dos操作界面,输入一个春整数算术表达式,按enter键 3、按任意键退出 6、附录 附录一: 源程序清单 表达式求值.c #include #include #defineOK0//正确状态 #defineERROR-1//错误信息 #defineOVERFLOW-2//溢出错误 #defineTrue1 #defineFalse0 typedefintStatus;//Status用于 返回函数状态信息 typedefcharElemType;//元素类型 typedefstructnode{ ElemTypech; structnode*next; }ChNode,*Stack;//定义字符 结点和栈头指针 StatusInitStack(Stack*S) {//初始化栈 *S=(ChNode*)malloc(sizeof(ChNode)); if(! (*S))exit(OVERFLOW); (*S)->next=NULL; returnOK; } StatusStackEmpty(StackS) {//判断栈是否为空 if(! S)exit(ERROR); if(S->next)returnFalse; elsereturnTrue; } StatusPush(Stack*S,ElemTypee){//元素e入栈 ChNode*p; if(! (*S))exit(ERROR); p=(ChNode*)malloc(sizeof(ChNode)); if(! p)exit(OVERFLOW); (*S)->ch=e;p->next=(*S);(*S)=p; returnOK; } StatusPop(Stack*S,ElemType*e){//栈顶元素弹出到e ChNode*p; if(! (*S)||StackEmpty(*S))exit(ERROR); p=(*S)->next;*e=p->ch;(*S)->next=p->next;free(p); returnOK; } StatusDestoryStack(Stack*S){//销毁栈 ChNode*p; if(! (*S))returnOK; while(*S){ p=*S;*S=p->next;free(p);DestoryStack(S); } } StatusEvaluateExpression(ElemType*a) {//多项式求值 StackOperator,Operand; ElemTypee,b; charc; Operator=Operand=NULL; InitStack(&Operator); InitStack(&Operand); loop1: c=getchar(); loop2: if(c! ='\n'){ if(c>='0'&&c<='9'){ *a=0; while(c>='0'&&c<='9'){ *a=10*(*a)+c-'0';c=getchar();//将连续的数字串转化成对应的整数, }//直到获取的字符为运算符或‘\n’ Push(&Operand,*a);//操作数入栈Operand gotoloop2; } loop3: if(StackEmpty(Operator)){//栈空,则运算符入栈Operator Push(&Operator,c);gotoloop1; } else{ Pop(&Operator,&e); if(e=='('||c=='('||((e=='+'||e=='-')&&(c=='*'||c=='/'))){//c优先级不低于e if(e=='('&&c==')')gotoloop1;//c优先级等于ePush(&Operator,e);Push(&Operator,c);gotoloop1;//c优先级高于e } else{//c优先级低于e Pop(&Operand,a);Pop(&Operand,&b);//Operand最顶两元素出栈运算 switch(e){ case'+': *a=b+(*a);break; case'-': *a=b-(*a);break; case'*': *a=b*(*a);break; case'/': *a=b/(*a);break; } Push(&Operand,*a);//运算结果入栈Operand gotoloop3; } } }//所有运算符都做过是否该入栈的处理了
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构实验 实验一 数据结构 实验