[图] 7.28 找出u到v的所有路径-邻接表(有向图)-DFS

版权声明:本文为博主原创文章,若有错误之处望大家批评指正!转载需附上原文链接,谢谢! https://blog.csdn.net/summer_dew/article/details/83009121

题目来源:严蔚敏《数据结构》C语言版本习题册 7.28

【题目】已知有向图和图中两个顶点u和v,试编写算法求有向图中从u到v的所有简单路径,并以下图为例手工执行你的算法,画出相应的搜索过程图

【测试数据】
在这里插入图片描述

【结果】
在这里插入图片描述

【答案】

/*----------------------------------------------------------------
 |7.28 有向图-从u-v的所有简单路径                                |
 ----------------------------------------------------------------*/
int visit[MAX_VERTEX_NUM]; //前面定义了
VertexType paths[maxSize][MAX_VERTEX_NUM]; //存放路径
int path[MAX_VERTEX_NUM]; //路径
int pathnum=0; //当前是第几条路径
void FindAllPath(ALGraph G, int u,int v,int k) { //u->v当前是第k个位置
	int i;
	ArcNode *p;
	visit[u]=1; //走到了u
	path[k]=u; //添加到路径->下标位置为k的结点是u(第k+1个是u)
	if (u==v) { //找到了
		for (i=0; i<=k; i++) {//复制到paths
			paths[pathnum][i] = G.vers[path[i]].data;
		}
		paths[pathnum][i]='\0'; //结束符
		pathnum++; //找下一条路径
	} else {
		//u的邻边开始找
		for (p=G.vers[u].firstarc; p; p=p->next) {
			if (visit[p->adjV]==0)
				FindAllPath(G, p->adjV, v, k+1); //去这个邻接点找
		}
	}
	// 回溯到上一个结点
	// 注意:回溯应该写在外面-->也就是不管有没有找到都要回溯
	visit[u]=0;
	path[k]=0;
}

【完整代码】

#include<stdio.h>
#include<stdlib.h>

#ifndef BASE
#define BASE
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int bool;
#endif

#define VertexType char //点类型
#define VRType int //边类型
#define maxSize 100
void Visit(VertexType e) {
	printf("%c", e);
}

#define MAX_VERTEX_NUM 20
typedef enum{DG, UDG} GraphKind;
typedef struct ArcNode{
	int adjV; //边指向的顶点
	VRType weight; //权重
	struct ArcNode *next;
}ArcNode; //边
typedef struct VNode{
	VertexType data;
	ArcNode *firstarc;
}VNode, AdjList[MAX_VERTEX_NUM]; //顶点
typedef struct{
	GraphKind kind;
	int vernum,arcnum;
	AdjList vers; 
}ALGraph;


/*------------------------
 |7.14 创建有向图的邻接表|
 ------------------------*/
Status InitGraph_AL(ALGraph *pG) { //初始化
	int i;
	pG->arcnum = 0;
	pG->vernum = 0;
	for (i=0; i<MAX_VERTEX_NUM; ++i)
		pG->vers[i].firstarc = NULL; //VC++6.0中指针初始化为0xcccccccc
	return OK;
}
int LocateVex_AL(ALGraph G, VertexType e) { //定位值为e的元素下标
	int i;
	for (i=0; i<G.vernum; ++i) {
		if (G.vers[i].data == e) {
			return i;
		}
	}
	return -1;
}
Status CreateDG_AL(ALGraph *pG) { //创建有向图的邻接表
	//输入规则:顶点数目->弧的数目->各顶点的信息->各条弧的信息
	int i,a,b;
	char tmp[MAX_VERTEX_NUM];
	char h,t;
	ArcNode *p, *q;

	InitGraph_AL(pG); //VC++6.0中指针初始化为0xcccccccc,如果不将指针初始化为NULL,会出错
	//图的类型
	pG->kind = DG;
	//顶点数目
	scanf("%d", &i); if (i<0) return ERROR;
	pG->vernum = i;
	//弧的数目
	scanf("%d", &i); if (i<0) return ERROR;
	pG->arcnum = i;
	//各顶点信息
	scanf("%s", tmp);
	for (i=0; i<pG->vernum; ++i) pG->vers[i].data=tmp[i];
	//弧的信息
	for (i=0; i<pG->arcnum; ++i) {
		scanf("%s", tmp);
		h = tmp[0]; t = tmp[2];
		a = LocateVex_AL(*pG, h);
		b = LocateVex_AL(*pG, t);
		if (a<0 || b<0) return ERROR;
		p = (ArcNode *)malloc(sizeof(ArcNode)); if (!p) exit(OVERFLOW);
		p->adjV=b;p->next=NULL;
		if (pG->vers[a].firstarc) { //已经有边了
			for (q = pG->vers[a].firstarc; q->next; q=q->next) ; //找到最后一条
			q->next = p;
		} else { //第一条边
			pG->vers[a].firstarc = p;
		}
	}
	return OK;
}

/*----------------------------------------------------------------
 |7.28 有向图-从u-v的所有简单路径                                |
 ----------------------------------------------------------------*/
int visit[MAX_VERTEX_NUM]; //前面定义了
VertexType paths[maxSize][MAX_VERTEX_NUM]; //存放路径
int path[MAX_VERTEX_NUM]; //路径
int pathnum=0; //当前是第几条路径
void FindAllPath(ALGraph G, int u,int v,int k) { //u->v当前是第k个位置
	int i;
	ArcNode *p;
	visit[u]=1; //走到了u
	path[k]=u; //添加到路径->下标位置为k的结点是u(第k+1个是u)
	if (u==v) { //找到了
		for (i=0; i<=k; i++) {//复制到paths
			paths[pathnum][i] = G.vers[path[i]].data;
		}
		paths[pathnum][i]='\0'; //结束符
		pathnum++; //找下一条路径
	} else {
		//u的邻边开始找
		for (p=G.vers[u].firstarc; p; p=p->next) {
			if (visit[p->adjV]==0)
				FindAllPath(G, p->adjV, v, k+1); //去这个邻接点找
		}
	}
	// 回溯到上一个结点
	// 注意:回溯应该写在外面-->也就是不管有没有找到都要回溯
	visit[u]=0;
	path[k]=0;
}


int main() {
/*7.28
6
11
ABCDEF
B,A
B,D
C,B
C,F
D,C
D,E
D,F
E,A
F,A
F,B
F,E
B->A
A->B
D->A
*/
	int i,j;
	int cnt;
	ALGraph G;
	char tmp[20];

	CreateDG_AL(&G);

	while (1) {
		scanf("%s", tmp); //A->B
		i = LocateVex_AL(G, tmp[0]);
		j = LocateVex_AL(G, tmp[3]);
		for (cnt=0; cnt<MAX_VERTEX_NUM; cnt++) visit[cnt]=0;
		pathnum=0;
		printf("7.28 输出所有 %c 到 %c 的路径\n", tmp[0], tmp[3]);
		FindAllPath(G, i, j, 0);
		if (pathnum==0) {
			printf("\t- 走不通\n");
		}
		for (i=0; i<pathnum; i++) {
			printf("\t%d %s\n", i+1, paths[i]);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/summer_dew/article/details/83009121