图的遍历
图的遍历(Traversing Graph):
从图中某一个顶点出发,访问图中的其余顶点,且使每个顶点仅被访问一次。
方法:
- 深度优先搜索
- 广度优先搜索
它们对无向图和有向图都适用
深度优先搜索类似于树的先根遍历
广度优先搜索类似于树的层次遍历
深度优先遍历(DFS)
- 从图的某一顶点V0出发,访问此顶点;然后依次从V0的未被访问的邻接点出发,深度优先遍历图,直至图中所有和V0相通的顶点都被访问到;
- 若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止。


深度优先遍历算法-递归算法

//--- 下列算法使用的全局变量 ---
Boolean visited[MAX]; // 访问标志数组
Status (* VisitFunc)(int v); // 函数变量
void DFS(Graph G, int v) {
// 从第v个顶点出发递归地深度优先遍历图G。
visited[v] = TRUE;
VisitFunc(v);
// 访问第v个顶点
for(w=FirstAdjVex(G,v);w!=0;w=NextAdjVex(G,v,w))
if(!visited[w])
DFS(G, w);
// 对v的尚未访问的邻接顶点w递归调用DFS
}
void DFSTraverse(Graph G, Status (*Visit)(int v)) {
// 对图G作深度优先遍历。
VisitFunc = Visit;
for (v=0; v<G.vexnum; ++v)
visited[v] = FALSE; // 访问标志数组初始化
for (v=0; v<G.vexnum; ++v)
if (!visited[v]) DFS(G, v);
// 对尚未访问的顶点调用DFS
}
广度优先遍历(BFS)
- 从图的某一顶点V0出发,访问此顶点后,依次访问V0的各个未曾访问过的邻接点;然后分别从这些邻接点出发,广度优先遍历图,直至图中所有已被访问的顶点的邻接点都被访问到;
- 若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止


广度优先遍历算法


#include<iostream>
#include<queue>
using namespace std;
#define MAX_VERTEX_NUM 20
#define FALSE -1
#define MAX 20
#define TRUE 1
typedef enum {
DG,
DN,
UDG,
UDN,
}Kind;
typedef int status;
typedef int VertexType;
typedef int AdjList;
bool visited[MAX];
status(*VisitFunc)(int v); // 函数变量
typedef struct ArcNode {
int adjvex;
struct ArcNode* nextarc;
}ArcNode;
typedef struct VNode {
VertexType data;
ArcNode* firstarc;
}Vnode,AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vertices;
int vexnum, arcnum;
int kind;
}ALGraph;
int firstAdjvex(ALGraph G, int v) { //返回顶点v的一个邻接顶点,若顶点在G中无邻接顶点返回空。
int i;
if (!G.vertices[v].firstarc)//判断是否有临界点
{
return 0;
}
return G.vertices[v].firstarc->adjvex;//如果有返回该点的位置
}
int NextAdjVex(ALGraph G, int u, int w)//表示u相对于w的下一个临界点w>=0 表示存在临界点
{
ArcNode* p;
p = G.vertices[u].firstarc;
while (p && p->adjvex != w)
p = p->nextarc;//找到w点的位置
p = p->nextarc;w位置的下一个位置
if (p)//如果该位置不为NULL说明和u位置还有相连的
{
return p->adjvex;
}
return -1;//该位置为NULL说明,与u位置有关系的点已经遍历完
}
void BFSTraverse(ALGraph G, status(*visit)(int v)) {
for (int v = 0; v < G.vexnum; ++v) {
visited[v] = FALSE;
}
queue<int>q ;
for (int v = 0; v < G.vexnum; ++v) {
if (!visited[v]) {
visited[v] = TRUE;
visit(v);
q.push(v);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int w = firstAdjvex(G, u); w >= 0; w = NextAdjVex(G, u, w)) {
if (!visited[w]) //w为u的尚未访问的邻接顶点
{
visited[w] = TRUE;
visit(w);
q.push(w);
}
}
}
}
}

被折叠的 条评论
为什么被折叠?



