数据结构实验指导书.docx
- 文档编号:8839310
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:15
- 大小:103.47KB
数据结构实验指导书.docx
《数据结构实验指导书.docx》由会员分享,可在线阅读,更多相关《数据结构实验指导书.docx(15页珍藏版)》请在冰豆网上搜索。
数据结构实验指导书
《数据结构》
实
验
指
导
书
实验一线性表的链式存储1
实验二简单运算器的实现5
实验三Huffuma编码的构造10
实验四拓扑排序13
实验五快速排序16
实验一线性表的链式存储
【实验目的和要求】
1.掌握线性表的结构特点和表示方法;
2.掌握线性表链式存储结构特性和基本操作算法;
3.掌握用指针实现单链表的建立、输出、插入和删除的算法。
【实验类型】验证性
【实验时数】2学时
【实验设备】计算机
【参考资料】
1.数据结构题解
2.C程序设计
【实验内容】
熟练掌握线性表的链式表示和实现方法,利用其定义具体的链表结点;利用链表的结构特点,建立单链表;利用链表结点间的指针关系,实现链表的插入和删除。
[具体要求]
(1)建立单链表时,要首先输入链表长度,根据输入值来确定所建链表的结点个数;
(2)在单链表中插入新结点时,要给出结点的插入位置和数据域的值;
(3)在单链表中删除某个结点时,要给出要删结点的位置;
(4)要编写单链表的输出函数,以便能验证程序的执行结果。
【实验分析】
1、实验的第一步应该建立单链表结点类型和程序所需的宏或数据类型,例如:
#defineNULL0//宏定义NULL的值为0
#defineLENsizeof(structnode)//宏定义LEN,为申请结点空间时做准备
typedefstruct
{inta;
floatb;
}elemtype;//定义elemtype类型,这里同学们可以根据自己的情况来自行定义。
typedefstructnode
{elemtypedata;//data域为elemtype类型的,它应该包含两个子域:
a和b
structnode*next;
}NODE,*NODEPTR;//定义了单链表结点类型和单链表结点指针类型
2、对单链表的四种操作进行实现。
(1)NODEPTRcreatlink()建立单链表的函数
很明显这个函数的返回值是结点指针类型的,所以这个函数应该返回的是建立的单链表的头指针。
同学们可以根据自己的构思,从前往后或从后往前建立单链表。
此外,提醒同学们最好建立带有附加头结点的单链表。
(2)voidprint(NODEPTRLh)输出单链表的函数
这个函数主要是将单链表中各结点的数据域的信息输出出来,输出数据的格式要根据同学们对于链表结点的data域所属的elemtype类型来设定。
(3)voiddel(NODEPTRLh,inti)删除结点的函数
这个函数完成的是在链表Lh中删除指定位置i的结点。
i的值是在执行删除操作之前通过键盘输入的。
(4)voidinsert(NODEPTRLh,inti)插入结点的函数
这个函数完成的是在链表Lh中在指定位置i的结点前或后面插入新建结点。
i的值是在执行插入操作之前通过键盘输入的。
同学们可以根据自己的情况选择是在结点前面插入还是在后面插入。
3、第二步应该构思程序主界面。
本实验要求实验单链表的建立、输出、插入和删除四种具体操作,因此可以主界面中可以给出相应的这四种操作的标题,用户在运行时可以根据自己的需要来选择要进行的操作,形式可以如下:
************************
Creat:
1Print:
2
Delete:
3Insert:
4
Esc:
0
************************
pleaseinputyourchoice(0-4):
用户通过键盘输入各操作对应的数码,就可以进入相应的操作了。
这是要使用一个变量(假设为operate_num)来接收用户输入的操作数码,在主函数中利用switch语句根据这个量的值来进行不同的操作。
例如:
switch(operate_num)
{case1:
进行单链表建立操作;break;
case2:
输出单链表的数据信息;break;
case3:
输入要删除的结点的位置;
删除指定结点;
break;
case4:
输入要插入的位置;
插入新建结点;
break;
}
【实验原理、数据(程序)记录】
略。
请同学们根据上面的步骤提示自己编程,不要互相抄袭。
【实验结果】
根据具体执行的情况,写出相应的实验结果。
同学们各自执行的结果应该不尽相同。
【注意事项】
1.学生上机时要严格遵守实验规章制度,若实验设备出现故障,应及时向实验指导教师反映,不要私自拆卸实验设备。
2.独立完成实验要求的内容,仔细观察和记录实验结果,领会实验目的,并认真完成实验报告。
实验二简单运算器的实现
【实验目的和要求】
1.掌握栈的结构特点、操作特征和表示方法;
2.掌握栈的存储结构特性和基本操作的算法;
3.掌握用栈实现简单四则运算的算法,从而设计和实现一个简单的运算器。
【实验类型】设计性
【实验时数】4学时
【实验设备】计算机
【参考资料】
1.数据结构题解
2.C程序设计
【实验内容】
充分理解栈的操作受限的特点,利用先进先出的结构特性实现实际应用问题。
[具体要求]
(1)定义栈类型为“stack”。
(2)输入一个包含+、-、×、\和括号简单四则运算表达式,程序可以得出正确结果;
(3)仔细理解表达式的求解过程,归纳运算符优先级的表示方法并用程序实现。
【实验分析】
1、定义程序所需的栈类型“stack”,例如:
typedefstruct
{floats[10];
inttop;
}stack;/*定义栈类型*/
同学们可以起另外的类型名称。
2、写出栈的基本运算
voidinistack(stack*st)/*置栈空,s->top应该为-1*/
floatgettop(stack*st)/*取栈顶元素返回*/
voidpush(stack*st,floatx)/*元素x进栈,s->top应加1*/
floatpop(stack*st)/*元素出栈,并出栈的栈顶元素返回,s->top应减1*/
用程序将它们实现,以备后面程序中使用。
同学们可以定义另外的形式参数名。
3、设计实现用于“出栈运算”的函数operate
floatoperate(floata,chartheta,floatb)/*进行相应运算并得到结果*/
若当前读入的算符优先级小于算符栈栈顶算符优先级时,就要进行相应的“出栈运算”。
其中要让算符栈栈顶算符出栈,再让操作数栈连续两次出栈依次得到右操作数和左操作数。
之后,就可以利用这个函数来进行相应的运算了。
函数形参中的a和b分别表示左操作数和右操作数,theta表示此时要进行的算符。
本实验是实现简单的四则运算,因此theta只可能是“+、-、×、\”。
可以利用switch语句来判断theta,根据判断结果,做相应的运算。
例如:
Switch(theta)
{cast”+”:
做加操作,得a+b的和;break;
case”-“:
做减操作,得a-b的差;break;
case”*”:
做乘操作,得a*b的积;break;
case”/”:
做除操作,得a/b的商;break;
}
最后将运算结果返回即可。
4、实现算符优先级的函数precede函数。
charprecede(charθ1,charθ2)/*比较相继出现的两个运算符θ2与θ2的优先级,返回字符*/
根据四则运算的优先级可以得到书第53面表3.1的算符间的优先关系表。
仔细观察这张表,可以得到一定的规律,由此可以编写precede函数。
在看这张表时一定要记住θ1和θ2是相继出现的,也就是说θ1先出现,然后θ2再出现并与θ1比较优先级的高低。
由此,可以说θ1是算符栈的栈顶算符,而θ2是当前读入的算符。
仔细观察这张表,可以得到一些规律:
(1)θ1是“+”和“-”时,当θ2是“*”、“/”和“(”时,它们的优先级关系应该是“<”,其余时候它们之间的优先关系是“>”;
(2)θ1是“*”和“/”时,当θ2是“(”时,它们之间的优先级是“<”,其余时候是“>”;
(3)θ1是“(”时,当θ2是表达式结束符时,它们之间的优先级是错误的可以用字符“e”表示,其余情况又可以分成两种:
当θ2是“)”时,它们之间的优先级是相同的“=”,θ2是其它字符时,它们之间的优先关系是“<”;
(4)θ1是“)”时,当θ2是“(”时,它们之间的优先关系是错误的用字符“e”表示,θ2是其它字符时,它们之间的优先关系就是“>”;
(5)θ2是表达式结束符时,当θ2也是表达式结束符时,它们之间的优先关系时相等的用“=”表示,其余情况又可分为两种:
当θ2是“)”时,它们之间的优先级关系用“e”表示,θ2是其它字符时,它们之间的优先级关系都可以利用“<”来表示。
这五种情况就将相继出现的算符θ1和θ2之间的优先级关系总结完毕了。
接下来,就是考虑用什么语句来实现它了。
很显然,总共有5种情况,而这5种情况都是根据θ1的值来分的,即当θ1的值确定后,再根据θ2的值来判断,因此可以利用switch语句来实现:
Switch(θ1)
{case‘+’:
case’-‘:
if(θ2是“*”或是“/”或是“(”)z=’<’
elsez=’>’;
break;
case’*’:
case’/’:
if(θ2是“(”)z=’<’
elsez=’>’;
break;
case‘(‘:
if(θ2是表达式结束符)z=’e’
elseif(θ2是“)”)z=’=’
elsez=’>’;
break;
case‘)’:
……
case表达式结束符:
……}
最后将优先级比较的结果z的值返回即可。
5、判断当前读入的字符是不是算符的in函数;
intin(charch,charopn[])/*判断字符是否为算符*/
字符数组opn中包含“+”、“-”、“*”、“/”、“(”、“)”和表达式结束符。
只要将当前读入的字符w与数组元素值一一比对,当前读入的字符ch只要等于这些字符中的一个,就可以断定当前读入的是算符,返回1;如果都不等于,就返回0。
6、最后来设计实现主函数。
(1)定义两个栈:
算符栈optr和操作数栈opnd;
(2)初始化操作,主要包括:
两个工具栈的初始化;表达式结束符进算符栈;输入表达式;
(3)不断读入字符到字符变量w,并对读入的字符w进行判断,看它是操作数还是算符;
注意:
因为程序中的栈类型中存放的数据都是float类型,而输入读取的都是char类型,因此在用in函数判断当前读入的字符w是操作数时,应该让它进操作数栈opnd,但是在进栈之前应该先将当前读入的数字字符w转换为真正的数值(因为字符‘2’与数值2是不同的)。
转换的方法也很简单,只需将当前读入的字符w减去‘0’即可,即w=w-‘0’。
至于是为什么,请同学们仔细体会。
①如果是操作数,将其转换为真正对应的数值进opnd栈,然后在继续读入下一个字符;
②如果是算符,应利用preced函数判断当前字符w与optr栈栈顶算符的优先级,即precede((char)gettop(optr),w)。
然后再根据返回值(优先级高低)进行不同的操作。
因为prcede函数的返回值不外乎是‘>’、‘<’、‘=’和‘e’,所以这部分又可以利用switch语句来实现:
switch(precede((char)gettop(optr),w))
{case‘<’:
将w进算符栈optr;//注意在进栈时要把w强制转换成float类型
再读入字符;
break;
case‘=’:
//此时一定是“(”遇到了“)”
将当前算符栈栈顶算符出栈;//脱掉了外层括号
再读入字符;
break;
case‘>’:
//此时要进行出栈运算
将optr栈栈顶算符出栈给theta;
将opnd栈栈顶操作数出栈给b;//出栈右操作数
将opnd栈栈顶操作数再次出栈给a;//出栈左操作数
利用operate函数即operate(a,(char)theta,b)计算出结果,将函数返回值进opnd栈;
break;
case‘e’:
输出错误信息;结束程序。
}
(4)最后将表达式的运算结果输出,即将最后的操作数栈opnd栈栈顶元素取出来输出。
【实验原理、数据(程序)记录】
略。
请同学们结合上课时所讲算法和以上的实验提示,认真自主的完成实验,不要互相抄袭,自己完成程序的成就感时无可比拟的!
【注意事项】
1.学生上机时要严格遵守实验规章制度,若实验设备出现故障,应及时向实验指导教师反映,不要私自拆卸实验设备。
2.独立完成实验要求的内容,仔细观察和记录实验结果,领会实验目的,并认真完成实验报告。
实验三Huffuma编码的构造
【实验目的和要求】
1.理解和掌握树型结构的特点和基本操作;
2.利用数组存储哈夫曼编码并定义所需的属性结构;
3.掌握哈夫曼树的结构特点和哈夫曼编码的构造算法及应用。
【实验类型】验证性
【实验时数】4学时
【参考资料】
1.数据结构题解
2.C程序设计
【实验内容】
理解哈夫曼树的结构特定,利用哈夫曼树的的构造算法进行哈夫曼编码的构造。
(1)定义程序所需各种数据类型;
(2)仔细理解和分析哈夫曼编码构造算法,编写程序;
(3)调试并修改程序,得到正确的实验结果。
【实验分析】
哈夫曼编码的算法:
①以文件中每个字符出现的频率作为叶结点的权值来设计哈夫曼树;
②求每个叶子结点的编码,从叶子到根通过依次找双亲来进行,得到的编码是反序的,进行转换之后方可得到对应编码。
1、假设要进行编码的字符也就是叶子是n个,用一维数组huftree来存储构成的哈夫曼树。
哈夫曼树的结点类型定义为:
typedefstruct
{charch;表示结点的字符值;
intweight;结点的权值
intlchild,rchild,parent;结点左、右孩子和双亲结点在数组中的下标值
}HTNODE;
HTNODEhuftree[2n-1];定义了一维数组huftree,数组长度为2n-1。
2、定义一个数组cd,专门用于存放各个叶子结点代表的字符值和各个叶子结点字符对应的编码。
因此,该数组元素应该包含两部分:
typedefstruct
{char*code;用于指向字符对应的编码字符串
charleaf;叶子结点代表的字符值
}CODE;
所以,数组定义为:
CODEcd[n];
3、用一个整型数组w来存放按升序排列的叶子的权值。
intw[n];
4、算法分析:
(以{a,b,c,d,e}权值分别为1,2,3,4,5的字符为例)
(1)用一维数组huftree来存储哈夫曼树(0号元素不用),初始状态为:
(2)选取结点生成内部结点,一共要生成n-1个内点(用k来表示生成内点的个数)。
每次都要选取从未用过的当前权值最小的两个结点来生成新的结点,则在数组中就要选取parent为0,权值最小的两个结点生成内点,通过课堂讲解可以知道符合条件的两个结点的下标s1和s2与当前生成的内点个数k之间存在关系:
s1=2k-1;s2=s1+1;由它们产生的内点的权值:
sum=huftree[s1].weight+huftree[s2].weight;
然后,将生成的新内点按权值升序插入到数组huftree中,可以采取从后往前进行权值比较,直到找到合适的位置(j+1)将其插入,并且将产生的这个新内点与它的左右孩子结点(s1结点和s2结点)的关系进行体现:
huftree[s1].parent=j+1;
huftree[s2].parent=j+1;
huftree[j+1].lchild=s1;
huftree[j+1].rchild=s2;
依次类推,最终的huftee数组为:
至此,整棵产生的哈夫曼树已经全部完成,并存储在数组huftree中,产生的哈夫曼树为:
由树中叶子结点开始向上回溯,从叶到根。
若当前结点是左孩子,则得‘0’,否则得‘1’,得到了反序的编码字符串存入到字符数组temp中,然后根据得到的编码串的实际长度来开辟空间,由数组cd中code指针域指向,再存放各个叶结点代表的字符值,得到相应的编码对照表:
【注意事项】
1.学生上机时要严格遵守实验规章制度,若实验设备出现故障,应及时向实验指导教师反映,不要私自拆卸实验设备。
2.独立完成实验要求的内容,仔细观察和记录实验结果,领会实验目的,并认真完成实验报告。
实验四拓扑排序
【实验目的和要求】
1.理解和掌握图的基本概念,掌握图的两种存储结构邻接表和邻接矩阵;
2.掌握图的相关的定义和在实际应用中的不同特点;
3.通过构造邻接表,实现拓扑排序,并按邻接表形式输出结果。
【实验类型】验证性
【实验时数】4学时
【实验设备】计算机
【参考资料】
1.数据结构题解
2.C程序设计
【实验内容】
用邻接表构造并存储图,并利用拓扑排序算法进行图中结点的拓扑排序。
(1)定义所需的各数据类型以实现图或网的构造,并用邻接表存储;
(2)按邻接表形式输出图;
(3)利用拓扑排序算法实现网结点的拓扑序列的输出。
【实验分析】
在一个有向图中找一个拓扑序列的过程称为拓扑排序。
拓扑排序过程如下:
(1)从有向图中选择一个没有驱动(即入度为0)的顶点并且输出它。
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边。
(3)重复上述两步,直到剩余的网中不再存在没有前驱的顶点为止。
为了实现拓扑排序算法,将邻接表表头结点增加一个入度如下:
typedefstructVnode邻接表头结点的类型
{ElemTypedata;顶点信息
intcount;存放顶点入度,专为拓扑排序设置
ArcNode*firstarc;指向第一条边
}Vnode;
在生成图的邻接表时计算每个顶点的入度值。
拓扑排序算法TopSort(G,Topsq),当拓扑排序成功时,该算法返回1,并将排序结果存放到Topsq[]数组中;否则,该算法返回0。
IntTopSort(Agraph*G,intTopsq[])拓扑排序结果存放到Topsq[]数组中
{
intI,j,n=0;
intSt[MAXV],top=--1;栈St的指针为top
ArcNode*p;
For(I=0;I If(Gadjlist[i].count==0)入度为0的顶点入栈 {top++; St[top]=I; } while(top>--1)栈不为空时循环 {I=St[top];top----;出栈 Topsq[n]=I;n++;将顶点I放入拓扑序列中 P=Gadjlist[i].firstarc;找到第一个相邻顶点 While(p! =NULL) {j=padjvex; Gadjlist[j].count――; If(Gadjlist[j].count==0)入度为0的相邻顶点入栈 {top++; St[top]=j; } p=pnextarc;找下一个相邻顶点 } } if(n return(0); else return (1);拓扑排序成功 } 【注意事项】 1.学生上机时要严格遵守实验规章制度,若实验设备出现故障,应及时向实验指导教师反映,不要私自拆卸实验设备。 2.独立完成实验要求的内容,仔细观察和记录实验结果,领会实验目的,并认真完成实验报告。 实验五快速排序 【实验目的和要求】 1.理解排序稳定性含义,掌握各种排序算法的稳定性; 2.掌握各种内部排序的基本算法和特点; 3.掌握快速排序的排序过程,程序实现快速排序。 【实验类型】验证性 【实验时数】2学时 【实验设备】计算机 【参考资料】 1.数据结构题解 2.C程序设计 【实验内容】 掌握快速排序的算法程序实现排序过程。 具体算法可描述如下: 设初始序列为a1,a2,……,an,以序列中的某个元素ai为基准(轴),经调整后,使得ai左边的元素均小于ai,右边的均大于等于ai,而后对这两个子区再分别使用快速排序。 [具体要求] (1)需要用一维数组a来存储等待排序的序列; (2)设置两个工作指针i和j; (3)每次快速排序都以排序区域的首元素为基准(轴); (4)程序用递归函数来实现。 【实验分析】 【注意事项】 1.学生上机时要严格遵守实验规章制度,若实验设备出现故障,应及时向实验指导教师反映,不要私自拆卸实验设备。 2.独立完成实验要求的内容,仔细观察和记录实验结果,领会实验目的,并认真完成实验报告。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 指导书