图的深度优先遍历和广度优先遍历

图的遍历: 从给定图中指定的顶点出发,按照某种搜索方法沿着图的边访问图中的所有顶点,使得每个顶点只会被访问一次,这个过程叫做图的遍历。图的遍历方法有两种:深度优先遍历(DFS)和广度优先遍历(BFS)。

1.深度优先遍历

深度优先遍历类似于树的先序遍历。一次深度优先遍历的基本过程可以用递归的方法来描述:
(1)从起始点v出发,首先访问顶点v。
(2)选择一个与顶点v相邻接且没有被访问过的顶点w作为新的起始点,继续深度优先遍历,直到顶点v的所有邻接点都被访问过。
例如,对于无向图来说,如果无向图是连通的,则一次深度优先遍历就可以访问到图中的所有顶点;但如果无向图是非连通的,则一次深度优先遍历只能访问到起始顶点所在连通分量的所有顶点。因此只有从其它连通分量中选择起始顶点,继续深度优先遍历,才能将所有顶点都访问一遍。

图的顶点之间的关系相对复杂,某个顶点vi既可以是其它顶点vj的邻接点,也可以是其它顶点诸如vk的邻接点。因此为了保证在遍历中每个顶点只会被访问一次,需要借助一个辅助数组visit[]来做标记。若visit[i]的值为true,则表示顶点vi已经被访问过;反之,则vi没有被访问过。

//图的深度优先遍历
void ALGraph::DFS_Visit() {
	int i;
	for (i = 0; i < vexnum; i++)
		visit[i] = false;    //辅助数组初始化
	for (i = 0; i < vexnum; i++) {
		if (visit[i] == false)    
			DFS(i);    //对每个没有被访问过的顶点调用一次深度优先遍历
	}
}

//以v为起始点的深度优先遍历
void ALGraph::DFS(int v) {
	ArcNode* p;
	visit[v] = true;    //将起始顶点标记为已被访问的状态
	cout << vexnode[v].data;    //输出起始顶点的信息
	p = vexnode[v].firstarc;    //指针p指向起始点的第一个邻接点
	while (p) {
		//遍历起始顶点的所有邻接点,若邻接点已经被访问过,那么p将继续向后遍历
		//否则以当前邻接点为新的起始点递归进行深度优先遍历
		if (visit[p->adjvex] == false)
			DFS(p->adjvex);
		p = p->nextarc;
	}
}

2.广度优先遍历

广度优先遍历类似于树的层次遍历。一次广度优先遍历的基本过程如下:
(1)从起始点v出发,首先访问顶点v;
(2)依次访问v的所有没有被访问的邻接点w1,w2,…,wi;
(3)按照w1,w2,…,wi的次序访问它们各自所有未被访问过的邻接点。
(4)以此类推,直到图中所有顶点v连通的顶点都被访问过为止。
同样,一次广度优先遍历只能保证将与起始点连通的顶点访问到,而其他不与起始点连通的顶点是访问不到的,因此为了保证图中所有顶点被访问到,需要对每个未被访问的顶点进行一次广度优先遍历;因此还是需要辅助数组visit[]
由于广度优先遍历是一种一层一层向外推进的遍历算法,所以需要使用队列进行辅助。

//图的广度优先
void ALGraph::BFS_Visit() {
	int i;
	for (i = 0; i < vexnum; i++)
		visit[i] = false;    //辅助数组从初始化,每个顶点均未被访问过
	for (i = 0; i < vexnum; i++) {
		if (visit[i] == false)
			BFS(i);
	}
}

//以v为起始点的广度优先遍历
void ALGraph::BFS(int v) {
	ArcNode* p;
	int Qu[MAX_V];    //定义队列
	int front, rear, i;
	front = rear = 0;    //队列初始化
	Qu[rear++] = v;    //起始点入队
	visit[v] = true;    //入队的顶点标记为已被访问状态,防止重复入队
	while (front != rear) {
		i = Qu[front];    //队头元素出队
		front = (front + 1) % MAX_V;
		cout << vexnode[i].data;    //访问队头元素
		p = vexnode[i].firstarc;    //指针p指向当前队头顶点的第一个结点
		while (p) {
			//遍历当前队头顶点的所有邻接点
			if (visit[p->adjvex] == false) {
				Qu[rear] = p->adjvex;
				rear = (rear + 1) % MAX_V;
				visit[p->adjvex] = true;
			}
			p = p->nextarc;
		}
	}
}
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值