BFS与DFS

邻接矩阵存储图的DFS与BFS

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

typedef enum {FALSE, TRUE} BOOL;
#define MaxVertexNum 10  /* 最大顶点数设为10 */
#define INFINITY 65535   /* ∞设为双字节无符号整数的最大值65535*/
typedef char Vertex;      /* 用顶点下标表示顶点,为字符型 */
typedef int WeightType;  /* 边的权值设为整型 */

typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;  /* 顶点数 */
    int Ne;  /* 边数   */
    WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
	Vertex vertex[MaxVertexNum];
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
BOOL Visited[MaxVertexNum]; /* 顶点的访问标记 */

MGraph CreateGraph(); /* 创建图并且将Visited初始化为FALSE */
int count(MGraph Graph, Vertex vertex);
void Visit( Vertex V );
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );
void BFS ( MGraph Graph, Vertex S, void (*Visit)(Vertex) );
void reset(MGraph Graph);

int main()
{
    MGraph G;
    G = CreateGraph();
	printf("DFS from %c:    ", G->vertex[0]);
    DFS(G, G->vertex[0], Visit);
	putchar('\n');
	reset(G);
	printf("\nBFS from %c:    ", G->vertex[0]);
    BFS(G, G->vertex[0], Visit);
	putchar('\n');
	system("pause");
    return 0;
}

void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) )//Graph表示邻接矩阵存储的图,V表示当前访问的节点。第三个参数为输出节点的函数
{
	int w, count_V;
	count_V = count(Graph, V);
	Visit(V);//访问到V,输出
	Visited[count_V] = TRUE;//标记V被访问过,此后不再访问
	for (w = 0; w < Graph->Nv; w++){ //数据是0到Graph->Nv(顶点数点数),访问每个节点
		if (Graph->G[count_V][w] < INFINITY && Visited[w] == FALSE){//如果当前节点V与遍历的节点w有边相连,且w没有被访问过
			DFS(Graph, Graph->vertex[w], Visit);//从w开始搜索访问
		}
	}				
}

void BFS ( MGraph Graph, Vertex S, void (*Visit)(Vertex) )//Graph表示邻接矩阵存储的图,V表示当前访问的节点。第三个参数为输出节点的函数
{
	char queue[100], front = 0, rear = 0;//用数组表示队列,front表示队列首,rear表示队列尾
	int w;	//定义邻接点w
	char pos;	//队列首部节点
	int pos_count;
	queue[++rear] = S;//队列存入访问的第一个节点S
    Visited[S] = TRUE;//标记S被访问过,以后不再访问
	while(front != rear){//当队列不为空时(首部没有到达尾部)
		pos = queue[++front];//取出队列首部节点
	    Visit(pos);//输出取出的节点
        pos_count = count(Graph, pos);
		for(w = 0; w < Graph->Nv; w++){//依次访问与pos相连的节点
			if(Graph->G[pos_count][w]<INFINITY && Visited[w] == FALSE){//如果这个节点没有被访问过
	        	Visited[w] = TRUE;//标记这个节点被访问
				queue[++rear] = Graph->vertex[w];//把这个节点加入到队列中
			}
		}
	}
}

MGraph CreateGraph()
{
	int number_vertex, number_edge;
	int i, j, temp, x, y;
	char temp_x, temp_y;
	MGraph graph = NULL;
	printf("请输入顶点的个数与边的个数:");
	scanf("%d %d", &number_vertex, &number_edge);
	graph = (MGraph)malloc(sizeof(struct GNode));
	graph->Nv = number_vertex;
	graph->Ne = number_edge;
	for (i = 0; i < number_vertex; i++){
		for (j = 0; j < number_vertex; j++){
			graph->G[i][j] = INFINITY;
		}
		Visited[i] = FALSE;
	}
	puts("请按矩阵的顺序输入顶点");
	getchar();
	for (i = 0; i < number_vertex; i++){
		scanf("%c", &graph->vertex[i]);
	}
	puts("请输入图中的信息\n起始点\t终端点\t边的权值");
	for (i = 0; i < number_edge; i++)
	{
		getchar();
		scanf("%c %c %d", &temp_x, &temp_y, &temp);
		x = count(graph, temp_x);
		y = count(graph, temp_y);
		graph->G[x][y] = temp;
	}
	return graph;
}

int count(MGraph Graph, Vertex vertex)
{
	int i;
	for (i = 0; i < Graph->Nv; i++)
		if (vertex == Graph->vertex[i])
			return i;
	exit(1);
}

void Visit( Vertex V )
{
    printf(" %c", V);
}

void reset(MGraph Graph)
{
	int i;
	for (i = 0; i < Graph->Ne; i++){
		Visited[i] = FALSE;
	}
}

邻接表存储图的DFS与BFS

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

typedef enum {FALSE, TRUE} BOOL;
#define MaxVertexNum 10   /* 最大顶点数设为10 */
typedef char Vertex;       /* 用顶点下标表示顶点,为字符型 */

/* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;        /* 邻接点下标 */
    PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
};

/* 顶点表头结点的定义 */
typedef struct Vnode{
    PtrToAdjVNode FirstEdge; /* 边表头指针 */
} AdjList[MaxVertexNum];     /* AdjList是邻接表类型 */

/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;     /* 顶点数 */
    int Ne;     /* 边数   */
    AdjList G;  /* 邻接表 */
	Vertex vertex[MaxVertexNum];
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */

BOOL Visited[MaxVertexNum]; /* 顶点的访问标记 */

LGraph CreateGraph(); /* 创建图并且将Visited初始化为false */
int count(LGraph Graph, Vertex vertex);
void Visit( Vertex V );
void DFS( LGraph Graph, Vertex V, void (*Visit)(Vertex) );
void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) );
void reset(LGraph Graph);

int main()
{
    LGraph G;
    G = CreateGraph();
	printf("BFS from %c:", G->vertex[0]);
    DFS(G, G->vertex[0], Visit);
	putchar('\n');
	reset(G);
	printf("\nBFS from %c:", G->vertex[0]);
    BFS(G, G->vertex[0], Visit);
	putchar('\n');
	system("pause");
    return 0;
}

void DFS( LGraph Graph, Vertex V, void (*Visit)(Vertex) )//Graph表示邻接矩阵存储的图,V表示当前访问的节点。第三个参数为输出节点的函数
{
	PtrToAdjVNode w;
	int count_V = count(Graph, V);
	int count_w;
	Visit(V);//访问到V,输出
	Visited[count_V] = TRUE;//标记V被访问过,此后不再访问
	for(w = Graph->G[count_V].FirstEdge; w != NULL; w = w->Next){ //数据是0到Graph->Nv(顶点数点数),访问每个节点
		count_w = count(Graph, w->AdjV);
		if(Visited[count_w] == FALSE){//如果w没有被访问过
			DFS(Graph, w->AdjV, Visit);//从w开始搜索访问
		}
	}				
}

void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) )//Graph表示邻接矩阵存储的图,V表示当前访问的节点。第三个参数为输出节点的函数
{
	int queue[100], front = 0, rear = 0;//用数组表示队列,front表示队列首,rear表示队列尾
	int count_S = count(Graph, S), count_pos, count_AdjV;
	Vertex pos;
	PtrToAdjVNode w;//定义邻接点w
	queue[++rear] = S;//队列存入访问的第一个节点S
    Visited[count_S] = TRUE;//标记S被访问过,以后不再访问
	while(front != rear){//当队列不为空时(首部没有到达尾部)
		pos = queue[++front];//取出队列首部节点
		count_pos = count(Graph, pos);
	    Visit(pos);//输出取出的节点
        
		for(w = Graph->G[count_pos].FirstEdge; w != NULL; w = w->Next){//依次访问与pos相连的节点
			count_AdjV = count(Graph, w->AdjV);
			if(Visited[count_AdjV] == FALSE){//如果这个节点没有被访问过
	        	Visited[count_AdjV] = TRUE;//标记这个节点被访问
				queue[++rear] = w->AdjV;//把这个节点加入到队列中
			}
		}
	}
}

LGraph CreateGraph()
{
	int number_vertex, number_edge;
	int i, x, y;
	char temp_x, temp_y;
	PtrToAdjVNode vnode = NULL, temp_vnode = NULL;
	LGraph graph = NULL;
	printf("请输入顶点的个数与边的个数:");
	scanf("%d %d", &number_vertex, &number_edge);
	graph = (LGraph)malloc(sizeof(struct GNode));
	graph->Nv = number_vertex;
	graph->Ne = number_edge;
	for (i = 0; i < number_vertex; i++){
		Visited[i] = FALSE;
		graph->G[i].FirstEdge = NULL;
	}
	puts("请按矩阵的顺序输入顶点");
	getchar();
	for (i = 0; i < number_vertex; i++){
		scanf("%c", &graph->vertex[i]);
	}
	puts("请输入图中的信息\n起始点\t终端点");
	for (i = 0; i < number_edge; i++)
	{
		getchar();
		scanf("%c %c", &temp_x, &temp_y);
		x = count(graph, temp_x);
		y = count(graph, temp_y);
		vnode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
		vnode->Next = NULL;
		vnode->AdjV = graph->vertex[y];
		if (graph->G[x].FirstEdge == NULL){
			graph->G[x].FirstEdge = vnode;
		}
		else{
			for (temp_vnode = graph->G[x].FirstEdge; temp_vnode->Next != NULL; temp_vnode = temp_vnode->Next);
			temp_vnode->Next = vnode;
		}
	}
	return graph;
}

int count(LGraph Graph, Vertex vertex)
{
	int i;
	for (i = 0; i < Graph->Nv; i++)
		if (vertex == Graph->vertex[i])
			return i;
	exit(1);
}

void Visit( Vertex V )
{
    printf(" %c", V);
}

void reset(LGraph Graph)
{
	int i;
	for (i = 0; i < Graph->Ne; i++){
		Visited[i] = FALSE;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值