深度优先遍历(DFS)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MaXInt 32767 //最大权值,代表无穷大
#define MVNum 10	//最大顶点数
/*
* 无向图的深度优先遍历
*/
//定义图的结构体
typedef struct {
	//顶点数组
	char vex[MVNum];
	//边数组(邻接矩阵)
	int edge[MVNum][MVNum];
	//顶点数,边数
	int vexnum, edgenum;
}Graph;

//辅助数组(标记已被访问过的顶点)
int visited[MVNum];
//初始化辅助数组,数字0代表此顶点未被访问过
void init_visited(Graph *G) {
	for (int i = 0; i < G->vexnum; i++)
	{
		visited[i] = 0;
	}
}


//创建图
void CreateGraph(Graph *G) {
	//初始化总顶点数和总边数
	G->vexnum = 0;
	G->edgenum = 0;
	printf("请输入图的总顶点数和总边数:");
	//输入图的总顶点数和总边数
	scanf("%d %d", &G->vexnum, &G->edgenum);

	/*------------关于顶点--------------*/

	//输入顶点信息
	for (int i = 0; i < G->vexnum; i++)
	{	
		char v;
		printf("请输入第%d顶点信息:",i+1);
		scanf(" %c", &v);
		G->vex[i] = v;
	}
	printf("输入完成!\n");

	/*------------关于边--------------*/

	//初始化邻接矩阵,边的权值
	for (int i = 0; i < G->vexnum; i++){
		for (int j = 0; j < G->vexnum; j++)
		{
			G->edge[i][j] = MaXInt;
		}
	}

	//输入边信息
	int i, j;
	//构造邻接矩阵(输入两个顶点在vex数组中的下标,如果置为1则表示此两点中有边)
	printf("请输入两个顶点(两点间有边)的下标:");
	scanf("%d %d", &i, &j);
	while (i!=-1 && j!=-1)	//循环结束条件
	{
		G->edge[i][j] = 1;
		G->edge[j][i] = 1;	//无向图的邻接矩阵为对称矩阵
		scanf("%d %d", &i, &j);
	}
	
}

//DFS遍历(从下标为v的顶点开始遍历图)
void DFS(Graph *G,int v) {
	 //输出当前第i个顶点
	 printf("%c",G->vex[v]);
	 //将第i个顶点的标志置为已经遍历
	 visited[v] = 1;//表示已经访问过此顶点
	 //循环从i顶点到各个顶点(j)
	 for (int i = v; i < G->vexnum; i++){
		 for (int j = 0; j < G->vexnum; j++)
		 {
			 //循环中判断i和j顶点间是否有边,并且j顶点也没标记过
			 if (G->edge[i][j] == 1 && !visited[j]) {	//检查到v_i和v_j之间有边
				 //调用dfs;将当前顶点作为下次遍历的起点
				 DFS(G, j);	//跳到v_j所在行开始遍历
			 }	
		 }
	 }
}


//主函数
int main() {
	//定义图
	Graph G;
	//初始化辅助数组
	init_visited(&G);
	//创建图
	CreateGraph(&G);
	//遍历邻接矩阵(每一行换行)
	for (int i = 0; i < G.vexnum; i++){
		for (int j = 0; j < G.vexnum; j++)
		{
			printf("%d ",G.edge[i][j]);
		}
		printf("\n");
	}
	printf("深度优先遍历结果:");
	//从第1个顶点开始遍历
	DFS(&G, 0);
	return 0;
}



此例的深度优先遍历详细过程

运行结果:

广度优先遍历(BFS)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MVNum 10	//最大顶点数
#define QSize 10
/*
* 无向图的广度优先遍历
*/
//定义图的结构体
typedef struct {
	//顶点数组
	char vex[MVNum];
	//边数组(邻接矩阵)
	int edge[MVNum][MVNum];
	//顶点数,边数
	int vexnum, edgenum;
}Graph;

/*--------------------队列----------------------*/
typedef struct Queue {
	char data[QSize];
	int front, rear;
}SeqQueue;
//队列顺序存储
//初始化队列
void InitQueue(SeqQueue *Q) {
	Q->front = 0;
	Q->rear = 0;
}
//入队操作
int EnQueue(SeqQueue Q, char e) {
	//判断队满
	if ((Q.rear + 1) % QSize == Q.front)
		return 0;
	//将新元素从队尾入队
	Q.data[Q.rear] = e;
	//队尾指针改变
	Q.rear = (Q.rear + 1) % QSize;	//防止假溢出
	return 1;
}
//出队操作
int DeQueue(SeqQueue Q, char* e) {
	//判断队空
	if (Q.front == Q.rear)
		return 0;
	*e = Q.data[Q.front];	//用e接收队头元素
	//队头指针改变
	Q.front = (Q.front + 1) % QSize;
	return 1;
}

/*----------------辅助数组---------------*/
//辅助数组(标记已被访问过的顶点)
int visited[MVNum];
//初始化辅助数组
void init_visited(Graph* G) {
	for (int i = 0; i < G->vexnum; i++)
	{
		visited[i] = 0;
	}
}

/*---------------图的操作函数-------------*/
//创建图
void CreateGraph(Graph* G) {
	//初始化总顶点数和总边数
	G->vexnum = 0;
	G->edgenum = 0;
	printf("请输入图的总顶点数和总边数:");
	//输入图的总顶点数和总边数
	scanf("%d %d", &G->vexnum, &G->edgenum);

	/*------------关于顶点--------------*/

	//输入顶点信息
	for (int i = 0; i < G->vexnum; i++)
	{
		char v;
		printf("请输入第%d顶点信息:", i + 1);
		scanf(" %c", &v);
		G->vex[i] = v;
	}
	printf("输入完成!\n");

	/*------------关于边--------------*/

	//初始化邻接矩阵,边的权值
	for (int i = 0; i < G->vexnum; i++) {
		for (int j = 0; j < G->vexnum; j++)
		{
			G->edge[i][j] = 0;
		}
	}

	//输入边信息
	int i, j;
	//构造邻接矩阵(输入两个顶点在vex数组中的下标,如果置为1则表示此两点中有边)
	printf("请输入两个顶点(两点间有边)的下标:");
	scanf("%d %d", &i, &j);
	while (i != -1 && j != -1)
	{
		G->edge[i][j] = 1;
		G->edge[j][i] = 1;
		scanf("%d %d", &i, &j);
	}

}

//广度优先遍历
void BFS(Graph G) {

	//接收出队顶点
	char e;
	//定义队列
	SeqQueue Q;
	//初始化队列
	InitQueue(&Q);
	//遍历邻接矩阵
	for (int i = 0; i < G.vexnum; i++)
	{
		//如果该顶点未被访问过,则打印该顶点
		if (!visited[i])
		{
			//打印该顶点
			printf("%c", G.vex[i]);
			//打印后代表该顶点被访问过,将此顶点在辅助数组中的标志置1
			visited[i] = 1;
			//将该顶点入队
			EnQueue(Q, G.vex[i]);
			//判断队空
			while (Q.front!=Q.rear)
			{
				//出队
				DeQueue(Q, &e);
				for (int  j = 0; j < G.vexnum; j++)
				{
					//邻接矩阵某顶点v_i和v_j间有边,且v_j未被访问过,打印v_j(v_i的邻接点)
					if (G.edge[i][j]==1 && !visited[j])
					{
						//打印v_i的邻接点v_j
						printf("%c", G.vex[j]);
						//打印v_j后,该顶点被访问过
						visited[j] = 1;
						//将v_i的邻接点v_j入队
						EnQueue(Q,G.vex[j]);
					}
				}

			}
		}
	}
}


//主函数
int main() {
	//定义图
	Graph G;
	//初始化辅助数组
	init_visited(&G);
	
	//创建图
	CreateGraph(&G);
	//遍历邻接矩阵(每一行换行)
	for (int i = 0; i < G.vexnum; i++) {
		for (int j = 0; j < G.vexnum; j++)
		{
			printf("%d ", G.edge[i][j]);
		}
		printf("\n");
	}
	printf("广度优先遍历结果:");
	//从第1个顶点开始遍历
	BFS(G);
	return 0;
}


运行结果

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐