图的深度优先遍历

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

属于是学到了图论的遍历,深度的优先遍历运用的比较多。深度优先遍历其实就是一个递归的过程,也就是树的前序遍历。而图的广度优先遍历类似于树的层序遍历。


在完成

相应的图的编程作业,二叉树的作业中,也都运用了多次C语言中的scanf,也让我学到了新的知识点。每次运用完一次scanf,其实回车都被保存了,会在下一次scanf的使用被赋予,就直接导致程序的结束。所以中间应该加入getchar()

scanf("%d %d",&m,&n);
getchar();  
scanf("%c%c", &c1, &c2);

在图的作业中,寻找两个顶点间是否存在路径和一个图中有几个连通分量,都运用到了深度优先遍历。所以准备记录一下,使用的一些代码。

图的两个顶尖是否存在路径

​
#include <stdio.h>

#define MAX 100

typedef struct Tree 
{
	char vexs[MAX]; \\顶点表
	int arc[MAX][MAX]; \\邻接矩阵
	int numt,nume; \\顶点数和边数
} TNree;

void TU(TNree * t,char a[MAX],int &y) \\创建图的邻接矩阵(无向图)
{
	int m,n,i=0,j=0,p,q;
	while(a[i]!='!')
	{
		t->vexs[i] = a[i];
		i++;
	}
	y = i; \\就是图的顶点数
	for(p=0;p<i;p++) //初始化
	{
		for(q=0;q<i;q++)
		{
			t->arc[p][q] = 0;
		}
	}
	for(j=0;j<MAX;j++) 
	{
		scanf("%d %d",&m,&n);
		if(m==-1&&n==-1)
		{
			break;
		}
		t->arc[m][n] = 1; \\无向图的邻接矩阵是对称的 
	}
}

void HANTAO(TNree *t,int m) \\输出整个邻接矩阵
{
	int i,j;
	for(i = 0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			printf("%d ",t->arc[i][j]);
		}
		printf("\n");
	}
}

void wuyu(TNree *t,int &i,int &j,int h) \\寻找两个顶点的下标
{
		int m,n;
	char c1, c2;
getchar();  
scanf("%c%c", &c1, &c2);

		

	for(m=0;m<h;m++)
	{
		if(t->vexs[m]==c1)
		{
			i = m;
		}
	}
		for(n=0;n<h;n++)
	{
		if(t->vexs[n]==c2)
		{
			j = n;
		}
	}
	
	
}


void DFS(TNree *t, int i, int j, int visited[], int *result,int m) \\深度的优先遍历
{
	int k;
    if (i == j) {  
        *result = 1;  \\两个顶点间存在路径。
    }
    visited[i] = 1;  
    for (k = 0;k<m; k++) {
        if (t->arc[i][k] != 0 && !visited[k]) //如果两个顶点间存在路径,并且未被调用过
		 {  
            DFS(t, k, j, visited,result,m); 
        }
    }
}


int main()
{
	int i,j;
	TNree t;
	char a[MAX];
	int result = 0;
	int visited[MAX] = {0}; //数组的初始化,全为0
	char g;
	int n,m;
	for(n=0;n<MAX;n++)
	{
		scanf("%c",&a[n]);
		if(a[n]=='!')
		{
			break;
		}
	}
	TU(&t,a,m);
	
	wuyu(&t,i,j,m);
	HANTAO(&t,m);
	printf("\n");

	
	DFS(&t,i,j,visited,&result,m);
	if (result) {
    printf("T\n");  // 存在路径
	} 
	else 
	{
	printf("F\n");  // 不存在路径
   }
	return 0;
}

​

图存在几个连通分量

#include <stdio.h>

#define MAX 100

typedef struct Tree
{
	char vexs[MAX];
	int arc[MAX][MAX];
	int numt,nume;
} TNree;

void TU(TNree * t,char a[MAX],int &y)
{
	int m,n,i=0,j=0,p,q;
	while(a[i]!='!')
	{
		t->vexs[i] = a[i];
		i++;
	}
	y = i;
	for(p=0;p<i;p++)
	{
		for(q=0;q<i;q++)
		{
			t->arc[p][q] = 0;
		}
	}
	for(j=0;j<MAX;j++)
	{
		scanf("%d %d",&m,&n);
		if(m==-1&&n==-1)
		{
			break;
		}
		t->arc[m][n] = 1;
		t->arc[n][m] = 1;
	}
}

void DFS(TNree *t, int i,int m,int visited[]) {
	int k;
    visited[i] = 1;  
    for (k = 0;k<m; k++) {
        if (t->arc[i][k] != 0 && !visited[k])
		 {  
            DFS(t, k,m,visited);
        }
    }
}


int main()
{
	TNree t;
	int visited[MAX]={0};
	char a[MAX];
	int n,m,count=0;
	for(n=0;n<MAX;n++)
	{
		scanf("%c",&a[n]);
		if(a[n]=='!')
		{
			break;
		}
	}
	TU(&t,a,m);
	for(n=0;n<m;n++)
	{
		if(!visited[n])
		{
			DFS(&t,n,m,visited);
			count++;
		}
	}
	printf("%d",count);
	return 0;
}

思路其实也就是开始从0深度遍历,在DFS里就会走完一个联通图,将其visited都变为1,这样就得到一个连通分量了。之后如果还有visited不为1,那就又得到一个新的连通分量。


总结

其实学完图的深度和广度优先遍历,在写作业时,完全没想到可以用在查图两个顶点是否存在路径和有几个连通分量,还是在网上参考了别人,才意识到深度优先遍历,作用这么大。只能说还是得多写写,多练练,多想想。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值