递归遍历图及邻接矩阵的理解

回溯的实现

深度遍历图最重要的思想:回溯。递归遍历二叉树就是一种回溯

递归遍历图为什么要循环 里 递归调用?

要先理解邻接矩阵:

因为是二维数组存图,既要知道行数(作为要选择路径的节点!),又要遍历列数(该节点要选择哪些路径节点!)。所以每一次进入for()循环 就是在选一个路径节点,每一次递归调用就是进入到下一个要选择路径的节点
所以需要循环(遍历找路径)里面套递归调用(找到一个节点路径,进入该节点!),并且需要传递列数作为下一层递归的行数
最后,当递归子程序跳到上一层,接着执行上一层未完的递归子程序,直到结束。

重要代码:

typedef struct
{
	VertexType Vertex[VertexMax];//存顶点的一维数组
	int AdjMatrix[VertexMax][VertexMax];//邻接矩阵二维数组
	int vexnum, arcnum;//图的顶点数和边数 
}MGraph;

//"标志"数组,代表是否访问 
int visited[VertexMax];

//这里的int i 指的是每次递归的矩阵行数,即作为要选择路径的节点!所以需要先输出他,然后找下一个
void DFS(MGraph *G, int i)
{
	int j;
	
	//处理起始点
	printf("%c", G->Vertex[i]);
	visited[i]=1; 
	
	//递归的出口是for循环全部执行完,即j>=G->vexnum,每一个递归子程序都有自己的出口,
	//跳出则进入上一层的递归
	for(j=0; j<G->vexnum; j++){
		//有边 && 没有被访问过 -> 递归调用
		if(G->AdjMatrix[i][j]==1 && visited[j]==0){
			DFS(G,j);
		}
	}
}

完整代码

//邻接矩阵深度遍历图 
#include <stdio.h>
#include <stdlib.h>
#define VertexMax 100 //最大顶点数为100

typedef char VertexType; //每个顶点的数据类型为字符型

//图的数据结构 
typedef struct
{
	VertexType Vertex[VertexMax];//存顶点的一维数组
	int AdjMatrix[VertexMax][VertexMax];//邻接矩阵二维数组
	int vexnum, arcnum;//图的顶点数和边数 
}MGraph;

void DFS(MGraph *, int ); 

//查找元素V在一维数组的下标
int LocationVex(MGraph *G, VertexType v)
{
	int i;
	
	for(i=0; i<G->vexnum; i++){
		if(G->Vertex[i] == v){
			return i;
		}
	}
	
	printf("未找到该顶点%c", v);
	return -1;
} 

//建立图,使用邻接矩阵存储
void CreateUDG(MGraph *G)
{
	int i, j;
	printf("输入该图顶点数和边数:\n");
	printf("顶点数 n=");
	scanf("%d", &G->vexnum);
	printf("边数 e=");
	scanf("%d", &G->arcnum);
	
	printf("\n");
	
	printf("输入顶点元素名称(不需要空格隔开):");
	scanf("%s", G->Vertex);
	printf("\n");
	
	//初始化矩阵 
	for(i=0; i<G->vexnum; i++){
		for(j=0; j<G->vexnum; j++){
			G->AdjMatrix[i][j] = 0;
		}
	} 
	
	int n, m;//两节点所在的位置,方便后续得到邻接矩阵 
	VertexType v1, v2;//接收输入的节点 
	
	printf("请输入边的两点信息:\n");
	for(i=0; i<G->arcnum; i++){
		scanf(" %c%c", &v1,&v2);
		n = LocationVex(G, v1);
		m = LocationVex(G, v2);
		
		//若两节点不存在 
		if(m==-1 || n==-1){
			printf("该边不存在!");
			return;
		}
		
		//邻接矩阵赋值 
		G->AdjMatrix[n][m] = 1;
		G->AdjMatrix[m][n] = 1;		
	} 
	
}

void print(MGraph G)
{
	int i, j;
	printf("\n");
	printf("\n邻接矩阵\n\n");
	
	//打印横表头
	printf("      "); 
	for(i=0; i<G.vexnum; i++){
		printf(" %c", G.Vertex[i]);
	}
	printf("\n");
	//打印列表头及邻接矩阵数据
	for(i=0; i<G.vexnum; i++){
		printf("     %c", G.Vertex[i]);
		for(j=0; j<G.vexnum; j++){
			printf(" %d", G.AdjMatrix[i][j]);
		}
		printf("\n");
	} 
	
} 

//"标志"数组,代表是否访问 
int visited[VertexMax];

void DFSTraverse(MGraph *G)
{
	int i;
	//初始化"标志"数组为0,代表未访问
	for(i=0; i<G->vexnum; i++){
		visited[i] = 0;
	} 
	
	for(i=0; i<G->vexnum; i++){
		if(visited[i] == 0){
			DFS(G,i);
		}
	} 
}

void DFS(MGraph *G, int i)
{
	int j;
	
	//处理起始点
	printf("%c", G->Vertex[i]);
	visited[i]=1; 
	
	for(j=0; j<G->vexnum; j++){
		if(G->AdjMatrix[i][j]==1 && visited[j]==0){
			DFS(G,j);
		}
	}
}

int main() 
{
	MGraph G;
	CreateUDG(&G);
	print(G); 

	printf("\n\n深度优先遍历:"); 
	DFSTraverse(&G); 
	 
	return 0;
}	





 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值