您的位置:首页 > 其它

第12周 项目4 - 利用遍历思想求解图问题 (1-5)

2016-11-12 17:44 441 查看
/*

Copyright (c)2015,烟台大学计算机与控制工程学院

All rights reserved.

文件名称:利用遍历思想求解图问题.cpp

作 者:林颖

完成日期:2016年11月12日

版 本 号:v1.0

问题描述: 假设图G采用邻接表存储,分别设计实现以下要求的算法,要求用区别于示例中的图进行多次测试,通过观察输出值,掌握相关问题的处理方法。

   (1)设计一个算法,判断顶点u到v是否有简单路径

   (2)设计一个算法输出图G中从顶点u到v的一条简单路径(设计测试图时,保证图G中从顶点u到v至少有一条简单路径)。

   (3)输出从顶点u到v的所有简单路径。

   (4)输出图G中从顶点u到v的长度为s的所有简单路径。

   (5)求图中通过某顶点k的所有简单回路(若存在)

输入描述:若干测试数据。

程序输出:相应的数据输出。

*/

(1).main函数:

int main()

{

ALGraph *G;

int A[5][5]=

{

{0,0,0,0,0},

{0,0,1,0,0},

{0,0,0,1,1},

{0,0,0,0,0},

{1,0,0,1,0},

}; //请画出对应的有向图

ArrayToList(A[0], 5, G);

HasPath(G, 1, 0);

HasPath(G, 4, 1);

return 0;

}

源函数:

int visited[MAXV]; //定义存放节点的访问标志的全局数组

void ExistPath(ALGraph *G,int u,int v, bool &has)

{

int w;

ArcNode *p;

visited[u]=1;

if(u==v)

{

has=true;

return;

}

p=G->adjlist[u].firstarc;

while (p!=NULL)

{

w=p->adjvex;

if (visited[w]==0)

ExistPath(G,w,v,has);

p=p->nextarc;

}

}

void HasPath(ALGraph *G,int u,int v)

{

int i;

bool flag = false;

for (i=0; i<G->n; i++)

visited[i]=0; //访问标志数组初始化

ExistPath(G,u,v,flag);

printf(" 从 %d 到 %d ", u, v);

if(flag)

printf("有简单路径\n");

else

printf("无简单路径\n");

}

运行结果



(2)main函数:

int main()

{

ALGraph *G;

int A[5][5]=

{

{0,0,0,0,0},

{0,0,1,0,0},

{0,0,0,1,1},

{0,0,0,0,0},

{1,0,0,1,0},

}; //请画出对应的有向图

ArrayToList(A[0], 5, G);

APath(G, 1, 0);

APath(G, 4, 1);

return 0;

}

源文件:

int visited[MAXV]; //定义存放节点的访问标志的全局数组

void FindAPath(ALGraph *G,int u,int v,int path[],int d)

{

//d表示path中的路径长度,初始为-1

int w,i;

ArcNode *p;

visited[u]=1;

d++;

path[d]=u; //路径长度d增1,顶点u加入到路径中

if (u==v) //找到一条路径后输出并返回

{

printf("一条简单路径为:");

for (i=0; i<=d; i++)

printf("%d ",path[i]);

printf("\n");

return; //找到一条路径后返回

}

p=G->adjlist[u].firstarc; //p指向顶点u的第一个相邻点

while (p!=NULL)

{

w=p->adjvex; //相邻点的编号为w

if (visited[w]==0)

FindAPath(G,w,v,path,d);

p=p->nextarc; //p指向顶点u的下一个相邻点

}

}

void APath(ALGraph *G,int u,int v)

{

int i;

int path[MAXV];

for (i=0; i<G->n; i++)

visited[i]=0; //访问标志数组初始化

FindAPath(G,u,v,path,-1); //d初值为-1,调用时d++,即变成了0

}

运行结果



(3)main函数:

int main()

{

ALGraph *G;

int A[5][5]=

{

{0,1,0,1,0},

{1,0,1,0,0},

{0,1,0,1,1},

{1,0,1,0,1},

{0,0,1,1,0}

}; //请画出对应的有向图

ArrayToList(A[0], 5, G);

DispPaths(G, 1, 4);

return 0;

}

.源函数:

int visited[MAXV]; //定义存放节点的访问标志的全局数组

void FindPaths(ALGraph *G,int u,int v,int path[],int d)

//d是到当前为止已走过的路径长度,调用时初值为-1

{

int w,i;

ArcNode *p;

visited[u]=1;

d++; //路径长度增1

path[d]=u; //将当前顶点添加到路径中

if (u==v && d>1) //输出一条路径

{

printf(" ");

for (i=0; i<=d; i++)

printf("%d ",path[i]);

printf("\n");

}

p=G->adjlist[u].firstarc; //p指向u的第一条边

while(p!=NULL)

{

w=p->adjvex; //w为u的邻接顶点

if (visited[w]==0) //若顶点未标记访问,则递归访问之

FindPaths(G,w,v,path,d);

p=p->nextarc; //找u的下一个邻接顶点

}

visited[u]=0; //恢复环境

}

void DispPaths(ALGraph *G,int u,int v)

{

int i;

int path[MAXV];

for (i=0; i<G->n; i++)

visited[i]=0; //访问标志数组初始化

printf("从%d到%d的所有路径:\n",u,v);

FindPaths(G,u,v,path,-1);

printf("\n");

}

运行结果



(4)main函数

[cpp] view plaincopyprint?

int main()

{

ALGraph *G;

int A[5][5]=

{

{0,1,0,1,0},

{1,0,1,0,0},

{0,1,0,1,1},

{1,0,1,0,1},

{0,0,1,1,0}

}; //请画出对应的有向图

ArrayToList(A[0], 5, G);

DispSomePaths(G, 1, 4, 3);

return 0;

}

源文件:

int visited[MAXV]; //全局变量

void DFSPath(ALGraph *G,int u,int v,int path[],int d)

//d是到当前为止已走过的路径长度,调用时初值为-1

{

int w,i;

ArcNode *p;

visited[u]=1;

d++;

path[d]=u;

p=G->adjlist[u].firstarc; //p指向顶点u的第一条边

while (p!=NULL)

{

w=p->adjvex; //w为顶点u的相邻点

if (w==v && d>0) //找到一个回路,输出之

{

printf(" ");

for (i=0; i<=d; i++)

printf("%d ",path[i]);

printf("%d \n",v);

}

if (visited[w]==0) //w未访问,则递归访问之

DFSPath(G,w,v,path,d);

p=p->nextarc; //找u的下一个邻接顶点

}

visited[u]=0; //恢复环境:使该顶点可重新使用

}

void FindCyclePath(ALGraph *G,int k)

//输出经过顶点k的所有回路

{

int path[MAXV],i;

for (i=0; i<G->n; i++)

visited[i]=0; //访问标志数组初始化

printf("经过顶点%d的所有回路\n",k);

DFSPath(G,k,k,path,-1);

printf("\n");

}

运行结果



(5)main函数

int main()

{

ALGraph *G;

int A[5][5]=

{

{0,1,1,0,0},

{0,0,1,0,0},

{0,0,0,1,1},

{0,0,0,0,1},

{1,0,0,0,0}

}; //请画出对应的有向图

ArrayToList(A[0], 5, G);

FindCyclePath(G, 0);

return 0;

}

源文件

int visited[MAXV]; //全局变量

void DFSPath(ALGraph *G,int u,int v,int path[],int d)

//d是到当前为止已走过的路径长度,调用时初值为-1

{

int w,i;

ArcNode *p;

visited[u]=1;

d++;

path[d]=u;

p=G->adjlist[u].firstarc; //p指向顶点u的第一条边

while (p!=NULL)

{

w=p->adjvex; //w为顶点u的相邻点

if (w==v && d>0) //找到一个回路,输出之

{

printf(" ");

for (i=0; i<=d; i++)

printf("%d ",path[i]);

printf("%d \n",v);

}

if (visited[w]==0) //w未访问,则递归访问之

DFSPath(G,w,v,path,d);

p=p->nextarc; //找u的下一个邻接顶点

}

visited[u]=0; //恢复环境:使该顶点可重新使用

}

void FindCyclePath(ALGraph *G,int k)

//输出经过顶点k的所有回路

{

int path[MAXV],i;

for (i=0; i<G->n; i++)

visited[i]=0; //访问标志数组初始化

printf("经过顶点%d的所有回路\n",k);

DFSPath(G,k,k,path,-1);

printf("\n");

}

运行结果



知识点总结:

图的遍历。

学习心得

感觉有点不太懂,模模糊糊,还是需要多练习
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: