图的深度优先遍历DFS (邻接矩阵实现) c语言

图的遍历是指从图中的某一顶点出发,按照一定的策略访问图中的每一个顶点。每个顶点有且只能被访问一次。

深度优先遍历也叫深度优先搜索(Depth First Search)。

它的遍历规则:先选择一个初始顶点,再规定一个方向,例如往右边一直遍历。于是就往右边一直走,把访问过的顶点做好标记,沿着右边访问完后,回溯到之前访问过的顶点,找找还有没有顶点没有访问的,当所有顶点被访问,完成遍历。

DFS是一个递归地将图中所有顶点访问的过程,类似于树的前序遍历。

用邻接矩阵实现时需注意设置一个布尔类型的访问标志数组  visited

对于m个顶点e条边的图来说,由于邻接矩阵是一个二维数组,故时间复杂度O(㎡)

具体实现代码如下,

#include<stdio.h>
#include<stdlib.h>
//邻接矩阵结构
typedef char VertexType;
typedef int EdgeType;

#define MAX 10
#define INFINITY 65535
#define TRUE 1
#define FALSE 0
typedef int Boole;  //布尔类型 存储TRUE FALSE
Boole visited[MAX];    //访问标志数组 

typedef struct
{
	VertexType vexs[MAX];   //顶点表 
	EdgeType arc[MAX][MAX];   //邻接矩阵 可看作边表   
	int numVertexes,numEdges;
	int GraphType;  //图的类型  无向0,有向1	
}MGraph;

//构造图   有向图和无向图 
void create(MGraph *G)
{
	int i,j,k,w;
	printf("请输入顶点数和边数:\n");
	scanf("%d%d",&G->numVertexes,&G->numEdges);
	fflush(stdin);
	for(i=0;i<G->numVertexes;i++)     //建立顶点表
	{ 
		printf("\n第%d个顶点",i+1);
		scanf("%c",&G->vexs[i]);
		getchar();
	}
	
	for(i=0;i<G->numVertexes;i++)   //矩阵初始化 
		for(j=0;j<G->numVertexes;j++)
			G->arc[i][j]=INFINITY;
			
	for(k=0;k<G->numEdges;k++)
	{
		printf("输入边(Vi,Vj)的上下标i,j和权w(空格隔开):");
		scanf("%d%d%d",&i,&j,&w);
		G->arc[i][j]=w;
		if(G->GraphType==0)      //此时为无向图   有向图与无向的区别就只是这一行代码的有无 
		G->arc[j][i]=G->arc[i][j];
	}			 
} 

void Output(MGraph *G)     //输出邻接矩阵 
{
	int i,j,count=0;
	for(i=0;i<G->numVertexes;i++)
		printf("\t%c",G->vexs[i]);
	printf("\n");
	for(i=0;i<G->numVertexes;i++)
	{
		printf("%4c",G->vexs[i]);
		for(j=0;j<G->numVertexes;j++)
		{	
			
				printf("\t%d",G->arc[i][j]);
				count++;
				if(count%G->numVertexes==0)
				printf("\n");	
		} 
    }	 
 } 




/*深度优先遍历*/



//深度优先递归算法
void DFS(MGraph G,int i)
{
	int j;
	visited[i]=TRUE;   //被访问的标记 
	printf("%c->",G.vexs[i]);
	for(j=0;j<G.numVertexes;j++)
	{
		if(G.arc[i][j]==1&&!visited[j])   //边(i,j)存在且j顶点未被访问,递归 
			DFS(G,j);
	} 
}

//深度优先遍历
void DFStraverse(MGraph G)
{
	
	int i;
	for(i=0;i<G.numVertexes;i++)
		visited[i]=FALSE;
	for(i=0;i<G.numVertexes;i++)
			if(!visited[i])
				DFS(G,i);		
				
} 


int main()
{
	MGraph G;
	int i,j;
	printf("输入生成图的类型(无向图0/有向图1):");
	scanf("%d",&G.GraphType);
	create(&G);	
	printf("邻接矩阵数据如下:\n");
	Output(&G);
	printf("\n");
	DFStraverse(G);
	printf("\n图遍历完毕");
	return 0;	 
}
 

 

  • 43
    点赞
  • 228
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
以下是C++实现邻接矩阵存储和深度优先遍历以及广度优先遍历的代码示例: 1. 邻接矩阵存储 ```c++ #define MAXVEX 100 // 最大顶点 #define INFINITY 65535 // 用65535来代表无穷大 typedef struct { int vexs[MAXVEX]; // 存储顶点组 int arc[MAXVEX][MAXVEX]; // 存储边的二维组 int numVertexes, numEdges; // 中当前的顶点和边 } MGraph; // 创建邻接矩阵 void CreateMGraph(MGraph *G) { int i, j, k, w; printf("请输入顶点和边:\n"); scanf("%d,%d", &G->numVertexes, &G->numEdges); for (i = 0; i < G->numVertexes; i++) { printf("请输入第%d个顶点:", i + 1); scanf("%d", &G->vexs[i]); } for (i = 0; i < G->numVertexes; i++) { for (j = 0; j < G->numVertexes; j++) { G->arc[i][j] = INFINITY; // 初始化邻接矩阵 } } for (k = 0; k < G->numEdges; k++) { printf("请输入边(vi,vj)的下标i,下标j和权值w:\n"); scanf("%d,%d,%d", &i, &j, &w); G->arc[i][j] = w; G->arc[j][i] = G->arc[i][j]; // 无向对称 } } ``` 2. 深度优先遍历 ```c++ bool visited[MAXVEX]; // 记录顶点是否被访问过 // 邻接矩阵的深度优先递归算法 void DFS(MGraph G, int i) { int j; visited[i] = true; printf("%d ", G.vexs[i]); for (j = 0; j < G.numVertexes; j++) { if (G.arc[i][j] != INFINITY && !visited[j]) { DFS(G, j); } } } // 邻接矩阵的深度遍历操作 void DFSTraverse(MGraph G) { int i; for (i = 0; i < G.numVertexes; i++) { visited[i] = false; } for (i = 0; i < G.numVertexes; i++) { if (!visited[i]) { DFS(G, i); } } } ``` 3. 广度优先遍历 ```c++ // 邻接矩阵的广度遍历算法 void BFSTraverse(MGraph G) { int i, j; queue<int> Q; for (i = 0; i < G.numVertexes; i++) { visited[i] = false; } for (i = 0; i < G.numVertexes; i++) { if (!visited[i]) { visited[i] = true; printf("%d ", G.vexs[i]); Q.push(i); while (!Q.empty()) { int k = Q.front(); Q.pop(); for (j = 0; j < G.numVertexes; j++) { if (G.arc[k][j] != INFINITY && !visited[j]) { visited[j] = true; printf("%d ", G.vexs[j]); Q.push(j); } } } } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值