数据结构实验指导书hfWord格式.docx
《数据结构实验指导书hfWord格式.docx》由会员分享,可在线阅读,更多相关《数据结构实验指导书hfWord格式.docx(29页珍藏版)》请在冰豆网上搜索。
对需编程的实验,写出程序设计说明,给出主要源程序流程图和清单。
(4)遵守机房纪律,每人每次实验固定一台机器,不得随意换用其他机器。
服从实验教师的安排和指挥,爱护实验设备,开关机时注意保护机器。
(5)实验课不得迟到、早退。
如有事不能参加实验,须提前向实验教师请假,申请调换批次。
(6)根据学校规定,无故缺少任一次实验操作或任一次实验报告,实验总成绩为0分。
平时实验的验收将分为两个部分。
第一部分是上机操作,包括检查预习报告、实验操作、程序运行和即时提问。
第二部分是提交书面的实验报告。
此外,针对以前教学中出现的问题,实验将采用阶段检查方式,每个实验都应当在规定的时间内完成,过期视为未完成该实验,以避免期末集中检查产生的诸多不良问题,希望同学们抓紧时间,合理安排,认真完成。
三实验步骤1选择自己的实验课题,写出预习报告,预习报告中应给出自己解决问题使用的实现算法以及对应算法的代码编写(注意不要把教材已经给出的文件代码重复抄写)。
2利用预习报告,在上机实验时完成自己设计的实现,完成后举手示意让老师验收。
3回去后完成自己的实验报告。
实验报告中应有算法的复杂度分析、实现以及遇到的问题及其解决方案和实验后的心得。
实验报告在下一次实验时上交。
实验一实验一线性表线性表实验目的1、掌握线性表的逻辑结构和物理实现;
2、掌握线性表的顺序存储结构和链式存储结构,熟悉对线性表的基本操作;
3、在学有余力的情况下,掌握循环链表的实现及其基本操作;
4、根据实验要求设计并完成程序,把理论的基本操作知识转化到实际的实践应用中。
实验原理线性表是最简单的一种数据结构。
线性表是由n(n=0)个数据元素组成的有限序列。
线性表中的数据元素可以是各种各样的,但同一线性表中的数据元素必须有相同的属性,因此是属于同一数据类型的。
在计算机内,可以用不同的方式来表示线性表,其中最简单和最常用的方式是用一组地址连续存储单元依次存储线性表中的元素。
其特点是逻辑关系上相邻的两个元素在物理位置上也相邻。
一般地,线性表的顺序存储结构可用一个一维数组结构来描述。
用这种方法存储的线性表简称为顺序表。
线性表的链式存储结构(也称链表)的特点是用一组任意的存储单元存储线性表中的数据元素,不要求逻辑上相邻的元素在物理位置上也相邻。
链表中的结点只有一个链域的链表称为单链表。
循环链表则是一种首尾相接的链表。
对线性表首先要掌握作为抽象数据类型(ADT)的那些基本操作,其次才是具体实现的细节。
实验要求(课题一必做,课题二选做)实验课题一:
(C语言实现)在给出参考代码中给出的线性表结构体以及与之相关的函数的基础上,编写程序,实现以下操作:
1、构造一个表,然后查找表内是否有某元素,如果有则交换该元素和它相邻的下一元素的位置;
2、写一个函数reverse,使其能倒置线性表中元素。
这个表倒置函数的时间复杂度应该是(n)。
课题一的具体实验内容1、构造元素类型为整型的线性表,将以下元素插入分别插入线性表:
2、查找表中是否存在元素20,实现元素20与元素9的交换;
3、按照课题要求编写函数,实现线性表元素的倒置,即倒置后的表应为。
*实验课题二:
约瑟夫(Josephus)问题的求解(循环链表的使用,使用C和C+语言均可)。
假设有编号为1,2,n的n个人围坐成一圈,约定从编号为k(n=k=1)的人开始报数,数到m的那个人出列,他的下一个人从1开始重新报数,数到m的那个人出列,依次类推,直到所有的人全部出列为止,由此产生一个出队编号的序列。
1、给定一个8个人的圈(n=8),约定从第3个人开始报数(k3),数到第4个人时的那个人出列(m4),使用循环链表,产生一个出队编号的序列。
2、参考的出队序列为:
。
实验步骤:
1、在“F:
2、创建项目,文件保存到第1步说的目录。
3、每台计算机的教材参考代码在“E:
DataStru”,先解压至“F:
DataStru”。
4、通过“工具/选项/vc+目录/包含文件”把相应的F:
DataStru”的代码包含进去,以便编程的时候,包含相关头文件,或参考测试程序。
5、弄懂教材参考代码中给出的线性表类(c+)或线性表结构体以及与之相关的函数(c);
构造一个表,进行实验要求的课题。
实验二实验二栈栈【实验目的】1、掌握栈的LIFO(后进先出)特点和栈的存储结构;
2、熟悉栈的各种操作;
3、掌握栈的应用方法,理解栈的重要应用;
【实验原理】栈是一种特殊的线性表,这种线性表只能在固定的一端(称为栈顶(top)进行插入和删除操作。
由于只允许在栈顶进行插入和删除操作,所以栈的操作是按照“后进先出”(LastInFirstOut,缩写为LIFO)原则进行的。
本实验要求用栈作为基本的数据结构解决各实验课题。
【实验要求】
(实验课题一必做,其他选做)实验课题一:
将一个十进制数转换成另外一个P进制数字符串(可以是二进制到十六进制)。
转换函数的原型为:
voidConvert(intn,charstr,unsignedP);
n:
输入,待转换的数str:
输出,转换好的P进制字符串P:
输入,要转换的进制,取值可从2到16。
如果在这范围之外,可认为输入错,不做转换。
将一个整数转换成P进制的数,我们可以采用如下的方法:
例:
十进制转换成八进制(P等于8):
(66)10=(102)866/8=8余28/8=1余01/8=0余1当商为0时转换结束,转换结果为上述过程余数序列的逆序:
102。
先求得的余数在写出结果时最后写出,最后求出的余数最先写出,符合栈的LIFO性质,故可用栈来实现数制转换。
用2个栈实现一个队列,并对使用这种方法实现的队列执行入队、出队操作的时间进行分析。
用C实现的同学,应该实现教科书第76页Figure3.56(参考代码的queue.h)中定义的队列类型的那些操作函数;
*实验课题三:
将一个普通代数表达式(infixexpression)转换为后缀表达式(postfixexpression)。
转换规则描述参见:
描述C语言描述的课本pp.68-71。
在本实验中,也只用、(、)作为算符,优先级自低至高为、*、()。
实验三实验三队列队列【实验目的】1、掌握队列的FIFO的特点(先进先出)特点和队列的存储结构;
2、熟悉队列的各种操作;
3、掌握队列的应用方法,理解队列的重要应用;
4、根据实验要求设计并完成程序。
【实验原理】队列是限定只能在表的一端进行插入,而在表的另一端进行删除的线性表。
是一种“先进先出”(FirstInFirstOut,缩写为FIFO)的线性表。
(实验课题一必做,课题二选做)实验课题一:
回文(palindrome)是指一个字符串从前面读和从后面读都一样,使用若干栈和队列,设计一个算法来判断一个字符串是否为回文。
假设字符串从标准输入设备一次读入一个字符,算法的输出结果为true或者false。
可以用一些字符串测试输出结果,如:
abcdeabcde,madamimadam等实验课题二:
打印扬辉三角形。
111121133114641151010511615201561172135352171打印二项式(a+b)i的展开系数,也就是扬辉三角,国外叫做Pascalstriangle。
如右下图为扬辉三角的前8行数据。
按照如右图所示的方式,完成对应杨辉三角的打印输出。
杨辉三角实验四实验四树树【实验目的】1、掌握树这种数据结构的特点和树的存储结构;
2、掌握二叉树的建立(二叉链表的建立);
3、掌握并灵活运用各种次序的遍历算法;
【实验原理】由于树的定义是递归的,对树的处理原则上也应是用递归的方式。
二叉树是一种非常重要的类型。
针对二叉树的操作主要有三种遍历(先序遍历、中序遍历、后序遍历),遍历二叉树是二叉树中各种运算的基础。
(实验课题一必做,课题二、三选做)实验课题一:
将下图中的二叉树用二叉链表表示:
1用三种遍历算法遍历该二叉树,给出对应的输出结果;
2写一个函数对二叉树搜索,若给出一个结点,根据其是否属于该树,输出true或者false。
3写函数完成习题4.28(C版教科书)。
实验课题二:
构造表达式树。
可参考教科书4.2.2(具体规则用C描述教材的p87)。
实验课题3:
哈夫曼编码的生成当哈夫曼树生成后,对由根节点到各叶结点(对应于待编码的符号)的路径作0-1编码就得到相应的哈夫曼编码。
任何一棵满二叉树(afullbinarytree)都可以看作是一棵哈夫曼树,所以本课题要求:
造一棵满二叉树,根据这棵二叉树生成相应的哈夫曼编码。
生成二叉树根据不同的应用规则可以有各种生成二叉树的方法,如二叉搜索树、表达式树、哈夫曼树等。
我们在这里描述一个根据对二叉树各节点遍历所得序列生成二叉树的方法,一般从这样一个序列不一定能生成这棵二叉树。
但如果把这二叉树的所有空指针都画出来就得到一棵满的扩充的树,根据对这棵扩充树的遍历得到的序列,可以生成那棵二叉树。
例如,用表示空指针,那么课题一图中那棵扩充二叉树的先序遍历得到的节点序列是:
char*extendedPreOrd=ABDFEGHC;
用它做为下列二叉树建造函数的输入就得到前图所示的树。
创建二叉树可用以下方法之一:
方法1:
TreeBiTreeBuildFrmStr(char*str)if(*str!
=)TreeNode*root=malloc(sizeof(TreeNode);
if(root=NULL)printf(Nomemoryavailable!
);
root-Element=*(*str)+;
root-Left=BiTreeBuildFrmStr(str);
root-Right=BiTreeBuildFrmStr(str);
returnroot;
else/theNULLpointer,justskipit(*str)+;
returnNULL;
方法2:
TreeCreateBiTree()/使用先序序列建立二叉树Treet=NULL;
charc;
c=getchar();
if(c=)t=NULL;
elseif(!
(t=(Tree)malloc(sizeof(Tree)/动态生成二叉树结点printf(mallocfailure!
n);
t-Element=c;
t-Left=CreateBiTree();
/创建二叉树的左子树t-Right=CreateBiTree();
/创建二叉树的右子树returnt;
二叉树的打印与教科书上的二叉树图相比,这里打出的数向左旋转了90度。
当然了,这里还是递归。
voidprintTree(Treeroot,intdepth)inti;
if(root=NULL)return;
/EmptytreeprintTree(root-Right,depth+1);
/Dorightsubtreefor(i=0;
iElement);
/PrintnodevalueprintTree(root-Left,depth+1);
/Doleftsubtree/printtreedrivervoidPrintTree(Treeroot)printTree(root,0);
实验五实验五散列表散列表【实验目的】1掌握散列表的构造方法;
2观察冲突现象及其解决;
3掌握使用散列法进行查找的方法。
【实验原理】散列(hashing)的基本思想是:
通过一个确定的散列函数关系H,把数据对象的关键字K映射到相应的散列值H(K),这个值就是该对象在散列表中的存储位置,又称散列地址。
查找时根据要查找的关键字k用同样的散列函数计算地址H(k),然后在散列表相应的单元取要找的对象。
对于散列表,最重要的是构造散列函数和对冲突的处理。
影响散列表查找效率的因素是装填因子(loadfactor)。
【实验要求】实验课题:
做这个实验时采用OpenAddressing框架,也可加做SeparateChaining以形成比较。
1构造散列表,把字符串数组中的各项加入到散列表中char*MyBirds13=robin,sparrow,hawk,eagle,seagull,bluejay,owl,cardinal,Jakana,Moa,Egret,Penguin,hawk;
为便于观察冲突现象,初始构造散列表时,表的容量不要过大,对OpenAddressing,装载因子为0.5左右,对于SeparateChaining,装载因子为1左右即可。
也不要做rehash(应该改源代码的哪里,如何改)。
建议对源代码做些改动、增加一些输出(建议用条件编译控制这些输出),以便于观察冲突的发生和解决;
对于OpenAddressing,参考代码的冲突解决方案是用的平方探测(quadraticprobing),如果用线性探测(linearprobing)的策略,应该对函数findPos做什么修改(冲突解决的策略都集中在那里)?
2观察不同的散列函数产生冲突散列地址的情况教科书上给了3个以字符串作输入的散列函数(两教科书第3个不一样),观察记录它们产生冲突散列地址的情况,写入你的实验报告。
还可对下列散列函数(所谓ELFhash,UnixSystemV用的)作观察inthash(char*key)/Cversionunsignedlongh=0;
while(*key)h=(h24;
h&
=g;
returnh;
/%M3对散列表做查找。
【提示】用C描述课本的同学可参考:
hashfunc.c、hashquad.c、hashquad.h、hashsep.c、hashsep.h和testhash.c实验六实验六排序排序【实验目的】1、掌握常用的几种内部排序算法,理解各种内部排序算法的基本思想和特点;
2、熟悉内部排序法的排序过程;
3、掌握内部排序算法的时间复杂度,针对不同的问题能选择出合适的排序方法。
【实验原理】排序是将一个无序的数据元素(或记录)序列,重新排列成一个按关键字递增(或递减)的有序序列的过程。
在计算机算法设计中,排序占有相当重要的地位。
排序分为内排序和外排序。
我们只讨论内排序。
本课程涉及的主要的内排序算法有:
插入排序、Shell排序、归并排序、快速排序等。
排序算法有稳定和不稳定之分。
【实验内容】
【用C描述课本的同学】有以下结构体构成的数组:
structStudentInfocharID10;
char*name;
floatscore;
StuInfo12=0800301105,JACK,95,0800201505,LUN,85,0400820115,MARY,75.5,0400850122,KATE,78.9,0500201011,LILI,88,0800401105,JACK,96,0600830105,JAN,98.4,0952520012,SAM,75,9721000045,OSCAR,64,0700301105,JACK,97,0458003312,ZOE,68.9,0400830211,BOBI,87.6;
1使用直接插入的排序方法按照学号的顺序对以上数组进行排序(递增);
2分别用归并排序和快速排序按照姓名的顺序对以上数组进行排序(递增),有3人的名字是JACK,注意观察排序是否稳定。
实测比较各排序算法的运行时间。
1、定义长度为N的数组(C),用0到N-1之间的随机整数对各元素赋值;
2、用内插排序、归并排序和快速排序对其排序,记录排序的时间;
3、用不同的N做几次测试,比较各排序算法所用的时间。
最初可以取N=1000,你可能得不到有效的测试结果,接下来,你可能会令N=10000,这时的测试数据会比较有意义了,再接着你可能想把N再扩大10倍,这里要提醒同学们,内插排序的时间复杂度是O(N2),当N扩大10倍,它需要的排序时间大致要扩大上百倍,你有这个耐心等待吗?
所以请同学们小心,对较大的N,只应对O(NlogN)的算法测试;
4、当测试框架搭好后,很方便对其它排序作测试,所以鼓励同学们对Shell排序、堆排序等,都可一并作比较测试;
5、注意记录整理测试结果好写入实验报告。
【实验参考程序】C描述的排序算法的实现在Sort.h内。
TestSort已经搭了一个测试框架,对书中各种排序甚至选择算法作了测试,但没有测排序时间,用C写的同学也可以参考(时间测试见下面)。
用C的同学可以用C标准库的随机数产生器(C+版实际用的也是它):
#include/这个头文件包含下列函数的说明voidsrand(unsignedseed);
/随机数产生器初始化,一般应用只需自选seed初始化一次/seed就决定了后面调用random产生的序列intrandom(intnum);
/产生0,num-1之间的随机数【时间测试函数】C和C+都可以用#include/Usedbytimingfunctions/Timingvariablesandfunctionsclock_ttstart=0;
/TimeatbeginningoftimedsectionvoidSettime()/Initializetheprogramtimertstart=clock();
doubleGettime()/ReturntheelapsedtimesincethelastcalltoSettimereturn(double)(double)clock()-(double)tstart)/(double)CLOCKS_PER_SEC;
测试例:
Settime();
/开始计时,这之后到调用Gettime()之间是要测试时间的程序段/待测的语句段doubleelapsedTime=Gettime();
/elapsedTime就是这段时间(以秒计)实验七实验七查找查找【实验目的】1、掌握几种常用的内部查找算法;
2、熟悉二分查找算法和二叉搜索树的查找过程。
【实验原理】查找又称为检索,就是根据给定的某一个值从一个数据元素集合中找出某个特定的数据元素。
查找和排序一样,是数据处理中经常使用的运算,查找算法的优劣对整个软件系统的影响很大。
在一个数据元素集合中进行查找可选用的方法和该数据元素集合的存储结构有很大关系。
查找有内查找和外查找之分。
对于线性表,主要的内查找算法有顺序查找、二分查找等。
但要注意,二分查找只适合于有序的线性表。
第4章学的二叉搜索树是搜索性能优良的存储结构。
(实验课题一必做,课题二选做)实验课题:
1编写程序对实验六中的数组进行查找:
用C版教科书的同学:
对数组StuInfo按照学号(ID)递增排序,然后用二分查找的方法进行学号查找,若找到则输出该学生的全部信息,若找不到相应记录也给出提示;
接下来,对该数组按照学分绩(score)递减排序后,使用二分查找法以学分绩作关键字进行查找。
2对二叉搜索树查找用C版教科书的同学:
对StuInfo数组的数据以姓名(name)为关键字(key)建立一棵二叉搜索树(BST),然后以姓名为关键字进行搜索,并输出该记录相应的其它信息。
要做到对关键字查找和删除,需要改变Find和Delete函数的原型,把对ElementType的查找和删除变成对KeyType的查找和删除,即把PositionFind(ElementTypeX,SearchTreeT);
SearchTreeDelete(ElementTypeX,SearchTreeT);
改为PositionFind(KeyTypeX,SearchTreeT);
SearchTreeDelete(KeyTypeX,SearchTreeT);
当然,对这些函数也要做相应的改动。
【实验参考程序】二分查找C版教科书在p.24Figure2.9,相应的程序名是fig2_9.c。
二分查找函数原型是:
intBinarySearch(constElementTypeA,ElementTypeX,intN);
用它只能对C的基本算术类型(整型、浮