数据结构小学期算法演示程序实验报告.docx

上传人:b****9 文档编号:25629905 上传时间:2023-06-10 格式:DOCX 页数:37 大小:92.28KB
下载 相关 举报
数据结构小学期算法演示程序实验报告.docx_第1页
第1页 / 共37页
数据结构小学期算法演示程序实验报告.docx_第2页
第2页 / 共37页
数据结构小学期算法演示程序实验报告.docx_第3页
第3页 / 共37页
数据结构小学期算法演示程序实验报告.docx_第4页
第4页 / 共37页
数据结构小学期算法演示程序实验报告.docx_第5页
第5页 / 共37页
点击查看更多>>
下载资源
资源描述

数据结构小学期算法演示程序实验报告.docx

《数据结构小学期算法演示程序实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构小学期算法演示程序实验报告.docx(37页珍藏版)》请在冰豆网上搜索。

数据结构小学期算法演示程序实验报告.docx

数据结构小学期算法演示程序实验报告

实习报告

实验名称:

数据结构基本算法演示程序日期:

2017年7月1日

姓名:

于博学号:

20153236班级:

信1501-2指导教师:

陈娜

                                 

1.实验题目

1)Prim算法输入:

无向图(顶点序列,边序列)

功能要求:

输出最小生成树的各组成边及最小生成树的权值

2)Kruskal算法输入:

无向图(顶点序列,边序列)

功能要求:

输出最小生成树的各组成边及最小生成树的权值

3)Floyd算法输入:

有向图(顶点序列,有向边序列)

功能要求:

输出各顶点对间最短路径和路径长度

4)Dijkstra算法

输入:

有向图(顶点序列,有向边序列),起始顶点

功能要求:

输出起始顶点到其它各顶点的最短路径和路径长度

2.需求分析

本演示程序用C++编写,完成四个算法的实现,Prim算法,Kruskal算法,Floyd算法,Dijkstra算法

①输入的形式和输入值的范围:

整数,菜单项是1至5,其他输入根据图的实际情况。

②输出的形式:

输出最小生成树,树的各组成边,所有路径及源点到其他点的所有最短路径。

③程序所能达到的功能:

四个算法Prim算法,Kruskal算法,Floyd算法,Dijkstra算法的实现。

④测试数据:

A.输入3个点,3条边。

B.输入135012202310三组点及权值。

3.概要设计

1)为了实现上述程序功能,需要定义树、线性表的抽象数据类型:

ADTTree{

数据对象:

D={ai|ai∈IntegerSet,i=0,1,2,…,n,n≥0}

数据关系:

R={|ai,ai+1∈D}

ADTLinkList{

数据对象:

D={ai|ai∈IntegerSet,i=0,1,2,…,n,n≥0}

数据关系:

R={|ai,ai+1∈D}

基本操作:

a)Prim算法

ok(Tree&t,intk)

初始条件:

树结构已存在

操作结果:

作为判断函数的条件

judge(Tree&t)

初始条件:

树结构已存在

操作结果:

判断树是否包含所有图的结点

show_prim()

初始条件:

树结构已存在,prim算法运行成功

操作结果:

展示prim算法,输出最小生成树

b)Kruskal算法

Find(intx)

初始条件:

图已存在

操作结果:

查寻父节点

Union(intx,inty)

初始条件:

图已存在

操作结果:

合并结点

boolCom(Nodex,Nodey)

初始条件:

图已存在

操作结果:

判断结点权值

show_kruskal()

初始条件:

图已存在,kruskal算法运行成功

操作结果:

展示kruskal算法,输出各组成边

c)Floyd算法

F_Creategraph(F_MGraph*F_MGraph)

操作结果:

创建图

Floyd(F_MGraph*F_MGraph,int**iArrPath)

初始条件:

图已存在

操作结果:

运行弗洛伊德算法

PrintResult(F_MGraph*F_MGraph,int**iArrPath)

初始条件:

图已存在

操作结果:

打印图的信息

show_floyd()

初始条件:

图已存在,弗洛伊德算法运行成功

操作结果:

展示弗洛伊德算法

d)Dijkstra算法

createGraph(HeadNode*G,intnodeNum,intarcNum)

操作结果:

创建图

printGraph(HeadNode*G,intnodeNum)

初始条件:

图已存在

操作结果:

打印图

getWeight(HeadNode*G,intbegin,intend)

初始条件:

图已存在

操作结果:

得到出发点到终点权重

Dijkstra(HeadNode*G,intnodeNum,intbegin)

初始条件:

图已存在,出发点已知

操作结果:

运行迪杰斯特拉算法

printPath(HeadNode*G,intend)

初始条件:

图已存,迪杰斯特拉算法运行成功

操作结果:

打印路径

show_Dijkstra()

初始条件:

图已存,迪杰斯特拉算法运行成功

操作结果:

展示迪杰斯特拉算法

menu()

操作结果:

在屏幕上显示操作菜单

2)本程序包含17个函数:

主函数main()

菜单函数menu()

Prim算法

判断函数ok()

判断树是否包含所有图的结点judge()

展示prim算法函数show_prim()

Kruskal算法

查寻父节点函数Find()

合并结点函数Union()

判断节点权值函数boolCom()

展示kruskal算法函数show_kruskal()

Floyd算法

弗洛伊德创建图F_Creategraph()

弗洛伊德算法函数Floyd()

打印图信息函数PrintResult()

展示弗洛伊德函数show_floyd()

Dijistra算法

创建图createGraph()

迪杰斯特拉算法函数Dijkstra()

打印路径函数printPath()

展示迪杰斯特拉函数show_Dijkstra()

各函数间关系如下:

4.详细设计

//------------------------------------------Prim算法--------------------------------------------------//

//判断函数--是否树包含图的所有结点

voidjudge(Tree&t){

for(inti=1;i

for(intj=0;j

intm;

m=t.v[j];

for(intk=1;k<=t.v1;k++){

if(t.a[m][k]

if(ok(t,k)){

biaoji1=t.a[m][k];

biaoji2=m;

biaoji3=k;

}

}

}

}

t.v[i]=biaoji3;

t.e[2*i-1]=biaoji2;

t.e[2*i]=biaoji3;

}

}

//调用prim算法相关所有代码

voidshow_prim(){

cout<<"请输入图的点数和边数"<

cin>>n>>m;

t.v1=n;//给树的结点总数和边的结点总数赋值

t.e1=m;

t.v=newint[n];//结点数组

for(inti=0;i

t.v[i]=0;

t.e=newint[2*n-1];//边与结点数的关系

for(inti=0;i<2*n-1;i++)//循环初始化

t.e[i]=0;

t.a=newint*[n+1];

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

t.a[i]=newint[n+1];

cout<<"请依次输入各边的两端点及权值"<

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

for(intj=1;j<=n;j++)

t.a[i][j]=10000;//初始化为无穷大

for(inti=1;i<=m;i++){//for循环输入

cin>>m1>>m2>>count;

t.a[m1][m2]=count;//无向网赋值

t.a[m2][m1]=count;

}

judge(t);//判断是否有全部叶子节点

cout<<"最小生成树为:

"<

for(inti=1;i

x=t.e[2*i-1];

y=t.e[2*i];

cout<"<

sum+=t.a[x][y];

}

cout<<"最小生成树的权值之和为:

"<

}

//--------------------------------------kruskal算法------------------------------------------------------//

intFind(intx){//查

if(x==Father[x])returnx;

elsereturnFind(Father[x]);

}

voidUnion(intx,inty){//并

Father[x]=y;

}

intTop,Edge;

boolCom(Nodex,Nodey){

returnx.Weight

}

dequeMap;

//调用克鲁斯卡尔的相关代码

voidshow_kruskal(){

cout<<"请输入结点个数及边数:

"<

cin>>Top>>Edge;

cout<<"请依次输入两点及权值:

"<

for(i=1;i<=Top;i++)

for(j=1;j<=Top;j++){

cin>>x;

if(j>i&&x!

=100){

y.Next=j;

y.Priority=i;

y.Weight=x;

Map.push_back(y);

}

}

sort(Map.begin(),Map.end(),Com);

for(i=1;i<=Top;i++){

Father[i]=i;

}

cout<<"树的各组成边有:

"<

for(i=0;i

if(count==Top-1)break;

if(Find(Map[i].Priority)!

=Find(Map[i].Next)){

Union(Map[i].Priority,Map[i].Next);

count++;

if(Map[i].Priority>Map[i].Next)

cout<"<"<

else

cout<"<

}

}

}

//--------------------------------------floyd算法---------------------------------------------------------------//

//图的创建

voidF_Creategraph(F_MGraph*F_MGraph){

cout<<"请输入顶点数和边数"<

cin>>F_MGraph->Vcount>>F_MGraph->Ecount;

for(introw=1;row<=F_MGraph->Vcount;row++){//初始化为无穷,即不连通

for(intcol=1;col<=F_MGraph->Vcount;col++){

F_MGraph->edges[row][col]=MAX_VALUE;

}

}

cout<<"请输入起始结点最终结点权重"<

for(inti=1;i<=F_MGraph->Ecount;i++){//赋值

cin>>row>>col>>weight;

F_MGraph->edges[row][col]=weight;

}

}

//佛洛依德算法

voidFloyd(F_MGraph*F_MGraph,int**iArrPath){

for(inti=1;i<=F_MGraph->Vcount;i++){

for(intj=1;j<=F_MGraph->Vcount;j++){

iArrPath[i][j]=i;

}

}

//初始化路径表

for(intk=1;k<=F_MGraph->Vcount;k++){

for(inti=1;i<=F_MGraph->Vcount;i++){

for(intj=1;j<=F_MGraph->Vcount;j++){

if(F_MGraph->edges[i][k]+F_MGraph->edges[k][j]edges[i][j]){

F_MGraph->edges[i][j]=F_MGraph->edges[i][k]+F_MGraph->edges[k][j];

iArrPath[i][j]=iArrPath[k][j];

}

}

}

}

}

//打印佛洛依德算法最短路径

voidPrintResult(F_MGraph*F_MGraph,int**iArrPath){

cout<<"起点->终点\t距离\t\t最短路径"<

for(inti=1;i<=F_MGraph->Vcount;i++){

for(intj=1;j<=F_MGraph->Vcount;j++){

if(i!

=j){

cout<"<

if(F_MGraph->edges[i][j]==MAX_VALUE){

cout<<"无连通路径"<<"\t\t"<

}

else{

cout<edges[i][j]<<"\t\t";

std:

:

stackstackVertices;

do{

k=iArrPath[i][k];

stackVertices.push(k);

}while(k!

=i);

cout<

stackVertices.pop();

unsignedintnLength=stackVertices.size();

for(unsignedintnIndex=0;nIndex

{

cout<<"->"<

stackVertices.pop();

}

cout<<"->"<

}

}

}

}

}

//调用弗洛伊德相关代码

voidshow_floyd(){

for(inti=0;i

iArrPath[i]=newint[MAX_VALUE];

}

F_MGraphF_MGraph;

for(inti=0;i

F_MGraph.edges[i]=newint[MAX_VALUE];

}

F_Creategraph(&F_MGraph);

Floyd(&F_MGraph,iArrPath);

PrintResult(&F_MGraph,iArrPath);

}

//-----------------------------Dijkstra算法------------------------------------//

//创建图函数

voidcreateGraph(HeadNode*G,intnodeNum,intarcNum){//G表示指向头结点数组的第一个结点的指针nodeNum表示结点个数arcNum表示边的个数

cout<<"开始创建图("<

//初始化头结点

for(inti=0;i

G[i].nodeName=i+1;//位置0上面存储的是结点v1,依次类推

G[i].inDegree=0;//入度为0

G[i].link=NULL;//指针置空

}

//给边赋权值

for(intj=0;j

intbegin,end,weight;//起点终点权值

cout<<"请输入起始顶点结束顶点权值:

";

cin>>begin>>end>>weight;//输入起点终点权值

D_Node*node=newD_Node;//创建边表插入链接表

node->adjvex=end-1;//记录终点信息

node->weight=weight;//赋权值

++G[end-1].inDegree;//边的终点入度加1

node->next=G[begin-1].link;//前插法即后输入的先打印(打印图的时候是倒着的)

G[begin-1].link=node;//插入链接表的第一个位置

}

}

//打印图函数

voidprintGraph(HeadNode*G,intnodeNum){

//输出结点入度及以其为起点的边

for(inti=0;i

cout<<"结点v"<

"<

D_Node*node=G[i].link;

while(node!

=NULL){//依附于该顶点的指针不为空,即还存在以该结点为起点的边

cout<<"v"<weight<<"---"<<"v"<adjvex].nodeName<

node=node->next;//依次向后遍历

}

cout<

}

}

//得到begin->end权重

intgetWeight(HeadNode*G,intbegin,intend){

D_Node*node=G[begin-1].link;

while(node){

if(node->adjvex==end-1){

returnnode->weight;

}

node=node->next;

}

}

//从begin开始,计算其到每一个顶点的最短路径

voidDijkstra(HeadNode*G,intnodeNum,intbegin){

//初始化所有结点的

for(inti=0;i

G[i].d=INT_MAX;//到每一个顶点的距离初始化为无穷大,头文件包含limits,增强可移植性

G[i].isKnown=false;//到每一个顶点的最短距离为未知数

}

G[begin-1].d=0;//到其本身的距离为0

G[begin-1].parent=-1;//表示该结点是起始结点

while(true){//如果所有的结点的最短距离都已知,那么就跳出循环

boolok=true;//表示是否全部ok

for(intk=0;k

if(!

G[k].isKnown){//只要有一个顶点的最短路径未知,ok就设置为false

ok=false;

break;

}

}

if(ok)return;

//搜索未知结点中d最小的,将其变为known

intminIndex=-1;

for(inti=0;i

if(!

G[i].isKnown){

if(minIndex==-1)

minIndex=i;

elseif(G[minIndex].d>G[i].d)

minIndex=i;

}

}

cout<<"已知最短路径的结点为:

v"<<(minIndex+1)<

G[minIndex].isKnown=true;//将其加入最短路径已知的顶点集

D_Node*node=G[minIndex].link;//将以minIndex为起始顶点的所有的d更新

while(node!

=NULL){

intbegin=minIndex+1;

intend=node->adjvex+1;

intweight=getWeight(G,begin,end);

if(G[minIndex].d+weight

G[end-1].d=G[minIndex].d+weight;

G[end-1].parent=minIndex;//记录最短路径的上一个结点

}

node=node->next;

}

}

}

//打印到end-1的最短路径

voidprintPath(HeadNode*G,intend){

if(G[end-1].parent==-1){

cout<<"v"<

}elseif(end!

=0){

printPath(G,G[end-1].parent+1);//因为这里的parent表示的是下标,从0开始,所以要加1

cout<<"->v"<

}

}

//调用迪杰斯特拉的相关代码

voidshow_Dijkstra(){

HeadNode*G;//头结点

intnodeNum,arcNum;//顶点个数,边的个数

cout<<"请输入顶点个数,边的个数:

";

cin>>nodeNum>>arcNum;

G=newHeadNode[nodeNum];

createGraph(G,nodeNum,arcNum);//创建

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

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

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

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