一、实验目的:
假设一个不带权连通图采用邻接表存储。请同学们设计一个算法输出从顶点u到顶点v的长度恰好为l的所有简单路径。并对如图片所示的图进行测试。
二、实验过程:
实现思路:
首先,我们需要创建一个邻接表表示的图。
然后,我们需要实现一个递归函数FindallPath,该函数用于查找从顶点u到顶点v的长度为l的所有简单路径。
在FindallPath函数中,我们需要遍历所有与当前顶点相邻的顶点,如果该顶点没有被访问过,则递归调用FindallPath函数。
当找到一条长度为l的路径时,输出该路径。
最后,销毁图结构。
实验步骤:
定义图的顶点数n和边数e。
定义邻接矩阵A表示图的结构。
调用CreateGraph函数创建图。
初始化visited数组,用于记录顶点是否被访问过。
调用FindallPath函数查找从顶点u到顶点v的长度为l的所有简单路径。
输出结果。
调用DestroyGraph函数销毁图结构。
实现代码:
#include <stdio.h>
#include <malloc.h>
#define MAXVEX 100
#define INF 32767
typedef char VertexType[10];
int visited[MAXVEX];
typedef struct edgenode
{ int adjvex;
int weight;
struct edgenode *nextarc;
} ArcNode;
typedef struct vexnode
{ VertexType data;
ArcNode *firstarc;
} VHeadNode;
typedef struct
{ int n,e;
VHeadNode adjlist[MAXVEX];
} AdjGraph;
void CreateGraph(AdjGraph *&G,int A[][MAXVEX],int n,int e)
{
int i,j;
ArcNode *p;
G=(AdjGraph *)malloc(sizeof(AdjGraph));
G->n=n; G->e=e;
for (i=0;i<G->n;i++)
G->adjlist[i].firstarc=NULL;
for (i=0;i<G->n;i++)
for (j=G->n-1;j>=0;j--)
if (A[i][j]>0 && A[i][j]<INF)
{
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->weight=A[i][j];
p->nextarc=G->adjlist[i].firstarc;
G->adjlist[i].firstarc=p;
}
}
void DestroyGraph(AdjGraph *&G) //销毁图
{
int i;
ArcNode *pre,*p;
for (i=0;i<G->n;i++) //释放边结点所占空间
{
pre=G->adjlist[i].firstarc;
if (pre!=NULL)
{
p=pre->nextarc;
while (p!=NULL)
{
free(pre);
pre=p; p=p->nextarc;
}
free(pre);
}
}
free(G); //释放G所指的内存空间
}
void DispGraph(AdjGraph *G) //输出图的邻接表
{
ArcNode *p;
int i;
for (i=0;i<G->n;i++)
{
printf(" [%2d]",i);
p=G->adjlist[i].firstarc; //p指向第一个邻接点
if (p!=NULL)
printf(" →");
while (p!=NULL)
{
printf(" %d(%d)",p->adjvex,p->weight);
p=p->nextarc; //p移向下一个邻接点
}
printf("\n");
}
}
int Degree1(AdjGraph *G,int v) //求无向图G中顶点v的度
{
int d=0;
ArcNode *p;
if (v<0 || v>=G->n)
return -1; //顶点编号错误返回-1
p=G->adjlist[v].firstarc;
while (p!=NULL) //统计v顶点的单链表中边结点个数即度
{
d++;
p=p->nextarc;
}
return d;
}
int Degree2(AdjGraph *G,int v) //求有向图G中顶点v的度
{
int i,d1=0,d2=0,d;
ArcNode *p;
if (v<0 || v>=G->n)
return -1; //顶点编号错误返回-1
p=G->adjlist[v].firstarc;
while (p!=NULL) //统计v顶点的单链表中边结点个数即出度
{
d1++;
p=p->nextarc;
}
for (i=0;i<G->n;i++) //统计边结点中adjvex为v的个数即入度
{
p=G->adjlist[i].firstarc;
while (p!=NULL)
{
if (p->adjvex==v) d2++;
p=p->nextarc;
}
}
d=d1+d2;
return d;
}
void FindallPath(AdjGraph *G,int u, int v,int path[ ],int d, int l){
ArcNode *p;int w,i;
visited[u]=1;
d++; path[d]=u;
if(u==v && d==l)
{ for(i=0;i<=d;i++)
printf(" %d",path[i]);
printf("\n");
}
p=G->adjlist[u].firstarc;
while(p!=NULL)
{
w=p->adjvex;
if(visited[w]==0)
FindallPath(G, w,v, path,d, l);
p=p->nextarc;
}
visited[u]=0;
}
int main(){
AdjGraph *G;
int n=5,e=8,i;
int path[MAXVEX],d=-1;
int u=0,v=4,l=3; // 设置路径长度为3
int A[MAXVEX][MAXVEX]={
{0,1,1,1,0},{1,0,1,1,0},{1,1,0,1,1},{1,1,1,0,1},{0,0,1,1,0} };
CreateGraph(G,A,n, e);
for (i=0;i< G->n;i++)
visited[i]=0;
printf("从顶点%d到%d的长度为%d的所有简单路径:\n",u,v,l);
FindallPath(G,u, v, path, d, l); // 传入路径长度参数l
DestroyGraph(G);
}
实验结果(运)行图: