据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx

上传人:b****7 文档编号:22248174 上传时间:2023-02-03 格式:DOCX 页数:16 大小:80.89KB
下载 相关 举报
据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx_第1页
第1页 / 共16页
据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx_第2页
第2页 / 共16页
据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx_第3页
第3页 / 共16页
据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx_第4页
第4页 / 共16页
据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx

《据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx(16页珍藏版)》请在冰豆网上搜索。

据结构与算法大平台试验指导书上海交通大学Word文档下载推荐.docx

x=x+1;

注释为x加1,没有什么意义),都应加以注释。

这会对程序的调试提供很多方便。

另外,根据情况可以设立若干调试点,即输出若干信息,用于验证和你的设想是否一致。

另外,对于输入输出语句,必须对它们的作用加以说明。

否则,在调试程序时,无法了解系统需要输入什么,系统输出的又是什么。

程序的书写,必须按照一定的规范,如保留字小写时涂黑等等。

3.上机准备和静态检查

上机准备:

●高级语言文本

●熟悉机器的用户手册,熟悉常用的命令。

●准备调试的工具,考虑调试方案。

如果机器上没有现成的调试工具可供利用,可以自己先设计一些以供使用。

●静态检查

自己用一组数据手动执行程序;

或同同学一起阅读自己的程序,以全面地了解该程序的逻辑。

4.上机调试程序

自底向上,先调试底层模块,再调试上层模块。

最后,整个程序进行联调。

调试正确后将源程序和运行结果加以列印输出。

5.实习报告的整理

●需求及规格说明

问题描述,求解的问题是什么。

●设计:

设计思想:

存储结构、主要的算法思想。

设计表示:

子程序(过程或函数)的规格说明,通过调用关系图表示它们之间的调用关系。

实现注释:

详细设计表示:

主要算法的框架。

●用户手册:

使用说明。

●调试报告:

问题是如何解决的,讨论与分析、改进设想、经验与体会、时空复杂度等。

●附录

源程序清单和结果:

源程序必须有注释,以及必要的测试数据和运行结果数据。

提倡用英文描述。

●实验报告要求:

在程序开发过程中,逐步形成各种必要的文档及资料。

可以写在实验报告纸上,或以电子文档的形式进行书写。

2.上机实习

●以下的实习题目配合课程的进度,请同学们务必自己完成。

为了锻炼自己的应用各种不同的数据结构的能力,尽可能的多作一些题目是非常必要的。

在完成各种不同题目的过程中,对各种算法的时、空复杂性的分析,将帮助您在更高的角度解决各种应用问题。

●为了减轻同学的负担,我们对同学的实习报告进行了精简。

本实习报告中的题目分以下几种类型:

1、实习题:

必须按照实习报告的规范完成。

每个实习的第一题都是实习题,必须编写详细的实习报告。

实习报告的书写方法,请参阅本指导书的第3部分:

实习报告的样例。

2、作业题:

同样必须完成。

只需交代清楚题目的解法,辅以求解程序和注释,使得别人能够看懂你的算法和程序即可。

不必象实习题那样书写完整的实习报告。

3、选作题:

鼓励同学选作的题目,尤其是学有余力的同学。

以下为各次实习作业:

实习一线性结构

1、(实习题)请写出计算两个以单链接表表示的多项式相乘的程序。

2、(作业题)已知两个单链表A和B分别表示两个集合,其元素递增排列。

请编写程序求集合A和B的交集C=AB,要求单链表C按其元素递增排列,并利用原表(即表A和表B)的结点空间存放表C。

3、(作业题)假设有二个栈共同使用一块顺序存储的空间,为简单起见可设为共同使用数组inta〔200〕。

它们的栈底分别设在数组的两端,而栈顶指针在进行插入操作时,向中间方向移动。

请给出进出栈的程序。

4、(选作题)将具有头结点的单链表的所有指针全部进行倒向。

要求使用的额外空间只能为O

(1),时间代价只能为O(n),其中n为结点个数。

注意:

如下图1所示的单链表,倒向之后将如图2所示。

图1、倒向之前的单链表

图2、倒向之后的单链表

1、(实习题)请编写一个程序,确定二叉树的特征。

如:

每个节点的层次,从根到该节点的枝长(路径长度),子孙的个数及祖先的个数。

每个节点在前序、中序、后序中的访问的序号。

2、(作业题)设二叉树的结点的数据场之值仅为一大写英文字母。

其前序和中序的遍历结果(打印结点的数据场之值)分别保存在字符串数组preorder[N]及inorder[N]之中,其中N未常数。

请设计程序以标准形式形式存储保存该二叉树。

3、(作业题)设树的根结点的层号为1,而其他各层上的结点的层号比其父结点的层号大1。

另外设该树中的结点的数据场之值为正整数。

这样数对(Ik,Wk)就表示了该树中的结点的层号和其数据场之值。

从键盘上依次输入m个数对,如:

(I1,W1),(I2,W2),……,(Im,Wm);

这些数对是按照结点的前序序列给出的。

注意这是用层号+前序表示一棵树的方法。

(1,A),(2,B),(2,C),(3,E),(4,G),(3,F),(2,D),(3,X),(3,Y),(3,Z);

它所表示的树如图3所示。

请编写程序,以标准形式存储这棵树。

为了简单起见,可设这棵树上的结点的度数最大为3,结点的存储形式为:

dataparentson1son2son3

其中:

data域为结点的数据场,parent域为结点的父亲结点的地址,son1,son2,son3分别给出结点的三个儿子的地址。

图3、一课三次树

4、(选作题)用标准形式给出了一棵度为三的树(每个结点包含数据场、指向儿子节点的指针场,可参阅上题)。

设该三次树的数据场的值为一个字符,请编写一个程序,以树的两维形式表示打印节点的值。

图3即为树的二维表示形式。

在实现时,为了方便可用打点的方法代替直线。

1、(实习题)从键盘上输入一串正整数,最后输入-1作为输入结束的标志。

如输入的序列为:

2,5,7,23,48,96,……,-1。

请以这些正整数的值作为二叉排序树中的结点的数据场之值,建立一棵二叉排序树。

注意:

请采用动态存储方法保存这棵二叉排序树,事先并未知道该二叉排序树中的结点的个数。

2、(作业题)已知一棵排序二叉树,树中结点的形式为:

datainfoleftright

其中,data给出结点的数据场,info给出本结点的左子树中的结点总数,left和right分别给出本结点的左儿子和右儿子的地址。

数据场data和info的类型皆为int。

又已知该二叉排序树的根结点的地址为root。

请设计二个函数,分别实现下述功能:

1.按递增序找出该二叉排序树中的第i个小的结点。

2.插入数据场之值为x的结点,并仍应保持该二叉排序树的性质不

变。

3、(作业题)已知一棵二叉排序树,其根结点的地址为root。

请编写一个程序,构造出一棵具有相同结点的完全二叉树,且它同样是二叉排序树。

4、(选作题)在平衡的排序二叉树的中,试编写删除具有给定关键字的结点的函数。

实习四图

1、(实习题)以数偶的形式依次从键盘上输入一串数据。

(A,B)为从起始结点(其数据场之值为一大写的英文字母A),到终止结点(其数据场之值为一大写的英文字母B)的无向边。

最后输入(Z,Z)表示输入结束。

请用无向图的邻接多重表存储该无向图,并注意一定要使用动态存储结构。

2、(作业题)已知一以动态存储结构形式存储的,以邻接多重表表示的无向图。

请用KRUSKAL算法求出它的最小代价生成树。

3、(作业题)已知一以邻接矩阵形式存储的AOV图。

请求出它的所有的合理的拓扑排序的序列。

4、(选作题)已知一以动态存储结构形式存储的,以邻接表表示的有向图。

请求出它的强连通分量。

3、实习报告样例

一、实习题:

约瑟夫(Josephus)问题:

设有n个人围成一个圆圈,任意给定一个正整数m,从第一个人开始顺时针计数,计到第m个人,将其从圆圈中除去。

然后再从下一个人开始,周而复始,直到圆圈中只剩一个人为止,那么剩下的那个人就是赢家。

1.需求分析和说明

分析约瑟夫问题:

n个人围成圈,从第一个人开始,数到第m个人,删除并以下一个

人开始进行第二轮操作,直到最后一个人作为优胜者。

例如n=6,m=3,处理过程下图。

2.设计

n个人围圈,形成线性关系;

处理为逐个删除,故用链式结构合适;

又人员围成圆圈,所以此链式结构采用循环方式较好;

排号按照一个方向进行,故数据结构采用带头结点的单向循环链表。

假设人员以首次的编号命名,对每个人员采用编号和姓名加以描述。

存储结构:

structperson{//定义人员信息,包括序号和姓名

intno;

charname[10];

};

//circlinklist.h

单向循环链表类

template<

classElemType>

classCircLinkList{

CircLinkListNode<

ElemType>

*head,*tail;

//指向表头结头和尾结点

*currPtr;

//指向当前工作结点

*prevPtr;

//指向当前工作结点的前一结点intsize;

//表中元素的个数

intposition;

//表中当前元素所在的元素序号(位置)

public:

CircLinkList();

//构造函数

~CircLinkList();

//析构函数

voidClear();

//链表置空

intLength()const{returnsize;

};

//求链表长度

boolIsEmpty()const{return(size==0);

//判断链表是否空

boolIsEnd()const{return(currPtr=tail);

//当前结点是否是尾结点

intCurrentPosition()const{returnposition;

//返回当前结点的序号

ElemTypeData()const;

//返回当前指针所指的结点中的元素值

voidGoNext();

//将当前指针指向当前结点后面的一个结点

voidReset(intpos);

//将当前指针指向序号为pos的结点

*Find(ElemTypee);

//查找从当前结点起第一个元素值为e的结点

//各种位置上的插入操作

voidInsertFront(constElemTypee);

//在首结点位置上插入元素值为e的新结点

voidInsertTail(constElemTypee);

//在尾结点之后插入元素值为e的新结点,使其成为新的尾结点

voidInsertAt(constElemTypee);

//在当前结点位置上插入元素值为e的新结点,

//原来的当前结点成为其后一个结点

voidInsertAfter(constElemTypee);

//在当前结点之后插入元素值为e的新结点

ElemTypeRemoveFront();

//删除首结点,并返回其元素值

ElemTypeRemoveAt();

//删除当前结点,并返回其元素值

算法思想:

声明一个person类型的单向循环链表。

从键盘顺序输入n个人的姓名,建立约瑟夫环。

计数并逐个读取并删除第m个人,直到链表为空,其中最后一个被读出的即优胜者。

调用关系:

程序任务简单,故设计在一个main()函数内,只设计类成员函数的调用,无另外的子程序或函数。

算法实现框架:

3.用户手册:

运行程序,按照屏幕提示分别输入圈内人数n,正整数m和n个人的姓名,之后屏幕将显示按照输入次序排好的人员被逐个删除的次序,最后显示最后的出优胜者。

4.调试报告:

时间复杂度分析:

该算法在建立时的时间复杂度为O(n),删除时时间耗费在逐个数元素上,按照第m个删除的原则,不妨将n个元素分成若干组,每组m个人,n个人最多分n/m+1组。

扩展

最后一组,使其也是m个人,对组内元素从1到m排号,每组排号为m的只数到一次便被删除;

第二圈数每组排号为1的被删除,每个元素数过2次;

第三圈数每组排号为2的被删除,每个元素数过3次;

最后,第m圈,每组排号为m-1的被删除,每个元素数过m次;

故总删除总的时间为:

(n/m+1)(1+2+3+…+m)=m(m+1)(n/m+1)/2,时间

复杂度为:

O(n*m);

缩小最后一组,使其是0个人,同上可得删除总的时间为:

(n/m)(1+2+3+…+m)=m(m+1)(n/m)/2,时间复杂度也为:

综合建立和删除,算法时间复杂度为:

O(n*m)

算法改进思路:

在对元素数数删除过程中,总是要去判断是否是头结点并绕过它,可以改进一下,去掉头结点,由此看来,并非链式结构带有头结点都有益处。

改进后性能可以提高,但时间复杂度依然为:

5.附录

源程序清单

//josephusRing.cpp

#include<

iostream.h>

#include"

circlinklist.h"

intno;

charname[10];

voidmain(){

CircLinkList<

person>

josephusRing;

//声称一个单向循环链表类对象

persontemp;

inti;

intn,m;

//共有n个人,计数到m删除

//从键盘输入总人数n

cout<

<

"

Inputthenumberofpeople:

;

cin>

>

n;

endl;

//从键盘输入计数标准m

Inputcountnumber:

m;

//顺序输入n个人的姓名,建立约瑟夫环

Inputeveryperson'

sname:

for(i=1;

i<

=n;

i++)

{cin>

temp.name;

//输入姓名

temp.no=i;

//将输入次序作为人员编号

josephusRing.InsertTail(temp);

//将新来人员信息加入到链表尾部

}

//计数并逐个删除第m个人,直到链表为空

josephusRing.Reset

(1);

//当前结点设置为首结点

i=0;

cout<

Deletedorder:

"

while(!

josephusRing.IsEmpty()){//以链表为空作为结束条件

josephusRing.GoNext();

//将当前结点设置为当前结点的下一个结点

if(josephusRing.CurrentPosition()!

=0)i++;

//如果当前结点不是头结点,计数值加1,否则跳过头结点,计数值不变

if(i==m){//如果计数到m,要删除当前结点

temp=josephusRing.RemoveAt();

//删除当前结点,当前结点顺其next指针变为下一个结点

cout<

temp.no<

temp.name<

//将删除的结点中的值在屏幕输出

//如果当前结点非头结点,已经进入下一轮计数,计数器值设置为1

//如果当前结点为头结点,还未进入下一轮计数,计数器值设置为0

if(josephusRing.CurrentPosition()!

=0)

i=1;

elsei=0;

}

Thewinneris:

//返回优胜者姓名

}

测试数据:

6个人,非别为Ann、Bill、Cherry、David、Elan、Fred,每次删除第3个人,预计运行结果为:

逐次删除Cherry、Fred、David、Bill、Elan、Ann,赢者为:

Ann

测试及运行结果:

6

3

Bill

Cherry

David

Elan

Fred

3Cherry

6Fred

4David

2Bill

5Elan

1Ann

Ann

运行结果分析:

运行结果符合预定目标

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

当前位置:首页 > 法律文书 > 判决书

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

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