北科大数据结构上机实验报告.docx

上传人:b****6 文档编号:5617018 上传时间:2022-12-29 格式:DOCX 页数:52 大小:145.60KB
下载 相关 举报
北科大数据结构上机实验报告.docx_第1页
第1页 / 共52页
北科大数据结构上机实验报告.docx_第2页
第2页 / 共52页
北科大数据结构上机实验报告.docx_第3页
第3页 / 共52页
北科大数据结构上机实验报告.docx_第4页
第4页 / 共52页
北科大数据结构上机实验报告.docx_第5页
第5页 / 共52页
点击查看更多>>
下载资源
资源描述

北科大数据结构上机实验报告.docx

《北科大数据结构上机实验报告.docx》由会员分享,可在线阅读,更多相关《北科大数据结构上机实验报告.docx(52页珍藏版)》请在冰豆网上搜索。

北科大数据结构上机实验报告.docx

北科大数据结构上机实验报告

北京科技大学计算机与通信工程学院

实验报告

 

实验名称:

数据结构上机实验

学生姓名:

专业:

计算机科学与技术

班级:

学号:

指导教师:

实验成绩:

________________________________

实验地点:

实验时间:

2015年____6___月

一、实验目的与实验要求

1实验目的

(1)加深对常用数据结构和算法设计基本思路、思考方法及其适用场合的理解,并能运用于解决实际问题;

(2)能根据特定问题需求,分析建立计算模型(包括逻辑结构和物理结构)、设计算法和程序,并在设计中综合考虑多种因素,对结果的有效性进行分析;

(3)训练分析问题、解决问题的能力以及自主学习与程序设计实践能力;

(4)形成将非数值型问题抽象为计算模型到算法设计、程序实现、结果有效性分析的能力。

2实验要求

(1)由于在有限的实验课内学时难以较好完成所有实验内容,因此要求在实验课前自主完成部分实验或实验的部分内容;

(2)对于每个实验都要针对问题进行分析,设计出有效的数据结构、算法和程序,对实现结果的正确性进行测试,给出测试用例和结果,分析算法的时间复杂度、空间复杂度、有效性和不足,在算法设计和实现过程中体现创新意识,并能综合考虑时空权衡、用户的友好性、程序的模块化和扩展性等;

(3)完成的每个实验需要在实验课内经指导教师现场检查、查看程序代码,回答指导教师提出的问题,以确认实验实际完成的质量;

(4)在实验报告中体现问题分析、算法思路、算法描述、程序实现和验证、算法和结果的有效性分析。

二、实验设备(环境)及要求

Win7、C语言、Dev-C++

三、实验内容、步骤与结果分析

1实验1:

链表的应用

1.1实验内容

输入数据(设为整型)建立单链表,并求相邻两节点data值之和为最大的第一节点。

1.2主要步骤

1.2.1问题分析与算法思路

①采用单链表结构。

②新建链表:

每输入一个整数数据,建立一个新节点。

循环操作直到输入结束符结束输入。

③利用一个调用函数求两节点data值之和为最大的第一节点:

假设,设一个int类型的变量s=0,读取链表中第一个节点的数据以及它的第二个节点的数据,并计算它们之和a,再计算第二个节点数据和第三个节点数据之和b,如果a>b,则s=a;反之,则s=b。

利用if语句和while语句实现。

④每当输入一个数据,程序会判断输入的时候输入的数据是否是整数,如果不是整数,要求重新输入。

1.2.2算法描述

typedefintdatatype;//设当前数据元素为整型

typedefstructnode//节点类型

{

datatypedata;//节点的数据域

structnode*next;//节点的后继指针域

}Linknode,*Link;

LinkCreatelist()//创建单链表的算法

{

inta;

LinkH,P,r;//H,P,r分别为表头,新节点和表尾节点指针

H=(Link)malloc(sizeof(Linknode));//建立头节点

r=H;

scanf(“%d”,&a);//输入一个数据

while(a!

=0)

{

P=(Link)malloc(sizeof(Linknode));//申请新节点

P->data=a;//存入数据

r->next=P;//新节点链入表尾

r=P;

scanf(“%d”,&a);//输入下一个数据

}

r->next=NULL;//将尾节点的指针域置空

return(H);//返回已创建的头节点

}

LinkAdjmax(LinkH)//求链表中相邻两节点data值之和为最大的第一节点的指针的算法

{

Linkp,p1,q;

inti,j;

p=p1=H->next;

if(p1==NULL)return(p1);//表空返回

q=p->next;

if(q==NULL)return(p1);//表长=1时返回

i=p->data+q->data;//相邻两节点data值之和

while(q->next)

{

p=q;q=q->next;//取下一对相邻节点的指针

j=p->data+q->data;

if(j>i)

{

p1=p;i=j;//取和为最大的第一节点指针

}

}

return(p1);

}

1.2.3程序实现

#include

#include

typedefintdatatype;//设当前数据元素为整型

typedefstructnode//节点类型

{

datatypedata;//节点的数据域

structnode*next;//节点的后继指针域

}Linknode,*Link;//linknode为节点说明符,link为节点指针说明符

LinkCreatelist()//创建单链表的算法

{

inta,c;

floatb;

LinkH,P,r;//H,P,r分别为表头,新节点和表尾节点指针

H=(Link)malloc(sizeof(Linknode));//建立头节点

r=H;

do

{

c=(fflush(stdin),scanf("%f",&b));

//printf("%d",c);//判断输入的是否是整数

a=(int)b;

if(c!

=1||a!

=b||a<-32768||a>32767)printf("非法输入!

请重新输入!

\n");

}while(c!

=1||a!

=b||a<-32768||a>32767);

while(a!

=0)

{

P=(Link)malloc(sizeof(Linknode));//申请新节点

P->data=a;//存入数据

r->next=P;//新节点链入表尾

r=P;

do

{

c=(fflush(stdin),scanf("%f",&b));//判断输入的是否是整数

a=(int)b;

if(c!

=1||a!

=b||a<-32768||a>32767)printf("非法输入!

请重新输入!

\n");

}while(c!

=1||a!

=b||a<-32768||a>32767);

}

r->next=NULL;//将尾节点的指针域置空

return(H);//返回已创建的头节点

}

LinkAdjmax(LinkH)//求链表中相邻两节点data值之和为最大的第一节点的指针的算法

{

Linkp,p1,q;

inti,j;

p=p1=H->next;

if(p1==NULL)return(p1);//表空返回

q=p->next;

if(q==NULL)return(p1);//表长=1时返回

i=p->data+q->data;//相邻两节点data值之和

while(q->next)

{

p=q;q=q->next;//取下一对相邻节点的指针

j=p->data+q->data;

if(j>i)

{

p1=p;

i=j;//取和为最大的第一节点指针

}

}

return(p1);

}

voidmain()//主函数

{

LinkA,B,p,q;

inta,b;

do

{

printf("请输入一组整数(以0为结束符,数之间回车):

\n");

p=A=Createlist();//创建新链表

B=Adjmax(A);//求链表中相邻两节点data值之和为最大的第一节点的指针

a=(int)(B->data);//取第一节点的data值

printf("第一节点的data值为:

%d\n",a);

while(p->next)//释放链表空间

{

q=p;

p=p->next;

free(q);

}

free(p);

printf("是否继续输入下一组整数:

是:

1,否:

0\n");

scanf("%d",&b);

}while(b);

}

1.3结果分析

①输入的数组为:

26473,输出结果:

第一节点为4。

结果是正确的。

②输入的数组为:

4521456421454230,输出结果:

第一节点为21。

结果是正确的。

③输入的数组为:

457235647012241214524,输出结果:

第一节点为70。

结果是正确的。

 

1.3.1测试

如图所示,只要输入的数据不是整数(字符或小数),或者输入的整数不在[32768,32767]这个范围,程序会用"非法输入!

请重新输入!

"提示用户,直到用户输入正确的数据。

1.3.2算法和结果的有效性分析

时间复杂度:

O(n)

空间复杂度:

不复杂

有效性:

算法正确,算法易读、易编码和易于调试

不足:

每个数据输入之间只能用回车区分。

2实验2:

栈的应用

2.1实验内容

设操作数:

0,1,2,……,8,9(可扩充);运算符:

+,-,*,/,(,),#(#号为结束)。

输入中缀表达式,将其转换成后缀表达式,然后计算,输出结果。

例如:

输入中缀表达式5+(4-2)*3#,将其转换成后缀表达式:

542-3*+#,然后计算,本例结果为11。

2.2主要步骤

2.2.1问题分析与算法思路

①利用栈来写程序。

②首先要获得中缀表达式,再利用一个调用函数是中缀表达式变为后缀表达式。

再用一个函数求后缀表达式的值。

③利用一个调用函数取判断中缀表达式的合法性。

2.2.2算法描述

typedefstructnode

{

chardata;

structnode*next;

}snode,*slink;

typedefstructnode1

{

intdata;

structnode1*next;

}snode1,*slink1;

voidClearstack(slinks)//置栈空

{

s=NULL;

}

intEmptystack(slinks)//判断栈是否为空

{

if(s==NULL)return

(1);//栈空返回1

elsereturn(0);//栈非空返回0

}

charGetstop(slinks)//取栈顶元素

{

if(s!

=NULL)return(s->data);

return(0);

}

voidPush(slink*s,charx)//元素x进栈

{

slinkp;

p=(slink)malloc(sizeof(snode));//生成进栈p节点

p->data=x;//存入新元素

p->next=*s;//p节点作为新的栈顶链入

*s=p;

}

charPop(slink*s)//出栈

{

charx;

slinkp;

if(Emptystack(*s))return(-1);//栈空,返回-1

else

{

x=(*s)->data;

p=*s;

*s=(*s)->next;

free(p);

return(x);//成功

}

}

intPrecede(charx,chary)//比较x是否"大于"y

{

inta,b;

switch(x)

{

case'#':

case'(':

a=0;break;

case'+':

case'-':

a=1;break;

case'*':

case'/':

a=2;break;

}

switch(y)

{

case'+':

case'-':

b=1;break;

case'*':

case'/':

b=2;break;

case'(':

b=3;break;

}

if(a>=b)return

(1);

elsereturn(0);

}

voidMid_post(charE[],charB[])//中缀表达式B到后缀表达式E的转换

{

inti=0,j=0;

charx;inta;

slinks=NULL;//置空栈

Clearstack(s);

Push(&s,'#');//结束符入栈

do

{

x=B[i++];//扫描当前表达式分量x

switch(x)

{

case'':

break;

case'#':

{

while(!

Emptystack(s))

{

E[j++]='';//栈非空时

E[j++]=Pop(&s);

}

}break;

case')':

{

while(Getstop(s)!

='(')

{

E[j++]='';

E[j++]=Pop(&s);

}//反复出栈直到遇到'('

Pop(&s);//退掉'('

}break;

case'+':

case'-':

case'*':

case'/':

case'(':

{

while(Precede(Getstop(s),x))//栈顶运算符(Q1)与x比较

{

E[j++]='';

E[j++]=Pop(&s);//Q1>=x时,输出栈顶符兵退栈

}

//E[j++]='';

Push(&s,x);//Q1

E[j++]='';

}break;

default:

E[j++]=x;//操作数直接输出

}

}while(x!

='#');

E[j]='\0';

Clearstack(s);

}

intEcount(charE[])//后缀表达式求值

{

inti=0,g=0,k=0,d=0,d1,g1;

charx;

intz,a,b;

slink1s=NULL;//置栈空

while(E[i]!

='#')//扫描每一个字符是送x

{

x=E[i];

switch(x)

{

case'':

break;

case'+':

b=Pop1(&s);a=Pop1(&s);z=a+b;Push1(&s,z);break;

case'-':

b=Pop1(&s);a=Pop1(&s);z=a-b;Push1(&s,z);break;

case'*':

b=Pop1(&s);a=Pop1(&s);z=a*b;Push1(&s,z);break;

case'/':

b=Pop1(&s);a=Pop1(&s);z=a/b;Push1(&s,z);break;//执行相应运算结果进栈

default:

{

g=0;g1=0;//获取操作数

while(E[i]!

='')

{

g1=E[i]-'0';

g=g*10+g1;

i++;

}

Push1(&s,g);//操作数进栈

}

}

i++;

}

if(!

Emptystack1(s))return(Getstop1(s));//返回结果

Clearstack1(s);

}

2.2.3程序实现

#include

#include

#include

typedefstructnode

{

chardata;

structnode*next;

}snode,*slink;

typedefstructnode1

{

intdata;

structnode1*next;

}snode1,*slink1;

voidClearstack(slinks)//置栈空

{

s=NULL;

}

intEmptystack(slinks)//判断栈是否为空

{

if(s==NULL)return

(1);//栈空返回1

elsereturn(0);//栈非空返回0

}

charGetstop(slinks)//取栈顶元素

{

if(s!

=NULL)return(s->data);

return(0);

}

voidPush(slink*s,charx)//元素x进栈

{

slinkp;

p=(slink)malloc(sizeof(snode));//生成进栈p节点

p->data=x;//存入新元素

p->next=*s;//p节点作为新的栈顶链入

*s=p;

}

charPop(slink*s)//出栈

{

charx;

slinkp;

if(Emptystack(*s))return(-1);//栈空,返回-1

else

{

x=(*s)->data;

p=*s;

*s=(*s)->next;

free(p);

return(x);//成功

}

}

voidPush1(slink1*s,intx)//元素x进栈

{

slink1p;

p=(slink1)malloc(sizeof(snode1));//生成进栈p节点

p->data=x;//存入新元素

p->next=*s;//p节点作为新的栈顶链入

*s=p;

}

intPop1(slink1*s)//出栈

{

intx;

slink1p;

if(Emptystack1(*s))return(-1);//栈空,返回-1

else

{

x=(*s)->data;

p=*s;

*s=(*s)->next;

free(p);

return(x);//成功

}

}

intEmptystack1(slink1s)//判断栈是否为空

{

if(s==NULL)return

(1);//栈空返回1

elsereturn(0);//栈非空返回0

}

voidClearstack1(slink1s)//置栈空

{

s=NULL;

}

intGetstop1(slink1s)//取栈顶元素

{

if(s!

=NULL)return(s->data);

return(0);

}

intPrecede(charx,chary)//比较x是否"大于"y

{

inta,b;

switch(x)

{

case'#':

case'(':

a=0;break;

case'+':

case'-':

a=1;break;

case'*':

case'/':

a=2;break;

}

switch(y)

{

case'+':

case'-':

b=1;break;

case'*':

case'/':

b=2;break;

case'(':

b=3;break;

}

if(a>=b)return

(1);

elsereturn(0);

}

voidMid_post(charE[],charB[])//中缀表达式B到后缀表达式E的转换

{

inti=0,j=0;

charx;inta;

slinks=NULL;//置空栈

Clearstack(s);

Push(&s,'#');//结束符入栈

do

{

x=B[i++];//扫描当前表达式分量x

switch(x)

{

case'':

break;

case'#':

{

while(!

Emptystack(s))

{

E[j++]='';//栈非空时

E[j++]=Pop(&s);

}

}break;

case')':

{

while(Getstop(s)!

='(')

{

E[j++]='';

E[j++]=Pop(&s);

}//反复出栈直到遇到'('

Pop(&s);//退掉'('

}break;

case'+':

case'-':

case'*':

case'/':

case'(':

{

while(Precede(Getstop(s),x))//栈顶运算符(Q1)与x比较

{

E[j++]='';

E[j++]=Pop(&s);//Q1>=x时,输出栈顶符兵退栈

}

Push(&s,x);//Q1

E[j++]='';

}break;

default:

E[j++]=x;//操作数直接输出

}

}while(x!

='#');

E[j]='\0';

Clearstack(s);

}

intEcount(charE[])//后缀表达式求值

{

inti=0,g=0,k=0,d=0,d1,g1;

charx;

intz,a,b;

slink1s=NULL;//置栈空

while(E[i]!

='#')//扫描每一个字符是送x

{

x=E[i];

switch(x)

{

case'':

break;

case'+':

b=Pop1(&s);a=Pop1(&s);z=a+b;Push1(&s,z);break;

case'-':

b=Pop1(&s);a=Pop1(&s);z=a-b;Push1(&s,z);break;

case'*':

b=Pop1(&s);a=Pop1(&s);z=a*b;Push1(&s,z);break;

case'/':

b=Pop1(&s);a=Pop1(&s

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1