图的遍历DFS和BFS代码实现

图的深度优先遍历是树的先序遍历的延伸,先序遍历是DFS的特殊情况。从图中任选一个顶点v,访问后开始随意选一个邻接点,从新的邻接点开始进行DFS,以此类推,这是一个递归的过程,直到遍历完图中所有结点。

实际上,递归算法的本质就是一个栈,递归算法消耗大量的内存存储临时变量和中间状态,但是代码更简单。(至于用不用递归,就看实际需求吧)

图的非递归深度优先遍历,引入一个数组和一个栈,数组visit[]用来记录每个结点被访问的状态,没有被访问是0,访问过是1,另外引入一个栈,用来存储访问过的结点,每访问一个结点就将它入栈,当某个结点不存在邻接点时,出栈,然后寻找栈顶元素的邻接点,如果没有,继续出栈,直到找到邻接点为止,如果栈空了仍然没有找到,说明一个连通图已经被遍历过了。如果是不连通图,从visit数组中可以发现还有没有遍历到的结点,就从这些结点中(另外一个图中)随机挑选一个结点作为第一个结点入栈,开始新的遍历。

图的广度优先遍历是一个非递归的过程,当然可以写成递归,但是没必要。广度优先遍历借助于一个visit数组和一个队列来实现,首先访问图中任意一个结点并入队列,然后将该结点的所有邻居入队,然后队列的第一个结点出队,访问队头结点,并将队头结点的邻居入队,然后队头结点出队,以此类推。。。最终就可以实现图的广度优先遍历。

接下来我们将以上图为例进行图的代码演示,使用邻接矩阵方法表示一个图,并实现图的深度优先遍历(递归)以及图的广度优先遍历。 

Graph_matrix.h

#ifndef _GRAPH_MATRIX_H
#define _GRAPH_MATRIX_H
#define MAX_VERTEX_NUM 100
typedef struct
{
	int n;//顶点数
	int e;//边数
	char vexs[MAX_VERTEX_NUM];
	int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
}Graph;
void CreateMGraph(Graph *G);
void DFS_Recur(Graph G, int i);
void BFS(Graph G);
#endif // !_GRAPH_MATRIX_H

SeqQueue.h

#ifndef _SEQQUEUE_H
#define _SEQQUEUE_H
#define MAXSIZE 50
typedef struct Queue * SeqQueue;
struct Queue
{
	int front; //队伍头
	int rear; //队伍尾
	char data[MAXSIZE];//数据
};

SeqQueue Create();//初始化操作,建立一个空队列
int IsEmpty(SeqQueue Sq);//是否为空
int Del(SeqQueue Sq);//出队
void Insert(SeqQueue Sq, char val);//插入
int GetHead(SeqQueue Sq);//获取队列的头元素
void Clear(SeqQueue Sq);//将队列清空
void Destory(SeqQueue Sq);//销毁队列
#endif // !_SEQQUEUE_H

Operation.cpp

#include <stdio.h>
#include <stdlib.h>
#include"Graph_matrix.h"
#include"SeqQueue.h"
void CreateMGraph(Graph *G)
{
	//方便起见,我们直接自动创建这个图。
	int i, j;
	G->n = 8;
	G->e = 9;
	for (int i = 0; i < G->n; i++)
	{
		G->vexs[i] = 'A' + i;
	}
	for(i = 0;i < G->n;i++)
		for (j = 0; j < G->n; j++)
		{
			G->edges[i][j] = 0;//初始化为最大值,我们假设0表示两个结点无连接
		}
	G->edges[0][1] = 1;
	G->edges[0][2] = 1;
	G->edges[1][0] = 1;
	G->edges[1][3] = 1;
	G->edges[1][5] = 1;
	G->edges[2][0] = 1;
	G->edges[2][4] = 1;
	G->edges[2][6] = 1;
	G->edges[3][1] = 1;
	G->edges[3][7] = 1;
	G->edges[4][2] = 1;
	G->edges[4][6] = 1;
	G->edges[5][1] = 1;
	G->edges[5][7] = 1;
	G->edges[6][2] = 1;
	G->edges[6][4] = 1;
	G->edges[7][3] = 1;
	G->edges[7][5] = 1;
}
int visit[MAX_VERTEX_NUM] = {0};//标志某个顶点是否被访问过
void DFS_Recur(Graph G, int i)//深度优先遍历算法的递归方法
{
	int j;
	visit[i] = 1;//将当前访问顶点的访问标志位设置为1
	printf("%c", G.vexs[i]);
	for (j = 0; j < G.n; j++)
	{
		//若j对应的顶点未被访问,则访问
		if (G.edges[i][j] == 1 && visit[j] == 0)
			DFS_Recur(G, j);
	}
}

int visit1[MAX_VERTEX_NUM] = { 0 };//标志某个顶点是否被访问过

void BFS(Graph G)//广度优先遍历
{
	int i, j;
	SeqQueue Q = Create();//创建一个队列并初始化
	for (i = 0; i < G.n; i++)
	{
		visit1[i] = 0;
	}
	i = 0;
	if (visit1[i] == 0)
	{
		visit1[i] = 1;
		printf("%c", G.vexs[i]);
		Insert(Q, 65 + i); //将结点对应的字母入队ABCDEFG
	}
	while (!IsEmpty(Q))
	{
		//printf("%d", i);
		for (j = 0; j < G.n; j++)
		{
			//访问当前结点的待访问临近结点
			if (G.edges[i][j] == 1 && visit1[j] == 0)
			{
				visit1[j] = 1;
				printf("%c", G.vexs[j]);
				Insert(Q, 65 + j);//入队
			}
		}
		Del(Q);	
		i = GetHead(Q) - 65;
	}
	
}

SeqQueue.cpp

#include "SeqQueue.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

SeqQueue Create()
{
	SeqQueue Sq = (SeqQueue)malloc(sizeof(struct Queue));//分配空间
	Sq->front = Sq->rear = -1;
	memset(Sq->data, 0, MAXSIZE * sizeof(char));//清空内存空间,从Sq的第一个空间data开始清空一整片内存
	return Sq;
}

int IsEmpty(SeqQueue Sq)
{
	if (Sq->front == Sq->rear)
	{
		return 1;
	}
	return 0;
}

void Insert(SeqQueue Sq, char val)
{
	if (Sq->rear == MAXSIZE - 1)//如果队列已满
	{
		printf("队列已满,无法再插入元素!\n");
		return;
	}
	//如果队列是空队列
	if (IsEmpty(Sq))
	{
		Sq->front = Sq->rear = 0;
		Sq->data[Sq->rear] = val;
		Sq->rear++;
	}
	else
	{
		Sq->data[Sq->rear] = val;
		Sq->rear++;
	}
}

int Del(SeqQueue Sq)
{
	//空队列
	if (IsEmpty(Sq))
	{
		printf("队列为空,无元素可以弹出!\n");
		return 10000;
	}
	int temp = Sq->data[Sq->front];
	Sq->front++;
	return temp;
}

int GetHead(SeqQueue Sq)
{
	//空队列
	if (IsEmpty(Sq))
	{
		//printf("队列为空,无元素可取!\n");
		return 10000;
	}
	//获取元素
	return Sq->data[Sq->front];
}

void Clear(SeqQueue Sq)
{
	Sq->front = Sq->rear = -1;
	printf("队列已清空!\n");
}

void Destory(SeqQueue Sq)
{
	free(Sq);
	printf("队列已销毁!\n");
}

main.cpp

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

int main()
{
	Graph G;
	CreateMGraph(&G);
	DFS_Recur(G, 0);
	printf("\n");
	BFS(G);
	system("pause");
}
发布了12 篇原创文章 · 获赞 927 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/zcg_741454897/article/details/103697795