邻接矩阵深度优先和广度优先遍历(DFS和BFS)

深度优先遍历

深度优先遍历(DepthFirstSearch),也有称为深度优先搜索,简称为DFS。

深度优先遍历

约定右手原则:在没有碰到重复顶点的情况下,分叉路口始终是向右手边走,每路过一个顶点就做一个记号。

如果再细心观察,你会发现整个遍历过程就像是一棵树的前序遍历!

深度优先遍历

广度优先遍历

广度优先遍历(BreadthFirstSearch),又称为广度优先搜索,简称BFS。


代码:

<span style="font-family:Microsoft YaHei;font-size:14px;">/*邻接矩阵的广度遍历算法*/
#include "stdio.h"
#include "stdlib.h"

#define OK 1
#define ERROR 1
#define FALSE 0
#define TRUE 1

typedef int Status; //Status是函数的类型,其值是函数结果状态代码
typedef int Boolean;//Boolean是布尔类型,其值是TRUE或FALSE

//图的邻接矩阵存储结构
typedef char VertexType;//顶点类型应由用户定义
typedef int EdgeType;//边上的权值类型应由用户定义
#define MAXVEX 100  //最大顶点数,应由用户定义

typedef struct 
{
	VertexType  vexs[MAXVEX];//顶点表
	EdgeType arc[MAXVEX][MAXVEX];//邻接矩阵,可看做边表
	int numVertexes,numEdge;//图中当前的顶点数和边数
}MGraph;

//***********用到的队列结构与函数***********

//链队列的结构
typedef int QElemType;//这里QElemType的类型假设为int

typedef struct QNode //结点结构
{
	QElemType  data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef struct //队列的链表结构
{
	QueuePtr front,rear;//队头、队尾指针
}LinkQueue;

//初始化队列:
Status initQueue(LinkQueue *q)
{
	q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
	if(!q->front)
		return ERROR;
	q->front->next = NULL;

	return OK;
}

//入队:插入元素e为q的新的队尾元素
Status EnQueue(LinkQueue *q,QElemType e)
{
	QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
	if(!s)//存储分配失败
		return ERROR;
	s->data = e;
	s->next = NULL;
	q->rear->next = s;
	q->rear = s;

	return OK;
}

//出队
//若队列不为空,删除q的队头元素,用e返回其值,并返回OK,否则返回ERROR
Status DeQueue(LinkQueue *q,QElemType *e)
{
	
	QueuePtr p;

	if(q->front==q->rear)
		return ERROR;
	p = q->front->next;
	*e = p->data;
	q->front->next = p->next;

	if(q->rear==p)//若队头是队尾,则删除后将rear指向头结点
		q->rear = q->front;
	free(p);
	return OK;
}

//判断是否为空队列,若为空队列则返回1,否则返回0
Status QueueEmpty(LinkQueue q)
{
	if(q.front == q.rear)
		return 1;
	return 0;
}

//******************************************************

//建立无向图的邻接矩阵表示
void CreatMGraph(MGraph *G)
{

	int i,j,k;
	printf("输入顶点数和边数:\n");
	scanf("%d,%d",&G->numVertexes,&G->numEdge);//输入顶点数和边数
	getchar();

	printf("输入顶点字符:\n");
	for(i=0;i<G->numVertexes;i++) //读入顶点信息,建立顶点表
		scanf("%c",&G->vexs[i]);

	for(i=0;i<G->numVertexes;i++)
		for(j=0;j<G->numVertexes;j++)
			G->arc[i][j] =0;//邻接矩阵初始化

	for(k=0;k<G->numEdge;k++)//读入numEdges条边,建立邻接矩阵
	{
		printf("输入边(vi,vj)上的下标i,下标j:\n");
		scanf("%d,%d",&i,&j);
		G->arc[i][j]=1;
		G->arc[j][i]=G->arc[i][j];//因为是无向图,矩阵对称
	}
}

Boolean visited[MAXVEX];//访问标记的数组

//邻接矩阵的深度优先递归算法
void DFS(MGraph G,int i)
{
	int j;
	visited[i] = TRUE;
	printf("%c ",G.vexs[i]);
	for(j=0;j<G.numVertexes;j++)
		if(G.arc[i][j]==1 && !visited[j])
			DFS(G,j);//对未访问的邻接顶点递归调用
}

//邻接矩阵的深度遍历算法
void DFSTraverse(MGraph G)
{
	int i;
	for(i=0;i<G.numVertexes;i++)
		visited[i]=FALSE;//初始所有顶点状态都是未被访问过
	for(i=0;i<G.numVertexes;i++)
		if(!visited[i])
			DFS(G,i);
}

//邻接矩阵的广度遍历算法
void BFSTraverse(MGraph G)
{
	int i,j;
	LinkQueue Q;

	for(i=0;i<G.numVertexes;i++)
	{
		visited[i] = FALSE;
	}

	initQueue(&Q);				//初始化一辅助用的队列

	for(i=0;i<G.numVertexes;i++)//对每一个顶点做循环
	{
		if(!visited[i])			//若是未被访问过就处理
		{
			visited[i] = TRUE;	//设置当前顶点访问过
			printf("%c ",G.vexs[i]);//打印顶点
			EnQueue(&Q,i);		//将此顶点入队列

			while(!QueueEmpty(Q))//若当前顶点不为空
			{
				DeQueue(&Q,&i);	 //将队中元素出队列,赋值给i
				for(j=0;j<G.numVertexes;j++)
				{
					//判断其他顶点若与当前顶点存在边且未被访问过
					if(G.arc[i][j] ==1 && !visited[j])
					{
						visited[j] = TRUE;//将找到的此顶点标记为已访问
						printf("%c ",G.vexs[j]);//打印此顶点
						EnQueue(&Q,j);//将找到的此顶点入队列
					}
				}
			}
		}
	}
}
	
int main()
{
	MGraph G;
	CreatMGraph(&G);
	printf("\n深度遍历:");
	DFSTraverse(G);
	printf("\n广度遍历:");
	BFSTraverse(G);

	return 0;
}</span>


  • 22
    点赞
  • 221
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
邻接矩阵是一种图的存储结构,它可以用来表示有限个顶点之间的关系。邻接矩阵深度优先广度优先是图的两种基本遍方式。 邻接矩阵深度优先(Depth First Search,DFS): 深度优先是一种用于遍或搜索树或图的算法。在这个算法中,首先访问根节点,然后递归地访问每个子节点。当访问一个节点时,将其标记为已访问,以避免重复访问。深度优先使用栈来实现,因此它是一种先进后出(Last In First Out,LIFO)的算法。 下面是邻接矩阵深度优先的Python代码示例: ```python def DFS(graph, start): visited = set() # 用集合来存储已经访问过的节点 stack = [start] # 用列表来模拟栈 while stack: vertex = stack.pop() # 取出栈顶元素 if vertex not in visited: visited.add(vertex) # 标记为已访问 print(vertex, end=' ') # 将未访问的邻居节点入栈 stack.extend([i for i in range(len(graph[vertex])) if graph[vertex][i] and i not in visited]) # 示例 graph = [[0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]] DFS(graph, 0) # 输出:0 1 3 2 ``` 邻接矩阵广度优先(Breadth First Search,BFS): 广度优先是一种用于遍或搜索树或图的算法。在这个算法中,首先访问根节点,然后逐层访问每个子节点。当访问一个节点时,将其标记为已访问,以避免重复访问。广度优先使用队列来实现,因此它是一种先进先出(First In First Out,FIFO)的算法。 下面是邻接矩阵广度优先的Python代码示例: ```python from collections import deque def BFS(graph, start): visited = set() # 用集合来存储已经访问过的节点 queue = deque([start]) # 用双端队列来模拟队列 while queue: vertex = queue.popleft() # 取出队首元素 if vertex not in visited: visited.add(vertex) # 标记为已访问 print(vertex, end=' ') # 将未访问的邻居节点入队 queue.extend([i for i in range(len(graph[vertex])) if graph[vertex][i] and i not in visited]) # 示例 graph = [[0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]] BFS(graph, 0) # 输出:0 1 2 3 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值