《数据结构与算法》课程设计.docx

上传人:b****3 文档编号:4871224 上传时间:2022-12-11 格式:DOCX 页数:42 大小:218.23KB
下载 相关 举报
《数据结构与算法》课程设计.docx_第1页
第1页 / 共42页
《数据结构与算法》课程设计.docx_第2页
第2页 / 共42页
《数据结构与算法》课程设计.docx_第3页
第3页 / 共42页
《数据结构与算法》课程设计.docx_第4页
第4页 / 共42页
《数据结构与算法》课程设计.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

《数据结构与算法》课程设计.docx

《《数据结构与算法》课程设计.docx》由会员分享,可在线阅读,更多相关《《数据结构与算法》课程设计.docx(42页珍藏版)》请在冰豆网上搜索。

《数据结构与算法》课程设计.docx

《数据结构与算法》课程设计

《数据结构与算法》课程设计

实习一

需求规格说明

1、单链表的输出

要求:

使用“递归”算法实现单链表中数据的顺序和逆序输出,但不允许引入额外的空间复杂度。

总体分析与设计

利用链表的存储结构,并采用递归的思想;

主函数

voidOpSeqOutput(intn)

voidSeqOutput()

利用主函数调用voidOpSeqOutput(intn)和voidSeqOutput()实现数序列逆序和顺序输出;

编码

voidSeqOutput()

利用递归的方法,输出头结点后,删除该节点;

voidOpSeqOutput(intn)

利用递归的方法,为尾节点计数,并依次逆序输出;

程序及算法分析

输入n个数进行测试,输出结果:

Listis:

549874567896864567539876542642982543

2154987456789686456753987654264298254321

54987456789686456753987654264298254321

Listsequencereverseoutput:

1234528924624567893576546869876547894512

3452892462456789357654686987654789451234

5289246245678935765468698765478945

Listsequenceoutput:

5498745678968645675398765426429825432154

9874567896864567539876542642982543215498

7456789686456753987654264298254321

请按任意键继续...

采用递归的方法,如果数序列较大,则时间复杂度较大;

小结

利用递归的方法空间复杂度较小;

附录

voidChain:

:

SeqOutput()

{

ChainNode*current=first;

if(current)

{

inti=0;

Tx;

cout<data<<"";

i++;

Delete(i,x);

SeqOutput();

}

else

cout<

/*cout<<"Listsequencesequenceoutputover!

"<

}

//逆序输出

template

voidChain:

:

OpSeqOutput(intn)

{

ChainNode*current=first;

ChainNode*trail;

if(first&&n>0)

{

for(inti=0;current&&i

{

trail=current;

current=current->link;

}

cout<data<<"";

OpSeqOutput(n-1);

}

/*cout<<"Listsequencereverseoutputover!

"<

}

实习二

需求规格说明

2、二值图像的像元分组

算法简介:

二值图像中每个元素的值只能为1或0,其中1表示有效像元,0表示图像的背景。

如果一个元素在另外一个元素的上、下、左、右四个方向,称两个元素为相邻元素。

“像元分组”算法是将二值图像中处于相邻的元素进行分组标号,使得属于同一个分组的像元集合,其编号都相同。

如下图所示:

1

1

0

0

0

0

1

1

0

0

0

0

0

0

0

1

0

0

0

0

1

1

0

1

0

0

1

0

0

1

0

0

0

0

0

1

1

1

0

0

0

0

1

1

0

0

0

0

0

0

0

2

0

0

0

0

2

2

0

3

0

0

2

0

0

3

0

0

0

0

0

3

分组前分组后

要求:

使用“队列”来实现二值图像的像元分组,图像数据采用TXT文件形式给出,把分组结果图像输出到另外一个文件

总体分析与设计

利用队列的存储结构;

数字化图像是一个m*n的像素矩阵。

识别图元就是对元像素进行标记,当且仅当两个像素属于同一图元时,它们的标号相同;

在识别图元的过程中,图像的周围包上一圈空白像素(即0像素);采用数组0offset来确定与一个给定像素相邻的像素。

通过逐行扫描像素来识别图元。

当遇到一个没有标号的图元的像素时,就给它指定一个图元编号(使用数字2、3、等为图元编号),该像素就为一个新图元种子,通过识别和标记与种子相邻的所有图元像素,可以确定图元中的其它像素。

编码

先在图像外围包上一圈背景像素,并对offset进行初始化,接下来的两个for循环通过扫描图像寻找下一个图元的种子。

再图元标号设置为种子标号,接下来借助于链表队列的帮助,可以识别出该图元的其余像素。

程序及算法分析

10

9

111100000000000000

000000111000000222

000000000000000000

001111100003333300

000011100000033300

110000000040000000

000001110000005550

011100000066600000

000001000000007000

000111010000777080

对于任一个图元来说,识别标记该图元的的每个像素(种子除外)所需时间为O(cnum),识别并标记所有非种子图元像素所需要的总时间为O(m2)。

小结

其存储方式可以用公式化队列,链表堆栈,或公式化堆栈。

附录

#include"stdafx.h"

#include"Disgra.h"

#include

#include

 

usingnamespacestd;

#definemax40

int_tmain(intargc,_TCHAR*argv[])

{

ifstreamf1("data.txt",ios:

:

_Nocreate);

DisgraD;//创建Disgra的对象D

D.pixel;

introws(0),cols(0);

f1>>rows>>cols;//读入行数和列数

intn(0);

for(inti=0;i

{

for(intj=0;j

{

f1>>n;//读入像元数据,并存入pixel[][]数组

D.pixel[i][j]=n;

}

}

f1.close();

D.Lable(rows,cols);//调用函数Lable

ofstreamf2("data2.txt",ios:

:

out);

intl(0);//计数

for(inti=0;i

{

for(intj=0;j

{

l++;

f2<

if(l==9)

{

f2<

l=0;

}

}

}

f2.close();

return0;

}

#ifndefDisgra_

#defineDisgra_

 

#include"positoin.h"

#include"lqueue.h"

#defineMAXSIZE50

structDisgra

{

intpixel[MAXSIZE][MAXSIZE];//存储数据的二维数组

voidLable(introws,intcols);//标记函数

};

voidDisgra:

:

Lable(introws,intcols)

{

/*intpixel[MAXSIZE][MAXSIZE];*/

/*introws(0),cols(0);*/

for(inti=0;i<=cols;i++)

pixel[0][i]=pixel[rows+1][i]=0;

for(inti=0;i

pixel[i][0]=pixel[i][cols+1]=0;

Positionoffset[4];

offset[0].row=0;offset[0].col=1;

offset[1].row=1;offset[1].col=0;

offset[2].row=0;offset[2].col=-1;

offset[3].row=-1;offset[3].col=0;

intNumOfNbrs=4;

LinkedQueueQ;

intid=1;

Positionhere,nbr;

for(intr=1;r<=rows;r++)

for(intc=1;c<=cols;c++)

if(pixel[r][c]==1)

{

pixel[r][c]=++id;

here.row=r;here.col=c;

do{

for(inti=0;i

{

nbr.row=here.row+offset[i].row;

nbr.col=here.col+offset[i].col;

if(pixel[nbr.row][nbr.col]==1)

{

pixel[nbr.row][nbr.col]=id;

Q.Add(nbr);

}

}

if(Q.IsEmpty())break;

Q.Delete(here);

}while(true);

}

}

#endif

                实习三

需求规格说明

3、课程安排问题

一套好的课程体系有如下要求:

各个课程之间有着严格的先后顺序关系;两个相邻课程之间的跨度为一个时间段(具体就是一个学期)。

课程安排问题,是为了验证专业课程安排方案是否合理,并提供多种选课方案供学生进行选择。

现有软件工程专业课程表(采用TXT文件格式),格式如下:

课程代号课程名称先修课程代号

11049高等代数C

25003计算机高级语言

22222计算机导论

33333计算机结构与组成25003,22222

……

要求:

使用“拓扑排序”算法,设计一个程序:

(1)验证软件工程专业课程表是否合理?

若不合理,指出并修改不合理的课程安排,产生新的软件工程专业课程表;

(2)对软件工程专业课程表,输出多种选课方案,以供学生进行选择。

总体分析与设计

利用图和栈存储结构;并利用贪婪算法来求解问题;

有向图的顶点代表任务,有向边(i,j)表示先后关系,任务j开始前任务i必须完成。

利用数组v来描述课程,用一个栈来保存可加入V的候选点,并用一维数组InDegree,InDegree[j]表示与顶点i相连的节点数目,其中顶点i不是V中的成员,它们之间有向图得边为(i,j),当InDegree[j]变为0时,表示j成为一个候选点。

序列v初始时为空。

InDegree[j]为顶点j的入度。

每次向v中加入一个顶点时,所有与新加入顶点临接的顶点j,其InDegree[j]减1.

主函数

boolTopological(intv[])

            

S.Add(i)

Begin(w)

S.Delete(w)

NextVertex(w)

编码

每一步,从栈中去出一个顶点将其加入v,同时减去与其邻接的顶点的InDegree值。

程序及算法分析

测试数据:

课程代号课程名称先修课程代号

11049高等代数C

25003计算机高级语言

22222计算机导论

33333计算机结构与组成25003,22222

44444软件工程概论22222

55555面向对象程序设计25003

11016离散数学11049,25003

25057数据结构与算法11016,25003

66666操作系统33333,25057

70000计算机网络25057

70010统一建模语言44444,55555

70020软件需求44444

70030软件测试44444

70040软件过程与管理70020,70030

70050软件项目管理70040

70060软件能力成熟度模型70050

运行结果:

软公选课课程推荐表:

课程代号课程名称

22222计算机导论

25003计算机高级语言

33333计算机结构与组成

11049高等代数C

11016离散数学

55555面向对象程序设计

25057数据结构与算法

66666操作系统

44444软件工程概论

70010统一建模语言

70020软件需求

70030软件测试

70040软件过程与管理

70050软件项目管理

70060软件能力成熟度模型

70000计算机网络

第一和第三个for循环的时间开销为O(n),利用邻接矩阵,改程序的时间复杂度为O

(n2).

小结

当算法失败时,有向图没有拓扑序列,若算法没有失败,则v为一个拓扑序列。

附录

boolNetwork:

:

Topological(intv[])

{//Computetopologicalorderingofdigraphvertices.

//Returntrueifatopologicalorderisfound.

//Inthiscasereturntheorderinv[0:

n-1].

//Returnfalseifthereisnotopologicalorder.

intn=Vertices();

//Computein-degrees

int*InDegree=newint[n+1];

InitializePos();//graphiteratorarray

for(inti=1;i<=n;i++)//initialize

InDegree[i]=0;

for(inti=1;i<=n;i++){//edgesoutofi

intu=Begin(i);

while(u){

InDegree[u]++;

u=NextVertex(i);}

}

//Stackverticeswithzeroin-degree

LinkedStackS;

for(inti=1;i<=n;i++)

if(!

InDegree[i])S.Add(i);

//Generatetopologicalorder

inti=0;//cursorforarrayv

while(!

S.IsEmpty()){//selectfromstack

intw;//nextvertex

S.Delete(w);

v[i++]=w;

intu=Begin(w);

while(u){//updatein-degrees

InDegree[u]--;

if(!

InDegree[u])S.Add(u);

u=NextVertex(w);}

}

DeactivatePos();

delete[]InDegree;

return(i==n);

}

////CourseSequence.cpp:

定义控制台应用程序的入口点。

////

//

#include"stdafx.h"

#include"course.h"

#include

#include

usingnamespacestd;

#include"ldigraph.h"

int_tmain(intargc,_TCHAR*argv[])

{

ifstreamf1("data.txt",ios:

:

_Nocreate);

intn=0;

//读取文件

f1>>n;

int*T=newint[n+1];

/*for(inti=0;i

T[i]=0;

*/

course*Mycou=newcourse[n+1];

/*course*T_Mycou=newcoures[n+1];*/

for(inti=0;i

{

if(i==9||i==11||i==12||i==14||i==15)

{

f1>>Mycou[i].v>>Mycou[i].num>>Mycou[i].name>>Mycou[i].fnum1;

}

elseif(i==0||i==1||i==2)

{

f1>>Mycou[i].v>>Mycou[i].num>>Mycou[i].name;

}

else

{

f1>>Mycou[i].v>>Mycou[i].num>>Mycou[i].name>>Mycou[i].fnum1>>Mycou[i].fnum2;

}

}

f1.close();

//初始化图

LinkedDigraphDG(n);

for(inti=0;i

{

if(Mycou[i].v==10||Mycou[i].v==12||Mycou[i].v==13||Mycou[i].v==15||Mycou[i].v==16)

DG.Add(Mycou[i].fnum1,Mycou[i].v);

elseif(Mycou[i].v==1||Mycou[i].v==2||Mycou[i].v==3)

{

continue;

}

else

{

DG.Add(Mycou[i].fnum1,Mycou[i].v);

DG.Add(Mycou[i].fnum2,Mycou[i].v);

}

}

/*cout<<"Thegraphis"<

DG.Output();*/

DG.Topological(T);//拓扑排序

ofstreamf2("data1.txt",ios:

:

out);

f2<<"软公选课课程推荐表:

"<

f2<<"课程代号"<<""<<"课程名称"<

//输出排序后课表

for(inti=0;i

{

f2<

}

f2.close();

return0;

}

实习四

需求规格说明

电话簿软件的实现(动态查找表算法的应用)

【问题描述】

在很多实际应用中,动态索引结构在文件创建或初始装入记录时生成,在系统运行过程中插入或删除记录时,为了保持较好的检索性能,索引结构本身将随之发生改变。

教材上已经介绍的动态查找数据结构包括:

二叉搜索树(BST)、平衡二叉树(AVL)、红黑树(RBT)、B-树。

本题要求选取一种已经学过的动态搜索树结构,设计并实现一个手机电话薄软件。

【基本要求】

一个完整的电话簿软件应具有以下功能:

(1)支持复式电话簿数据的存储,数据条目不少于500条。

每个人名下可保存的信息包括:

姓名、手机号码、住宅电话号码、办公电话号码、电子邮件地址、所属群组、备忘录等。

(2)支持电话簿记录的添加、删除、编辑等操作。

(3)将不同类型的人群按照同事、朋友、家人、商务伙伴等分组,支持群组记录的添加、删除、编辑等操作。

(4)支持所有电话簿记录的导入、导出操作,外部数据采用TXT格式。

(5)支持电话簿记录的各种查询操作,具体包括:

①逐条翻看

能显示所有的电话簿记录,支持分屏查看。

②电话号码查找

输入一个电话号码(手机、住宅、办公),能将包含该号码的电话簿记录显示出来。

③人名查找

输入一个人名(全名或者部分名),能将包含该姓名的电话簿记录显示出来。

④群组查找

选择一种群组类型,能将属于该群组的所有电话簿记录显示出来。

(6)要求使用BST或者AVL实现动态索引结构。

【提高要求】

(1)系统支持铃声库和图片库的数据存储,提供添加、删除、修改、播放等操作。

铃声库和图片库可直接使用文件目录进行管理;铃声格式可使用WAV、MP3或者WMA格式;图片格式可使用BMP、JPG等格式。

(2)电话簿记录信息支持:

来电铃声、来电图片等信息,用户可通过界面编辑或者浏览某条电话簿记录的来电铃声、来电图片。

(3)人名查询支持:

输入姓名的首字母查找。

(4)使用红黑树或者B-树的数据结构,来实现动态索引结构。

【测试数据】

自行随机生成500~1000条电话簿数据记录。

【实现提示】

(1)设计合适的电话簿数据文件格式;

(2)设计合适的索引文件格式。

总体分析与设计

利用二叉搜索数为存储结构进

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

当前位置:首页 > 医药卫生 > 基础医学

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

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