实验无向图中求两点间的所有简单路径.docx

上传人:b****5 文档编号:5757247 上传时间:2023-01-01 格式:DOCX 页数:18 大小:40.31KB
下载 相关 举报
实验无向图中求两点间的所有简单路径.docx_第1页
第1页 / 共18页
实验无向图中求两点间的所有简单路径.docx_第2页
第2页 / 共18页
实验无向图中求两点间的所有简单路径.docx_第3页
第3页 / 共18页
实验无向图中求两点间的所有简单路径.docx_第4页
第4页 / 共18页
实验无向图中求两点间的所有简单路径.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

实验无向图中求两点间的所有简单路径.docx

《实验无向图中求两点间的所有简单路径.docx》由会员分享,可在线阅读,更多相关《实验无向图中求两点间的所有简单路径.docx(18页珍藏版)》请在冰豆网上搜索。

实验无向图中求两点间的所有简单路径.docx

实验无向图中求两点间的所有简单路径

实验6无向图中求两点间的所有简单路径

计科二班宋瑞霞20100810217

一、需求分析

1、用无向图表示高速公路网,其中顶点表示城市,边表示城市之间的高速公路。

设计一个找路程序,获取两个城市之间的所有简单路径。

2、由用户通过键盘输入:

(1)结点总数,

(2)结点的城市编号(4位长的数字,例如电话区号,长沙是0731),

(3)连接城市的高速公路(用高速公路连接的两个城市编号标记),

(4)要求取所有简单路径的两个城市编号。

不对非法输入做处理,即假设输入都是合法的。

3、输出:

将所有路径(有城市编号组成)输出到DOS界面上。

4、测试数据:

输入:

68(结点数和边数)

000100020003000400050006(结点的城市编号)

00010003(连接城市间的高速公路)

00010005

00020006

00030002

00030004

00030006

00040006

00050006

00010002(要求取所有简单路径的两个城市编号)

输出:

000100030002(两个城市间的所有简单路径)

0001000300060002

00010003000400060002

0001000500060002

00010005000600030002

000100050006000400030002

二、概要设计

抽象数据类型

根据对问题的分析,要用无向图表示高速公路网,其中顶点表示城市,边表示城市之间的高速公路。

所以要建立一个图来实现。

图的ADT设计如下:

数据元素:

包括一个顶点集合和一个边集合

数据关系:

网状关系

基本操作:

Graph(intnumvert)//构造图结构

virtualintn()=0;//获取顶点的个数

virtualintfirst(int)=0;//访问所给顶点的第一个邻居

virtualintnext(int,int)=0;//访问当前邻居的下一个邻居

virtualvoidsetedge(int,int)=0;//建立所给两顶点之间的边

virtualvoidsetmark(intv,intval)=0;//给顶点做标记

virtualintgetmark(intv)=0;//获取顶点是否已做标记

算法的基本思想

首先,根据输入的结点总数构建一个线性表,将输入的城市编号即顶点依次添加到线性表中;然后就是在图的二维数组中存入边即连接两个城市间的高速公路,这步操作首先要找到两个城市即两个顶点在线性表中的位置如m和n,然后再在二维数组相应的位置(m,n)上存入1建立该条边;最后当所有的边都存入图中后,由于深度优先的结果是沿着图的某一分支搜索直至末端,然后回溯,在沿着另一条分支搜索,依次类推,故对图进行深度优先搜索,即可得到两个城市间的简单路径。

程序的流程

程序由四个模块组成:

1、输入模块:

输入图的顶点和边;

2、构建模块:

用线性表存储顶点,用二维数组存储边,构建图结构;

3、处理模块:

对图进行深度优先搜索;

4、输出模块:

将深度优先搜索后得到的所有简单路径输出到DOS界面上。

三、详细设计

物理数据类型

该问题需要输入4位长的数字表示的城市编号,为了能够存储,采用C++语言中的字符串string来定义变量线性表中的元素类型,数组的大小为4。

根据用邻接矩阵表示法来实现图的相关知识,要先建立一个线性表来存储顶点,由于结点总数即图的顶点数已知,则线性表的长度已知,故用顺序表实现比较好,因为顺序表是预先分配一段连续的存储空间,而且没有结构性开销。

1、顺序表的具体实现如下:

template(在本问题,Elem为string)

classAlist

{

private:

intmaxSize;//顺序表的最大长度

intlistSize;//顺序表的实际长度

intfence;//指向当前位置

Elem*listArray;//存储顺序表元素的数组

public:

Alist(intsize=DefaultListSize)//构造一个由用户指定最大长度的空顺序表

{

maxSize=size;

listSize=fence=0;

listArray=newElem[maxSize];

}

boolappend(constElem&item)//添加

{

if(listSize==maxSize)

returnfalse;

else

{

listArray[listSize++]=item;

returntrue;

}

}

intrightLength()const//右边长度

{

returnlistSize-fence;

}

boolgetvalue(iElem&it)const//获取当前位置的元素值,若右边为空,返回false

{

if(rightLength()==0)

returnfalse;

else

{

it=listArray[fence];

returntrue;

}

}

voidsetStart()//将当前位置置0

{

fence=0;

}

voidnext()//右移一位

{

if(fence

fence++;

}

};

2、图的具体实现如下:

classGraph

{

private:

intnumvertex,numedge;//存储顶点数和边数

int**matrix;//指向邻接矩阵的指针

int*mark;//指向访问标记数组的指针

public:

Graph(intnumvert)//实现邻接矩阵

{

inti,j;

numvertex=numvert;

numedge=0;

mark=newint[numvert];

for(i=0;i

mark[i]=0;

matrix=(int**)newint*[numvertex];//构造邻接矩阵

for(i=0;i

matrix[i]=newint[numvertex];

for(i=0;i

for(j=0;j

matrix[i][j]=0;

}

~Graph()//析构函数

{

delete[]mark;

for(inti=0;i

delete[]matrix[i];

delete[]matrix;

}

intn()//获取顶点个数

{

returnnumvertex;

}

inte()//获取边的个数

{

returnnumedge;

}

intfirst(intv)//访问所给顶点的第一个邻居

{

inti;

for(i=0;i

if(matrix[v][i]!

=0)

returni;

returni;

}

intnext(intv1,intv2)//访问当前邻居的下一个邻居

{

inti;

for(i=v2+1;i

if(matrix[v1][i]!

=0)

returni;

returni;

}

voidsetedge(intv1,intv2)//无向图中建立所给两顶点之间的边

{

if(matrix[v1][v2]==0)

numedge++;

matrix[v1][v2]=1;

matrix[v2][v1]=1;

}

voidsetmark(intv,intval)//给顶点做标记

{

mark[v]=val;

}

intgetmark(intv)//获取顶点是否已做标记

{

returnmark[v];

}

};

算法的具体步骤

1、定义顺序表L、图G,还有存储课程名的字符串stringcity,city1,city2,

输入顶点个数n和边数m。

2、输入顶点city并将输入的顶点依次存入顺序表L中。

for(inti=0;i

{

cin>>city;

L.append(city);

}

3、输入有路连接的两个城市编号,即相互间存在边的两个顶点,找到这两个顶点在线性表中的位置,然后在图的二维数组相应的位置上存入1建立该条边。

通过一个循环将所有的边都建完,完成图的存储。

for(inti=0;i

{

cin>>city1>>city2;

G.setedge(find(L,n,city1),find(L,n,city2));

}

其中find函数即实现找到顶点在线性表中的位置的功能,具体如下:

intfind(AlistL,intn,int&city)

{

inti;

stringcity1;

L.setStart();

for(i=0;i

{

L.getvalue(city1);//获取当前位置的元素值

if(city1==city)//若当前位置的元素值与所要找的顶点值相同

returni;//则返回当前位置所在的位置

else

L.next();//若不同,则在向右移一位再做判断

}

}

4、对图进行深度优先搜索

intaddr[100];

intnum=-1;

voidDFS(Graph&G,intv,Alist&L,intd)

{

G.setmark(v,1);

if(v==d)

{

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

{

printout(L,addr[i]);

cout<<'';

}

cout<

G.setmark(d,0);

num--;

return;

}

for(intw=G.first(v);w

if(G.getmark(w)==0)

{

addr[++num]=w;

DFS(G,w,L,d);

}

num--;

G.setmark(v,0);

}

其中的输出函数为:

voidprintout(AlistL,intv)

{

L.setStart();

strings;

for(inti=0;i

L.next();

L.getvalue(s);

cout<

}

算法的时空分析

设V为顶点数,E为边数,

(1)由于顺序表用来存储顶点,顺序队列用来存储入度为0的顶点,所以它们的空间代价都为Θ(|V|);而邻接矩阵的空间代价为Θ(|V|^2),故总的空间代价为Θ(|V|^2)。

(2)由于顺序表的添加操作的时间复杂度为Θ

(1),故将所有结点存入顺序表的时间复杂度为Θ(|V|);在对无向图进行深度优先时,DFS从两个方向处理每条边,每个顶点都必须被访问,而且只能访问一次,故总的时间复杂度为Θ(|V|+|E|)。

输入和输出的格式

输入:

请输入结点总数和边数:

//提示

等待输入

请输入城市编号:

//提示

等待输入

请输入有路连接的两个城市的编号:

//提示

等待输入

请输入要求取所有简单路径的两个城市编号:

//提示

等待输入

输出:

这两个城市间的所有简单路径为:

//提示

输出结果的位置

四、调试分析

大部分是语法错误,看着错误提示都改过来了,今天又学到点新知识,就是如果执行的界面没关的话,连接时会出现错误。

五、测试结果

六、用户使用说明

1、本程序的运行环境为DOS操作系统

2、运行程序时

提示输入结点总数和边数

城市编号

有路连接的两个城市的编号

要求取所有简单路径的两个城市编号

输出:

两个城市间的所有简单路径

七、实验心得

这次实验感觉好难啊,搞了一天的预习报告,结果就得了1分,那种感觉真的好难受的!

八、程序

#include

#include

usingnamespacestd;

#defineElemstring

classAlist

{

private:

intmaxSize;//顺序表的最大长度

intlistSize;//顺序表的实际长度

intfence;//指向当前位置

Elem*listArray;//存储顺序表元素的数组

public:

Alist(intsize)//构造一个由用户指定最大长度的空顺序表

{

maxSize=size;

listSize=fence=0;

listArray=newElem[maxSize];

}

boolappend(constElem&item)//添加

{

if(listSize==maxSize)

returnfalse;

else

{

listArray[listSize++]=item;

returntrue;

}

}

boolremove()//删除

{

Elemit;

if(rightLength()==0)

returnfalse;

it=listArray[fence];

for(inti=fence;i

listArray[i]=listArray[i+1];

listSize--;

returntrue;

}

intrightLength()const//右边长度

{

returnlistSize-fence;

}

boolgetvalue(Elem&it)const//获取当前位置的元素值,若右边为空,返回false

{

if(rightLength()==0)

returnfalse;

else

{

it=listArray[fence];

returntrue;

}

}

voidsetStart()//将当前位置置0

{

fence=0;

}

voidnext()//右移一位

{

if(fence

fence++;

}

voidprev()

{

if(fence!

=0)

fence--;

}

boolsetPos(intpos)

{

if((pos>=0)&&(pos<=listSize))

fence=pos;

return(pos>=0)&&(pos<=listSize);

}

};

classGraph

{

private:

intnumvertex,numedge;

int**matrix;

int*mark;

public:

Graph(intnumvert)

{

inti,j;

numvertex=numvert;

numedge=0;

mark=newint[numvert];

for(i=0;i

mark[i]=0;

matrix=(int**)newint*[numvertex];

for(i=0;i

matrix[i]=newint[numvertex];

for(i=0;i

for(j=0;j

matrix[i][j]=0;

}

~Graph()

{

delete[]mark;

for(inti=0;i

delete[]matrix[i];

delete[]matrix;

}

intn()

{

returnnumvertex;

}

inte()

{

returnnumedge;

}

intfirst(intv)

{

inti;

for(i=0;i

if(matrix[v][i]!

=0)

returni;

returni;

}

intnext(intv1,intv2)

{

inti;

for(i=v2+1;i

if(matrix[v1][i]!

=0)

returni;

returni;

}

voidsetedge(intv1,intv2)

{

matrix[v1][v2]=1;

matrix[v2][v1]=1;

}

voidsetmark(intv,intval)

{

mark[v]=val;

}

intgetmark(intv)

{

returnmark[v];

}

};

intfind(AlistL,intn,strings)

{

inti;

strings1;

L.setStart();

for(i=0;i

{

L.getvalue(s1);

if(s1==s)

returni;

else

L.next();

}

}

voidprintout(AlistL,intv)

{

L.setStart();

strings;

for(inti=0;i

L.next();

L.getvalue(s);

cout<

}

intaddr[100];

intnum=-1;

voidDFS(Graph&G,intv,Alist&L,intd)

{

G.setmark(v,1);

if(v==d)

{

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

{

printout(L,addr[i]);

cout<<'';

}

cout<

G.setmark(d,0);

num--;

return;

}

for(intw=G.first(v);w

if(G.getmark(w)==0)

{

addr[++num]=w;

DFS(G,w,L,d);

}

num--;

G.setmark(v,0);

}

voidmain()

{

inti,n,m;

stringcity,city1,city2;

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

\n";

cin>>n>>m;

GraphG(n);

AlistL(n);

cout<<"请输入城市编号:

\n";

for(i=0;i

{

cin>>city;

L.append(city);

}

cout<<"请输入有路连接的两个城市的编号:

\n";

for(i=0;i

{

cin>>city1>>city2;

G.setedge(find(L,n,city1),find(L,n,city2));

}

cout<<"请输入要求取所有简单路径的两个城市编号:

\n";

cin>>city1>>city2;

cout<<"这两个城市间的所有简单路径为:

\n";

addr[++num]=find(L,n,city1);

DFS(G,find(L,n,city1),L,find(L,n,city2));

}

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

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

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

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