数据结构实验报告.docx
《数据结构实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告.docx(36页珍藏版)》请在冰豆网上搜索。
数据结构实验报告
福建农林大学计算机与信息学院
(程序设计类课程)
实验报告
课程名称:
数据结构
姓名:
系:
计算机与信息
专业:
电子信息工程
年级:
学号:
指导教师:
职称:
实验项目列表
序号
实验项目名称
成绩
指导教师
1
线性表及其应用(多项式相加、相乘)
黄思先
2
哈夫曼树及哈夫曼编码译码的实现(验证性)
黄思先
3
(快速、堆、基数)排序算法的设计(综合性)
黄思先
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
福建农林大学计算机与信息学院实验报告
系:
计算机与信息专业:
电子信息工程年级:
姓名:
学号:
实验室号:
田家炳后座514计算机号:
实验时间:
322指导教师签字:
成绩:
实验一线性表及其应用(多项式相加、相乘)
一、实验目的和要求
1、熟悉tc的运行环境,并可以熟练的使用tc;
2、掌握链表存储的方法以及基本操作;
3、掌握内存的动态分配和释放方法;
4、熟悉C语言程序的基本格式与规范。
二、实验内容和原理
1、实验内容:
设计一个一元多项式的简单计算程序,其基本功能有:
(1)输入并建立多项式;
(2)输出多项式;(3)多项式的相加;(4)多项式的相乘。
利用单链表实现。
2、实验原理:
将两多项式存入链表lianbiao1、lianbiao2,用pointer1扫描lianbiao1,pointer2扫描lianbiao2,结果保存在lianbiao3中(用pointer3来创建lianbiao3)
三、实验环境
硬件:
(1)学生用微机
(2)多媒体实验教室
(3)局域网环境
软件:
(1)WindowsXP中文操作系统
(2)VC6.0
四、算法描述及实验步骤
1、描述
1.定义创建链表的函数,然后创建三个链表,其中一个用于存放结果。
2.定义多项式相加的函数实现多项式的相加功能,定义多项式的相乘功能。
3.定义打印链表和释放链表的函数。
4.最后在主函数里面调用这些函数,实现多项式的相加和相乘。
2、框图
创建链表多项式相加
多项式相乘(一乘多)多项式相乘(多乘多)
以上Pn,lianbiao,pointer,hemp分别对应程序里的PN,l,p,h;
lianbiao1,lianbiao2,lianbiao3则分别对应la,lb,lc。
3、代码(注释)
#include"stdio.h"
typedefstructnode/*定义结点,包含两个数据域(c和e)*/
{intc,e;/*c是多项式的系数,e是项的指数*/
structnode*next;/*定义next为指向下一个结点的指针*/
}PN;/*定义PN类型*/
PN*createPoly()/*创建多项式链表*/
{PN*head,*p;
intn;
scanf("%d",&n);/*接收用户输入的多项式的项数*/
head=p=newPN;
while(n--)/*对n进行判断,当n--不为0时执行while循环语句*/
{p->next=newPN;
p=p->next;/*将p下移,指向下一个元素*/
scanf("%d%d",&p->c,&p->e);/*接收用户输入的多项式各项系数和指数*/
}
p->next=NULL;/*链表最后一个结点的next域指向空*/
returnhead;
}
voidprintPoly(PN*head)/*输出链表*/
{PN*p=head->next;/*指针由头结点指向下一个结点,以此递传*/
while(p)/*打印出当前的结点系数c和指数e,直到链表为空*/
{printf("(%d,%d)",p->c,p->e);
p=p->next;/*打印出当前结点后,将指针移到下一个结点*/
}
printf("\n");
}
voidfreePoly(PN*head)/*释放链表空间*/
{PN*p=head;/*将p指向头结点*/
while(p)/*释放链表中的结点直到p链表为空时退出循环*/
{head=head->next;
delete(p);/*删除当前结点*/
p=head;/*当p指向头结点指针时结束循环*/
}
}
PN*addPoly(PN*la,PN*lb)/*两个多项式相加*/
{PN*lc,*p1=la->next,*p2=lb->next,*p3;/*创建新的链表lc用于存放la和lb相加后的结果*/
intc,e;/*这里的c为两个多项式对应各项相加后的系数,e为结点相加后的指数*/
lc=p3=newPN;/*向多项式lc里存入数据*/
while(p1||p2)/*当p1与p2只要有一个非空执行以下语句*/
{if(p1&&(p2==NULL||p1->ee))/*若p1非空且p2为空或p1所指的指数e小于p2所指的指数e时*/
{c=p1->c;/*将p1当前所指结点的系数c赋值给c*/
e=p1->e;/*将p1当前所指结点的指数e赋值给e*/
p1=p1->next;/*将p1下移至下一结点*/
}
elseif(p2&&(p1==NULL||p1->e>p2->e))/*若p2非空且p1为空或p2所指的指数小于p1所指的指数e时*/
{c=p2->c;
e=p2->e;
p2=p2->next;
}else/*以上两种情况不满足时,执行以下语句*/
{c=p1->c+p2->c;/*将pa与pb所指的系数相加后赋值给c*/
e=p1->e;
p1=p1->next;/*将p1下移*/
p2=p2->next;/*将p2下移*/
}
if(c)/*若c不为空*/
{p3->next=newPN;/*申请新结点的空间*/
p3=p3->next;/*p3下移*/
p3->c=c;/*把系数c放入新结点*/
p3->e=e;/*把指数e放入新结点*/
}
}
p3->next=NULL;/*当指针所指的为NULL时,链表结束*/
returnlc;/*返回两个多项式相加的结果lc*/
}
PN*oneXmulti(PN*la,PN*lb)/*两个多项式相乘*/
{PN*lc,*p3,*p2=lb->next;/*定义链表lc*/
p3=lc=newPN;/*为lc申请空间,并将p3指向lc*/
while(p2)
{p3->next=newPN;/*为新创结点申请空间*/
p3=p3->next;/*将p3指向新结点*/
p3->c=p1>c*p2->c;/*将p1的系数乘以p2的系数再赋值给c*/
p3->e=p1->e+p2->e;/*将p1的指数乘以p2的指数再赋值给e*/
p2=p2->next;/*p2下移*/
}
p3->next=NULL;
returnlc;/*将结果lc返回*/
}
PN*multiXmulti(PN*la,PN*lb)/*两个多项式相乘*/
{PN*lc,*h,*p1=la->next;
lc=newPN;
lc->next=NULL;
while(p1)
{h=oneXmulti(p1,lb);/*将相乘结果放到链表h*/
lc=addPoly(lc,h);/*将h中的多项式加上lc中的多项式*/
freePoly(h);/*释放链表h*/
p1=p1->next;
}
returnlc;
}
intmain()
{PN*la,*lb,*lc;/*定义三个链表la,lb,lc*/
freopen("poly.in","r",stdin);
freopen("poly.out","w",stdout);
la=createPoly();/*创建链表la*/
printPoly(la);/*输出链表la*/
lb=createPoly();
printPoly(lb);
lc=addPoly(la,lb);/*将la与lb相加的结果赋值给lc*/
printPoly(lc);
freePoly(lc);/*释放出lc*/
lc=multiXmulti(la,lb);/*将la与lb相乘的结果赋值给lc*/
printPoly(lc);/*输出链表lc*/
freePoly(la);/*释放la*/
freePoly(lb);
freePoly(lc);
return0;
}
五、调试过程
调试过程出现多处字母错误、分号漏写或为全角、若干变量未定义等问题,在老师和同学的帮助下,通过调试。
六、实验结果
测试数据
(1):
取两项多项式为:
(2,5),(4,1)
取一项多项式为:
(-1,5)
实验结果
(1):
这两个项式相加结果为:
la+lb:
(1,5)(4,1)
这两个项式相乘结果为:
la*lb:
(-4,6)(-2,10)
实验截图
(1):
测试数据
(2):
取三项多项式为:
(1,1)(3,4)(-9,8)
取四项多项式为:
(2,-3)(7,1)(-3,0)(8,5)
实验结果
(2):
这两个项式相加:
la+lb:
(2,-3)(8,1)(-3,0)(3,4)(8,5)(-9,8)
这两个项式相乘:
la*lb:
(2,-2)(6,1)(7,2)(-3,1)(3,5)(-9,4)(8,6)(-39,9)(27,8)(-72,13)
实验截图
(2):
七、总结
通过这次实验我更熟悉了vc的运行环境,并可以熟练的使用vc,掌握链表存储的方法以及基本操作、内存的动态分配和释放方法并且熟悉C语言程序的基本格式与规范,从中我学会了更细心地审查程序并依靠vc软件查找出错处,不足之处是我尚未能够熟练学会程序调试,今后我将在这一点上更加努力。
附录:
[1]宁正元、王秀娟《算法与数据结构》,北京:
清华大学出版社,2006;
[2]严蔚敏、佩娟等《数据结构》,北京:
国防工业出版社,1981;
[3]宁正元《数据结构》-用C语言描述,北京:
中国水利水电出版社,2000
[4]中国计算机科学与技术学科教程2002研究组《中国计算机科学与技术学科教程2002》,北京:
清华大学出版社,2002;
[5]陈小平《数据结构》,南京:
南京大学出版社,1994。
福建农林大学计算机与信息学院实验报告
系:
计算机与信息专业:
电子信息工程年级:
姓名:
学号:
实验室号:
田家炳后座514计算机号:
实验时间:
322指导教师签字:
成绩:
实验二哈夫曼树及哈夫曼编码译码的实现
一、实验目的和要求
1、进一步了解数据结构的实现策略。
2、掌握动态结构的静态实现法。
3、了解大批量数据的组织策略。
4、掌握数据结构在问题建模中的应用。
二、实验内容和原理
实验内容:
利用huffman编码吧一段字符转化为huffman编码,后者吧一段huffman编码转化为字符串。
实验原理:
哈夫曼树是由n个带权叶子结点构成的所有二叉树中带权路径长度WPL最小的二叉树。
本实验中,要输入电文字符以及它的权值,用Hunffman算法构建哈夫曼树。
定义一个存储哈夫曼编码结果的二维数组。
为使每一个字符编码都不是另一个字符编码的前缀,规定哈夫曼树中左分枝以“0”编码,右分枝以“1”编码。
三、实验环境
硬件:
(1)学生用微机
(2)多媒体实验教室
软件:
(1)WindowsXP中文操作系统
(2)TurboC3.0
四、算法描述及实验步骤
算法描述
哈夫曼编码的形成:
字符集合D={a,b,c,d},字符的概率分布(字符出现的次数)为W={3,4,2,10},由此够着哈夫曼树如下图所示。
有哈夫曼树可得哈夫曼编码为a:
011b:
00c:
010d:
1
01
01d
b
01
ca
建哈夫曼树:
ht[0][1][2][3][4][5][6][7]
3
4
2
10
5
9
19
3
2
6
1
5
4
5
6
5
7
6
7
w
lch
rch
parent
3,4,2,10为叶子权值。
编哈夫曼编码:
a
b
c
d
3
2
3
1
0
1
1
0
0
0
1
0
1
ch
code
starstarstarstar
代码注释
#include
#defineN010
#defineInf1000000//定义无穷大
#defineTXT100
#defineHMNUM1000
typedefstruct
{
intw,lch,rch,parent;//权重w,左孩子lch,右孩子rch,双亲parent
}htcode;//哈夫曼树结点的数据类型
typedefstruct
{
chardata;
intcode[N0+1];
intstart;
}hccode;//字符的哈夫曼编码信息的数据类型
htcodeht[2*N0];
hccodehc[N0+1];
charhmcode[HMNUM];
intfr[256];//ASCLL码
intn,root;//定义叶子和根
voidreadData()//读入数据
{charch;
freopen("huffman.in","r",stdin);//读取文件名为huffman.in的信息
while((ch=getchar())!
=EOF)//EOF文件结束标志
fr[ch]++;
for(inti=0;i<=255;i++)
if(fr[i])
{n++;
hc[n].data=i;
ht[n].w=fr[i];
}
root=2*n-1;
}
voidselect1(intt,int*s1,int*s2)//选出从1到t中权值的最小与次最小结点
{
intw1=Inf,w2=Inf;
for(inti=1;i<=t;i++)
if(ht[i].parent==0)//先找出前面2个无双亲(即未合并的)结点的位置
if(ht[i].w{w2=w1;//记住次最小项
*s2=*s1;
w1=ht[i].w;//记住新的最小项
*s1=i;//令s1指向权值次最小的结点
}
elseif(ht[i].w{w2=ht[i].w;
*s2=i;//令s2指向权值最小的结点
}
}
voidcreatHtreeHcode()//建立哈夫曼树函数
{
inti,parent,child;
ints1,s2;
for(i=n+1;i<=root;i++)
{select1(i-1,&s1,&s2);//调用select()函数
ht[i].w=ht[s1].w+ht[s2].w;
ht[s1].parent=ht[s2].parent=i;
ht[i].lch=s1;//ht[i]左孩子指向最小的数
ht[i].rch=s2;//ht[i]右孩子指向次小的数
}
for(i=1;i<=n;i++)//生成哈夫曼编码的函数
{child=i;//从叶子开始
while(child!
=root)//当结点不为根时进行如下操作
{parent=ht[child].parent;
if(child==ht[parent].lch)
hc[i].code[hc[i].start++]=0;//左分枝编码为0,同时校正指针的位置
else
hc[i].code[hc[i].start++]=1;//右分枝编码为1,同时校正指针的位置
child=parent;
}
}
}
voidshowTree(introot,inttab)//哈夫曼树的显示
{
inti;
if(root)//从根开始,如果根结点不为空
{for(i=1;i<=tab;i++)
printf("");//输出空格
printf("%d\n",ht[root].w);
showTree(ht[root].lch,tab+3);//沿左链下降
showTree(ht[root].rch,tab+3);//沿右链下降
}
}
voidshowCode()//显示哈夫曼编码
{
inti,j;
for(i=1;i<=n;i++)
{printf("%c:
",hc[i].data);//输出结点字符
for(j=hc[i].start-1;j>=0;j--)//依次输出结点的编码
printf("%d",hc[i].code[j]);
printf("\n");
}
}
voidprintText(char*str)//将输入的文本存储于str字符数组中,并将其输出
{
charch;
inti=0;
freopen("huffman.in","r",stdin);
while((ch=getchar())!
=EOF)
str[i++]=ch;
str[i]='\0';
puts(str);
}
voidstrChangeCode(char*str)//str字符数组中的文本转换为哈弗曼编码
{
intk=0,j=0,l=0;
while(*(str++))//扫描文本,直到结束
{
for(inti=1;i<=n;i++)//扫描每个字符编码列表,即hc
{
if(hc[i].data==*(str-1))//发现两个字符相同,把该字符的哈弗曼编码以字符串存储到hmcode数组中去
for(j=hc[i].start-1;j>=0;j--)
{
hmcode[l++]=hc[i].code[j]+48;
}
}
}
hmcode[l]='\0';
puts(hmcode);
}
voidcodeChangeStr(char*text)//解压hmcode,并把解压后的文本存储到text数组中
{
intchild,i=0,j=0;
child=root;//从根开始扫描
while(hmcode[j++])//扫描hmcode
{
if((hmcode[j-1]-48)==0)//编码为0移到左孩子
child=ht[child].lch;
if((hmcode[j-1]-48)==1)//编码为1移到右孩子
child=ht[child].rch;
if(child<=n)//直到为叶子了,把寻找到的数据赋给text,
{
text[i++]=hc[child].data;
child=root;//返回根
}
}
text[i]='\0';
puts(text);
}
intmain()
{
charstr[TXT];//存储输入的待压缩的字符串数组
chartext[TXT];//存储解压哈弗曼编码后的字符串数组
readData();
creatHtreeHcode();
showTree(root,1);
showCode();
printText(str);//输出待压缩的字符串
strChangeCode(str);//把该字符串转换成哈弗曼编码
codeChangeStr(text);//把编码解压成文本
return0;
}
五、调试过程
编译正确,无需调试。
六、实验结果
1)输入:
4
a3
b4
c2
d10
caabd
010*********
2)输出:
35
15
7
8
4
2
2
4
2
2
20
9
11
5
2
1
1
3
6
:
111
0:
00
1:
10
2:
11000
3:
11001
4:
0100
a:
1101
b:
0101
c:
0110
d:
0111
4
a3
b4
c2
d10
caabd
010*********
010*********
4
a3
b4
c2
d10
caabd
010*********
七、总结
通过此次实验让我学会了一些写程序的方法:
1)通过实验,让我了解了树在实际应用过程中的作用。
让我们对所学知识有了一个更全面的了解。
2)通过实验,使我对树的结构有了新的认识。
在今后学习数据结构的过程中有很大的帮助,也在编程的过程中掌握了更多编程上的技巧,如使用文件进行输入输出。
附录:
1)宁正元、王秀娟《算法与数据结构》,北京:
清华大学出版社,2006;
2)宁正元《数据结构》-用C语言描述,北京:
中国水利水电出版社,2000
福建农林大学计算机与信息学院实验报告
系:
计算机