数据结构(C语言实现)-图(2)(图的遍历:深度优先、广度优先算法)

深度优先搜索(DFS)

类似树的前序遍历,规定以某节点为根节点,从根结点出发,在没碰到重复顶点的情况下,遇到分叉路口就始终向右手边走,每路过一个顶点就做一个记号,没无路可走时就回退一步,走另一个分岔路口。
接下来是DFS的递归实现,图的存储结构及创建使用前一篇写过的邻接表。结合上一篇文章的邻接表部分的代码可以实现编译运行。

bool Visited[MAX_VERTEX_NUM]; //为了避免同一顶点被访问多次,设置此标记数组

void DFS(Graph G,int v)       //从第v个顶点出发,深度优先遍历图G
{
	if(Visited[v]==false)     //如果该顶点没有被访问过
	{
		Visited[v] = true;    //标记为访问过
		printf("%c",G->vertices[v].data); //输出数据
	}
	
	ArcNode *arc;
	arc = G->vertices[v].firstarc;//arc保存与此顶点相连的第一条弧
	while(arc != NULL)            //若刚访问过的顶点 存在 与之相连的边(顶点)
	{
		if (Visited[arc->adjvex] = false) //若与之相连的顶点没有被访问过
			DFS(G,arc->adjvex);           //从相连的顶点开始继续递归访问
		arc = arc -> nextarc;             //arc指向与此边相连的下一条边(下一个顶点)
	}
}

void DFS_traverse(Graph G,int t)      //给定初始顶点数组序号t,遍历整个图结构
{
	for (int v = 0;v<G->vexnum;v++)   //Visited数组初始化
		Visited[v] = false;

	DFS(G,t);    //访问初始给定顶点
	for(int v = 0;v<G->vexnum;v++)    //访问剩余漏下的顶点(其他连通分量)
	{
		if(Visited[v] == false)
			DFS(G,v);
	}
}

广度优先搜索(BFS)

类似树的层序遍历,规定以某节点为根节点,从根节点出发,依次访问与此结点相邻的所有结点,然后从这些邻接点出发再依次访问它们的邻接点。需注意:应使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问。
BFS一般借助队列实现,图结构采用前一篇写过的邻接表,结合之前写过的邻接表和队列的代码,可以使下列程序编译运行。

bool Visited[MAX_VERTEX_NUM]; //为了避免同一顶点被访问多次,设置此标记数组

void BFS_traverse(Graph G,int t)     //给定初始顶点数组序号t,遍历整个图结构
{
	for (int v = 0;v<G->vexnum;v++)  //Visited数组初始化
		Visited[v] = false;
	SqQueue Q;            //建立队列并初始化
	InitQueue(Q);

	for(int v = 0;v<vexnum;v++)
	{
		if(Visited[v] == false)     //该顶点没有访问过
		{
			Visited[v] = true;      //标志数组置1
			printf("%c",G->vertices[v].data); //访问数据
			
			EnQueue(Q,v);           //顶点v入队
			while(Q.front != Q.rear)//若队列中有元素
			{
				int temp;
				DeQueue(Q,temp);    //顶点v出队并将其记录在临时变量temp中
				ArcNode *arc;
				arc = G->vertices[v].firstarc;//arc保存与此顶点相连的第一条弧
				for(int w=arc->adjvex; arc!=null; w=arc->nextarc->adjvex,arc=arc->next)//与v相邻的所有顶点
					if(Visited[w]=false)      //w为未访问过的相邻顶点,访问这些顶点并使其依次入队
					{
						Visited[w]=true;
						printf("%c",G->vertices[w].data); //访问数据
						EnQueue(Q,w);
					}
			}
		}
	}
]
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值