《数据结构》实验指导书文档格式.docx
- 文档编号:21706213
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:18
- 大小:48.91KB
《数据结构》实验指导书文档格式.docx
《《数据结构》实验指导书文档格式.docx》由会员分享,可在线阅读,更多相关《《数据结构》实验指导书文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
2)问题改进:
在人数n、k及起始报数人确定的情况下,最后剩下的人的编号事前是可以确定的。
若每人有一个密码Ki(整数),留作其出圈后的报到Ki后出圈。
密码Ki可用随机数产生。
这样事前无法确定谁是最后一人。
【选做内容】
1)约瑟夫问题的改进算法。
2)约瑟夫问题的报数方法若采用顺时针报数和逆时针报数交替进行,则如何设计数据结构?
【实现提示】
//结点结构和单循环链表类定义
enumResultCode{Error,NoMemory,OutOfBounds,Underflow,Overflow};
template<
classT>
structNode
{Node(){link=NULL;
}
Node(Te,Node*next)
{data=e;
link=next;
}
Tdata;
Node*link;
};
classLinkList
{private:
intn;
//表长
Node<
T>
*current,*front;
public:
LinkList(intmSize);
//构造函数,不带表头结点单循环链表
~LinkList();
//析构函数
TRemoveCurrent();
//删除操作
voidmovenext(intn);
//current后移n次
intCurrentPassword(){returncurrent->
password;
TCurrentData(){returncurrent->
data;
voidtoLocatioin(T&
t);
//将current指向元素为t的结点
voidOutput()const;
//输出链表
//ClassLinkList
//单循环链表类部分成员函数实现
LinkList<
:
LinkList(intmSize)//构造函数
{inti;
Node<
*p;
current=newNode<
;
current->
data=n=mSize;
front=current;
for(i=mSize-1;
i>
0;
i--)
{p=newNode<
(i,current);
current=p;
front->
link=current;
}
//Joseph类定义
classJoseph
intnumOfBoy;
intstartPosition;
intInterval;
Joseph(intboys=10,intstart=1,intm=3)
{
numOfBoy=boys;
startPosition=start;
Interval=m;
}
voidGetWinner();
//Joseph类
//Joseph类实现
voidJoseph<
GetWinner()
{
LinkList<
boys(numOfBoy);
boys.movenext(startPosition-1);
//?
?
boys.Output();
cout<
<
endl<
"
依次出列的小孩是:
endl;
for(inti=1;
i<
numOfBoy;
i++)
{
boys.movenext(interval-1);
cout<
boys.RemoveCurrent()<
"
\nThewinneris"
boys.CurrentData()<
//主函数main
voidmain()
{try
{time_ttime1=time(NULL);
structtm*t;
t=localtime(&
time1);
srand(t->
tm_sec*t->
tm_min+t->
tm_hour);
请输入初始数据:
小孩数,间隔数,起始小孩号码:
\n"
inttotal,interv,startboy;
cin>
>
total>
interv>
startboy;
Joseph<
int>
jose(total,startboy,interv);
jose.GetWinner();
catch(enumResultCodeerr)
{switch(err)
caseError:
cout<
LocationError!
caseDeleteError:
DeleteError!
内容3:
多项式的表示和相加
建立链式多项式类,并设计算法实现多项式的相加。
【要求】
1)设计多项式链表类并实现。
2)相加后可将原多项式销毁,也可以保留。
【选做内容】多项式的减法、乘法及除法运算。
【问题思考】
建立的链表不带头结点与带头结点,则在操作实现上有何差异?
实验2栈和队列及其应用
1.加深理解栈和队列的特性;
2.能根据实际问题的需要灵活运用栈和队列;
3.了解递归算法的设计;
4.掌握栈和队列的应用方法。
设计算术表达式求值类
表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。
设计一个表达式类程序,演示用算符优先法算术表达式求值的过程。
【基本要求】
以字符序列的形式输入语法正确且不含变量的整数表达式。
利用教材中给出的算符优先关系表,实现对算术四则混合运算表达式的求值。
(1)表达式类说明:
classexpression
private:
char*str;
doubleresult;
intprior(char,char);
//比较运算符优先级0-相等,1-大于,-1-小于
doublevalue(charop,doublea,doubleb);
//a和b进行op运算
expression(char*ss);
//构造函数
~expression(){delete[]str;
}//构造函数
voiddel_blank();
//删除串str中所有空格
voidcalculate();
//对表达式串str进行计算
doublegetResult()const{returnresult;
}//获取表达式的值
//classexpression
char*s;
doubleresult
expression(char*str);
voiddel_blank();
intprior(char,char);
//比较运算符优先级0—相等,1—大于,-1—小于
doublevalue(charop,doublea,doubleb);
voidcalculate()//对表达式串str进行计算
voidOutput()const;
//输出计算结果
(2)顺序栈类说明
classSeqStack//线性表抽象类
private:
T*s;
//存储栈空间的首地址
inttop;
//栈顶指针
intmaxsize;
//栈空间总规模
public:
SeqStack(intmSize);
~SeqStack(){delete[]s;
voidPush(constT&
x);
//入栈
voidPop();
//出栈
TTop()const;
//访问栈顶元素
boolIsEmpty()const;
//判空
boolIsFull()const;
//判满
(3)设置运算符栈和运算数栈算符优先辅助分析算符优先关系。
(4)在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,以及相应的运算。
参考算法如下:
voidexpression:
calculate()
{SeqStack<
double>
opnd(100);
//opnd为运算数栈
doublea,b;
SeqStack<
char>
optr(100);
//optr为运算符栈
charoperate;
optr.Push('
#'
);
char*s=str;
intk=strlen(s);
s[k]='
//在表达式尾部加结束标志
s[k+1]='
\0'
while(*s!
='
||optr.Top()!
)//当前字符为'
且栈顶也是'
,则计算完毕
if(*s>
0'
&
*s<
9'
)//当前字符为运算对象
opnd.Push(*s-'
s++;
continue;
while(prior(optr.Top(),*s)==1)//当前运算符优先级低于与栈顶运算符
operate=optr.Top();
optr.Pop();
b=opnd.Top();
opnd.Pop();
a=opnd.Top();
opnd.Push(value(operate,a,b));
//计算,结果入opnd栈
if(*s=='
)'
optr.Top()=='
('
)//左右括号配对
if(prior(optr.Top(),*s)==0)//当前运算符优先级高则入optr栈
optr.Push(*s);
result=opnd.Top();
//当前opnd栈顶元素为表达式的值
intprior(chart,charc)
{//计算t和c的优先级
switch(t)
{case'
+'
case'
-'
if(c=='
||c=='
)return1;
//t>
c
elsereturn0;
//t<
*'
/'
)return0;
elsereturn1;
)return-1;
//相等
elsereturn0;
if(c=='
return-2;
//无此运算符
}//prior
(3)在识别出运算数的同时,实现将数字字符转换成整数形式。
(4)在程序的适当位置输出运算符栈、运算数栈、输入字符和主要操作的内容。
(5)算法的原理见教材。
(1)扩充运算符集。
如乘方、赋值等运算。
(2)运算分量可以是变量。
(3)运算分量可以是多位整数或实数类型。
(4)计算器的功能和仿真界面。
航空客运订票系统
航空客运订票的业务活动包括:
查询航线、客票预订和办理退票等。
试设计一个航空客运订票系统,完成上述功能。
(1)每条航线信息:
终点站名、航班号、飞机号、飞行周日(星期几)、乘员定额、余票量、已定票的客户名单(包括姓名、定票量、舱位等级1,2或3)以及等候替补的客户名单。
(2)作为模拟系统,全部数据可以只放在内存中。
(3)系统功能:
查询航线、客票预订和办理退票
(1)已定票的客户名单可采用线性表及其链表结构存储,等候替补的客户名单可采用队列。
(2)系统每条航线信息可采用线性表及其顺序结构存储。
(3)每条航线信息结构:
包括以上8个成员信息,其中已定票的客户名单成员为已定票的客户名单链表的头指针,等候替补的客户名单成员为分别指向队头和队尾的指针。
回文判断问题
顺读与逆读字符串一样(不含空格)。
(1)回文判断借助于栈来实现。
(2)对字符串中的空格要忽略,即不进行判断,当然也可以先对原串进行处理,去掉所有空格字符,再进行判断。
(1)回文判断借助的栈可采用链栈方式。
(3)算法原理:
1.读入字符串
2.去掉空格(原串)
3.压入栈
4.原串字符与出栈字符依次比较
若不等,非回文
若直到栈空都相等,回文
实验3
二叉树及其应用
1.加深对二叉树的结构特性的理解;
2.熟练掌握二叉树的存储结构,特别是二叉链表类的描述及其实现方法;
3.熟练掌握二叉树的遍历算法原理及实现;
4.学会编写实现二叉树的各种算法;
5.掌握二叉树的应用方法。
二叉树及其操作
设计二叉树的二叉链表类,操作主要有建二叉树、遍历二叉树、求该二叉树中、的结点个数等。
(1)建立二叉树可用先序方式建立,也可根据二叉树的先序和中序序列建立。
(2)对二叉树的遍历可采用递归或非递归的算法。
(1)二叉链表的结点结构描述
structbtnode{//定义结点类型
ElemTypedata;
//数据域
btnode*lchild,*rchild;
//左、右指针域/
//btnode
(2)可设计以下功能函数:
btnode*createbitree();
//建立二叉链表
voidpreorder(btnode*bt);
//先序遍历二叉树
intsum(btnode*bt);
//求二叉树中的结点个数
算法可用递归或非递归实现。
建立二叉树可用以下两种算法实现:
方案1:
btnode*createBT()//前序建树
{bitreeT;
charch;
cin>
ch;
if(ch==’#’)returnNULL;
//二叉树为空
T=newBinTNode;
//申请根结点
T->
data=ch;
lchild=createBTpre();
//创建根的左子树
rchild=createBTpre();
//创建根的右子树
returnT;
方案2:
btnode*createBT(char*preorder,char*midorder)
{//由前序preorder和中序midorder建树,返回根指针
if(strlen(preorder)==0)returnNULL;
//空二叉树
T=newNode;
//建立根结点
data=*preorder;
k=locate(midorder,*preorder);
//找根在中序中的位置
lmidorder=fetch(midorder,0,k);
//左子树的中序
lpreorder=fetch(preorder,1,k);
//左子树的前序
rmidorder=fetch(midorder,k+1);
//右子树的中序
rpreorder=fetch(preorder,k+1);
//右子树的前序
lchild=createBT(lmidorder,lpreorder);
//建根的左子树
rchild=createBT(rmidorder,rpreorder);
//建根的右子树
intsum(btnode*bt)//求二叉树中的结点个数
{if(!
bt)return0;
returnsum(bt->
lchild)+sum(bt->
rchild)+1;
(1)对二叉树进行层次遍历算法。
(2)求二叉树的深度、宽度等操作。
(3)复制二叉树,交换二叉树中左右子树的问题怎么实现?
哈夫曼编码/译码器
【问题描述】设字符集为26个英文字母,其出现频度如下表所示。
先建哈夫曼树,再利用此树对报文“Thisprogramismyfavorite”进行编码和译码。
算法具有以下功能:
(1)CreateHuffmanTree:
根据给定字符的出现频数,建立其哈夫曼树。
(2)Encoding:
对给定的原字符串进行编码。
(3)Decoding:
对给定的编码串进行译码(或解码)。
(4)ShowHuffmanTree:
显示哈夫曼树
(1)用户界面可设计成模拟菜单方式。
(2)原字符串及编码串可从键盘输入。
(3)生成Huffman树的步骤如下:
①由给定的n个权值{w1,w2,…,wn}构成n棵二叉树的集合(即森林)F={T1,T2,…,Tn},其中每棵二叉树Ti中只有一个带权为wi的根结点,其左右子树均空。
②在F中选取两棵根结点的权值最小的树做为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左右子树上根结点的权值之和。
③在F中删去这两棵树,同时将新得到的二叉树加入F中。
④重复②和③,直到F只含一棵树为止。
这棵树便是赫夫曼树。
(1)字符的出现频数能否从指定文件中统计而得?
(2)对指定的文件进行编码/解码。
实验4
图及其应用
1.加深对图的结构的理解;
2.熟练掌握图的存储结构,特别是图的邻接表结构;
3.熟练掌握图的搜索算法原理及其实现;
4.掌握图的常用的应用方法。
图的搜索问题
设计无向图的邻接表类并实现,演示在连通的无向图上访问全部结点的操作。
(1)以邻接表作为存储结构,并对图进行深度优先和广度优先搜索。
(2)以指定结点为起点,分别输出每种搜索方式下结点访问序列和相应生成树边集。
(1)图的每个结点用一个编号表示(如1~n)。
通过输入图的全部边来输入一个图,每个边是一个数对。
(2)数据结构描述见教材。
(3)无向图的邻接表类的主要成员函数:
voidcreateadjlist();
//建立图的邻接表
voiddesttraverse(intk);
//图的深度优先搜索
voidbesttraverse(intk);
//图的广度优先搜索
借助栈,用非递归算法实现深度优先搜索。
教学计划编制问题
教学计划中各课程之间必须满足先修关系。
每门课程的先修课程是确定的,可以有任意多门,也可以没有。
试在这样的前提下设计一个教学计划编制的程序。
(1)输入数据:
学期总数、一学期学分上限、课程号、课程学分和先修课程课程号。
(2)编排策略:
使每学期的总学分数尽量均匀。
可设学期总数不超过12,课程总数不超过100。
产生多种不同的方案,并使方案之间的差异尽可能大。
实验5
查找
1.熟练掌握顺序表和有序表的查找方法及算法实现。
2.熟悉常用查找算法的编写。
3.理解静态查找和折半查找的关系。
4.熟练掌握二叉排序树的构造和查找方法。
5.通过上机操作,理解如何科学地组织信息存储,并选择高效的查找算法。
建议2学时
基本查找算法
设计一个程序,演示折半查找和二叉排序树查找过程。
(1)建立一棵二叉排序树,采用二叉链表存储结构,并进行查找。
(2)给出一组有
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 指导书