数据结构实验指导书hf.docx

上传人:b****5 文档编号:28627427 上传时间:2023-07-19 格式:DOCX 页数:42 大小:585.08KB
下载 相关 举报
数据结构实验指导书hf.docx_第1页
第1页 / 共42页
数据结构实验指导书hf.docx_第2页
第2页 / 共42页
数据结构实验指导书hf.docx_第3页
第3页 / 共42页
数据结构实验指导书hf.docx_第4页
第4页 / 共42页
数据结构实验指导书hf.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

数据结构实验指导书hf.docx

《数据结构实验指导书hf.docx》由会员分享,可在线阅读,更多相关《数据结构实验指导书hf.docx(42页珍藏版)》请在冰豆网上搜索。

数据结构实验指导书hf.docx

数据结构实验指导书hf

《数据结构B》实验指导书

 

电子工程学院

数据结构与算法分析教学小组编

前言

《数据结构B》是电子工程学院测控技术与仪器和电子信息科学与技术专业的专业必修课。

由于教科书选材的变动,原来使用的数据结构实验指导书与授课内容关联不够密切。

为了能更好的将理论教学和实验教学结合在在一起,我们调整了实验内容的安排,加大了实验的实践力度,并重新编写了实验指导书。

要学好数据结构这门课,加强算法的设计并上机加以实现是非常重要的,希望同学们充分利用实验条件,认真完成实验,从实验得到相应的锻炼和培养。

另外,仅仅依靠本实验教材中的实验想达到透彻理解数据结构的相关算法和实现是远远不够的,有条件有兴趣的学生可以针对学习和实践中出现的问题主动地思考和设计算法,编写程序,进一步提高自己分析问题和解决问题的能力。

希望同学们在使用本实验指示书及进行实验的过程中,对本实验指导书中的不足之处提出建议,使《数据结构B》课程的教学得到不断的改进和提高。

本实验指导书在编写过程中,参考了原来的电子工程系的数据结构实验指导书、计算机系的实验指导书。

由于编者水平有限,难免有不足之处,敬请批评指正。

电子工程学院数据结构与算法分析教学小组

2008年4月

目录

实验说明及要求3

实验一线性表4

实验二栈6

实验三队列8

实验四树10

实验五散列表14

实验六排序2

实验七查找5

实验八图8

综合设计考核11

附录1在VisualS2003中建立、编译和运行程序12

附录2使用教材提供的参考文件的方法17

附录3如何设置编译器生成C代码20

参考文献21

实验说明及要求

一实验说明

《数据结构B》实验是为了辅助《数据结构B》(双语教学)而开展的。

因为理论教学采用了两种教材(《数据结构与算法分析》的C++版和C语言描述版),所以在实验时程序的编写既允许采用C语言,又允许采用C++语言。

若采用C语言编程,C语言版本的《数据结构》教材上给出的基本结构,均已包含在头文件中,具体实验时可以从计算机的“E:

\DataStru\SourceCode\C\”目录下获取。

若采用C++语言编程,《数据结构与算法分析》(C++)(第3版)教材上给出的一些源码可以从计算机的“E:

\DataStru\SourceCode\CPP\”目录下获取。

编程的工具建议使用VisualC++开发环境,该编译环境对C和C++代码均支持。

具体操作:

在“F:

\DataStru\”目录下面创建自己以自己学号作为名字的文件夹。

自己所有的实验程序均放在该文件夹下面。

如学号为“0600820101”的同学,在“F:

\DataStru\”目录下创建一个名为0600820101的文件夹,自己整个数据结构实验过程中设计的实验程序,都放在“F:

\DataStru\0600820101\”目录下即可。

二实验要求

在《数据结构B》的课程实验过程中,要求学生做到:

(1)预习实验,认真做好实验内容的准备,对实验可能出现的情况提前做出思考和分析,并写成实验预习报告,需要编写程序的实验,提前做好实验的分析和设计工作。

(2)仔细观察上机编程操作时出现的各种现象,记录主要数据、信息,做出必要说明和分析。

对实验中遇到的问题及对应的解决方案,要及时加以记录并写在实验报告上。

(3)认真书写实验报告。

实验报告包括实验目的和要求,实验情况及其分析。

对需编程的实验,写出程序设计说明,给出主要源程序流程图和清单。

(4)遵守机房纪律,每人每次实验固定一台机器,不得随意换用其他机器。

服从实验教师的安排和指挥,爱护实验设备,开关机时注意保护机器。

(5)实验课不得迟到、早退。

如有事不能参加实验,须提前向实验教师请假,申请调换批次。

(6)根据学校规定,无故缺少任一次实验操作或任一次实验报告,实验总成绩为0分。

平时实验的验收将分为两个部分。

第一部分是上机操作,包括检查预习报告、实验操作、程序运行和即时提问。

第二部分是提交书面的实验报告。

此外,针对以前教学中出现的问题,实验将采用阶段检查方式,每个实验都应当在规定的时间内完成,过期视为未完成该实验,以避免期末集中检查产生的诸多不良问题,希望同学们抓紧时间,合理安排,认真完成。

三实验步骤

1选择自己的实验课题,写出预习报告,预习报告中应给出自己解决问题使用的实现算法以及对应算法的代码编写(注意不要把教材已经给出的文件代码重复抄写)。

2利用预习报告,在上机实验时完成自己设计的实现,完成后举手示意让老师验收。

3回去后完成自己的实验报告。

实验报告中应有算法的复杂度分析、实现以及遇到的问题及其解决方案和实验后的心得。

实验报告在下一次实验时上交。

 

实验一线性表

实验目的

1、掌握线性表的逻辑结构和物理实现;

2、掌握线性表的顺序存储结构和链式存储结构,熟悉对线性表的基本操作;

3、在学有余力的情况下,掌握循环链表的实现及其基本操作;

4、根据实验要求设计并完成程序,把理论的基本操作知识转化到实际的实践应用中。

实验原理

线性表是最简单的一种数据结构。

线性表是由n(n>=0)个数据元素组成的有限序列。

线性表中的数据元素可以是各种各样的,但同一线性表中的数据元素必须有相同的属性,因此是属于同一数据类型的。

在计算机内,可以用不同的方式来表示线性表,其中最简单和最常用的方式是用一组地址连续存储单元依次存储线性表中的元素。

其特点是逻辑关系上相邻的两个元素在物理位置上也相邻。

一般地,线性表的顺序存储结构可用一个一维数组结构来描述。

用这种方法存储的线性表简称为顺序表。

线性表的链式存储结构(也称链表)的特点是用一组任意的存储单元存储线性表中的数据元素,不要求逻辑上相邻的元素在物理位置上也相邻。

链表中的结点可用C语言中的结构数据类型来描述,也可以用C++语言中类来实现。

链表中的结点只有一个链域的链表称为单链表。

循环链表则是一种首尾相接的链表。

对线性表首先要掌握作为抽象数据类型(ADT)的那些基本操作,其次才是具体实现的细节。

实验要求(课题一必做,课题二选做)

实验课题一:

a、(C++语言实现):

1、使用教材参考代码中给出的线性表类构造一个表,查找表内是否有某元素,如果有则交换该元素和它相邻的下一元素的位置;

2、(2和3中选一个即可)为链表类List增加一个成员函数reverse,使其具备能倒置链表中元素的功能。

写好的表倒置函数的时间复杂度应该是Θ(n);

3、为List链表实现增加逆转迭代器类(reverseiterators),并增加方法rbegin和rend,具体要求参见教科书109页习题3.16。

b、(C语言实现)在给出参考代码中给出的线性表结构体以及与之相关的函数的基础上,编写程序,实现以下操作:

1、构造一个表,然后查找表内是否有某元素,如果有则交换该元素和它相邻的下一元素的位置;

2、写一个函数reverse,使其能倒置线性表中元素。

这个表倒置函数的时间复杂度应该是Θ(n)。

课题一的具体实验内容

1、构造元素类型为整型的线性表,将以下元素插入分别插入线性表:

<3456209155>

2、查找表中是否存在元素20,实现元素20与元素9的交换;

3、按照课题要求编写函数,实现线性表元素<3456920155>的倒置,即倒置后的表应为<5152095634>。

*实验课题二:

约瑟夫(Josephus)问题的求解(循环链表的使用,使用C和C++语言均可)。

假设有编号为1,2,……,n的n个人围坐成一圈,约定从编号为k(n>=k>=1)的人开始报数,数到m的那个人出列,他的下一个人从1开始重新报数,数到m的那个人出列,依次类推,直到所有的人全部出列为止,由此产生一个出队编号的序列。

1、给定一个8个人的圈(n=8),约定从第3个人开始报数(k=3),数到第4个人时的那个人出列(m=4),使用循环链表,产生一个出队编号的序列。

2、参考的出队序列为:

<62743518>。

实验步骤:

1、在“F:

\DataStru\”目录下面创建自己以自己学号作为名字的文件夹。

自己所有的实验程序均放在该文件夹下面。

2、创建项目,文件保存到第1步说的目录。

3、每台计算机的教材参考代码在“E:

DataStru\”,先解压至“F:

\DataStru\”。

4、通过“工具/选项/vc++目录/包含文件”把相应的F:

\DataStru\”的代码包含进去,以便编程的时候,包含相关头文件,或参考测试程序。

5、弄懂教材参考代码中给出的线性表类(c++)或线性表结构体以及与之相关的函数(c);构造一个表,进行实验要求的课题。

实验二栈

【实验目的】

1、掌握栈的LIFO(后进先出)特点和栈的存储结构;

2、熟悉栈的各种操作;

3、掌握栈的应用方法,理解栈的重要应用;

4、根据实验要求设计并完成程序,把理论的基本操作知识转化到实际的实践应用中。

【实验原理】

栈是一种特殊的线性表,这种线性表只能在固定的一端(称为栈顶(top))进行插入和删除操作。

由于只允许在栈顶进行插入和删除操作,所以栈的操作是按照“后进先出”(LastInFirstOut,缩写为LIFO)原则进行的。

本实验要求用栈作为基本的数据结构解决各实验课题。

【实验要求】(实验课题一必做,其他选做)

实验课题一:

将一个十进制数转换成另外一个P进制数字符串(可以是二进制到十六进制)。

转换函数的原型为:

voidConvert(intn,charstr[],unsignedP);

n:

输入,待转换的数

str:

输出,转换好的P进制字符串

P:

输入,要转换的进制,取值可从2到16。

如果在这范围之外,可认为输入错,不做转换。

将一个整数转换成P进制的数,我们可以采用如下的方法:

例:

十进制转换成八进制(P等于8):

(66)10=(102)8

66/8=8余2

8/8=1余0

1/8=0余1

当商为0时转换结束,转换结果为上述过程余数序列的逆序:

102。

先求得的余数在写出结果时最后写出,最后求出的余数最先写出,符合栈的LIFO性质,故可用栈来实现数制转换。

*实验课题二:

用2个栈实现一个队列,并对使用这种方法实现的队列执行入队、出队操作的时间进行分析。

用C实现的同学,应该实现教科书第76页Figure3.56(参考代码的queue.h)中定义的队列类型的那些操作函数;

用C++实现作为ADT的队列,应以以下抽象类VQueue作为与用户的界面接口:

templateclassVQueue{

public:

virtualvoidenqueue(constObject&)=0;

virtualvoiddequeue(Object&)=0;

virtualvoiddequeue()=0;

virtualconstObject&front()const=0;

virtualboolempty()const=0;

};

出队函数dequeue()有2个原型,如QueueQ;intx;x=Q.front();Q.dequeue();等价于Q.dequeue(x);前面的用法符合STL的习惯,后面一个有时会觉得方便,所以2个都放在接口里。

*实验课题三:

将一个普通代数表达式(infixexpression)转换为后缀表达式(postfixexpression)。

转换规则描述参见:

描述C语言描述的课本pp.68-71,C++语言描述的课本pp.99-102。

在本实验中,也只用+、*、(、)作为算符,优先级自低至高为+、*、()。

栈的ADT接口:

用C++描述的教科书中没给栈的ADT,可以用以下Stack类模版:

templateclassStack

{

public:

boolempty()const

{returntheList.empty();}

constObject&top()const

{returntheList.front();}

voidpush(constObject&x)

{theList.push_front(x);}

voidpop(Object&x)

{x=theList.front();theList.pop_front();}

voidpop()

{theList.pop_front();}

private:

ListtheList;

};

实验三队列

【实验目的】

1、掌握队列的FIFO的特点(先进先出)特点和队列的存储结构;

2、熟悉队列的各种操作;

3、掌握队列的应用方法,理解队列的重要应用;

4、根据实验要求设计并完成程序。

【实验原理】

队列是限定只能在表的一端进行插入,而在表的另一端进行删除的线性表。

是一种“先进先出”(FirstInFirstOut,缩写为FIFO)的线性表。

队列可以有多种实现形式,本实验要求将队列作为一个抽象数据类型(ADT)来解决各实验课题。

【实验要求】(实验课题一必做,课题二选做)

实验课题一:

回文(palindrome)是指一个字符串从前面读和从后面读都一样,仅使用若干栈和队列、栈和队列的ADT函数以及若干个int类型和char类型的变量,设计一个算法来判断一个字符串是否为回文。

假设字符串从标准输入设备一次读入一个字符,算法的输出结果为true或者false。

可以用一些字符串测试输出结果,如:

"abcdeabcde","madamimadam"等

实验课题二:

打印扬辉三角形。

1

1

1

1

2

1

1

3

3

1

1

4

6

4

1

1

5

10

10

5

1

1

6

15

20

15

6

1

1

7

21

35

35

21

7

1

打印二项式(a+b)i的展开系数,也就是扬辉三角,国外叫做Pascal'striangle。

如右下图为扬辉三角的前8行数据。

按照如右图所示的方式,完成对应杨辉三角的打印输出。

 

杨辉三角

队列的ADT接口:

用C++描述的教科书中没给队列的ADT,可以根据上次实验给出的抽象类VQueue写一个实现,也可以用以下Queue类模版:

template

classQueue

{

public:

boolempty()const

{returntheList.empty();}

constObject&front()const

{returntheList.front();}

voidenqueue(constObject&x)

{theList.push_back(x);}

voiddequeue(Object&x)

{x=theList.front();theList.pop_front();}

voiddequeue()

{theList.pop_front();}

private:

ListtheList;

};

如果要用STL的queue,可以包含头文件:

#include

要注意在STL的queue中,入队、出队函数不是用enqueue和dequeue,而是类似stack,用push和pop。

实验四树

【实验目的】

1、掌握树这种数据结构的特点和树的存储结构;

2、掌握二叉树的建立(二叉链表的建立);

3、掌握并灵活运用各种次序的遍历算法;

4、根据实验要求设计并完成程序,把理论的基本操作知识转化到实际的实践应用中。

【实验原理】

由于树的定义是递归的,对树的处理原则上也应是用递归的方式。

二叉树是一种非常重要的类型。

针对二叉树的操作主要有三种遍历(先序遍历、中序遍历、后序遍历),遍历二叉树是二叉树中各种运算的基础。

【实验要求】(实验课题一必做,课题二、三选做)

实验课题一:

将下图中的二叉树用二叉链表表示:

1用三种遍历算法遍历该二叉树,给出对应的输出结果;

2写一个函数对二叉树搜索,若给出一个结点,根据其是否属于该树,输出true或者false。

3写函数完成习题4.31(C++版)或4.28(C版教科书)。

实验课题二:

构造表达式树。

可参考教科书§4.2.2(具体规则用C++描述教材的见p.122,用C描述教材的见p.87)。

实验课题3:

哈夫曼编码的生成

当哈夫曼树生成后,对由根节点到各叶结点(对应于待编码的符号)的路径作0-1编码就得到相应的哈夫曼编码。

任何一棵满二叉树(afullbinarytree)都可以看作是一棵哈夫曼树,所以本课题要求:

造一棵满二叉树,根据这棵二叉树生成相应的哈夫曼编码。

附录:

二叉树的ADT接口

用C++描述的教科书中没有给出一个二叉树的ADT接口,我们在这里给出一个二叉树类模板,供同学们使用。

//Binarytreenodeabstractclass

templateclassBinaryNode{

public:

//Returnthenode'selement

virtualObject&val()=0;

//Setthenode'selement

virtualvoidsetVal(constObject&)=0;

//Returnthenode'sleftchild

virtualBinaryNode*left()const=0;

//Setthenode'sleftchild

virtualvoidsetLeft(BinaryNode*)=0;

//Returnthenode'srightchild

virtualBinaryNode*right()const=0;

//Setthenode'srightchild

virtualvoidsetRight(BinaryNode*)=0;

//Returntrueiffthenodeisaleaf

virtualboolisLeaf()=0;

};

//Binarytreenodeclass,animplementationoftheabstractclassBinaryNode

template

classBinNode:

publicBinaryNode{

private:

Objectit;//Thenode'svalue

BinNode*lc;//Pointertoleftchild

BinNode*rc;//Pointertorightchild

public:

//Twoconstructors--withandwithoutinitialvalues

BinNode():

lc(NULL),rc(NULL){}

BinNode(Objecte,BinNode*l=NULL,BinNode*r=NULL)

:

it(e),lc(l),rc(r){}

~BinNode(){}//Destructor

Object&val(){returnit;}

voidsetVal(constObject&e){it=e;}

inlineBinaryNode*left()const{returnlc;}

voidsetLeft(BinaryNode*b){lc=(BinNode*)b;}

inlineBinaryNode*right()const{returnrc;}

voidsetRight(BinaryNode*b){rc=(BinNode*)b;}

boolisLeaf(){return(lc==NULL)&&(rc==NULL);}

};

生成二叉树

根据不同的应用规则可以有各种生成二叉树的方法,如二叉搜索树、表达式树、哈夫曼树等。

我们在这里描述一个根据对二叉树各节点遍历所得序列生成二叉树的方法,一般从这样一个序列不一定能生成这棵二叉树。

但如果把这二叉树的所有空指针都画出来就得到一棵满的「扩充」的树,根据对这棵「扩充树」的遍历得到的序列,可以生成那棵二叉树。

例如,用'@'表示空指针,那么课题一图中那棵「扩充」二叉树的先序遍历得到的节点序列是:

char*extendedPreOrd="ABD@F@@EG@@H@@C@@";

用它做为下列二叉树建造函数的输入就得到前图所示的树。

BinNode*BinTreeBuildFrmStr(char*&str)

{

if(*str!

='@'){

BinNode*root=newBinNode(*str++);

root->setLeft(BinTreeBuildFrmStr(str));

root->setRight(BinTreeBuildFrmStr(str));

returnroot;

}

else{//theNULLpointer'@',justskipit

str++;

returnNULL;

}

}

注:

把这个函数的参数类型由对二叉树节点指针的引用改为指向指针的指针,很容易把它改为C的函数。

二叉树的打印

与教科书上的二叉树图相比,这里打出的数向左旋转了90度。

当然了,这里还是递归。

改成C函数也很容易。

template

voidprintTree(BinaryNode*subroot,intdepth=0){

if(subroot==NULL)return;//Emptytree

printTree(subroot->right(),depth+1);//Dorightsubtree

for(inti=0;i

cout<<"";

cout<val()<

printTree(subroot->

展开阅读全文
相关搜索

当前位置:首页 > 高等教育 > 医学

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

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