图的深度优先搜索遍历(DFS)类似于二叉树的先序遍历。
基本思想:首先访问出发点A,并将其标记为已访问过,然后选取与A邻近的并且未被访问过的任意一个顶点,比如D,访问它并且标记为已访问过;再选取与D邻接的未被访问的任意顶点,以此重复进行。当一个顶点所有的邻接顶点都被访问过时,则依次退回到最近被访问过的顶点,若该顶点还有其他啊邻近顶点未被访问,则从这么未被访问过的顶点中选取一个那个重复上述过程,直至图中所有顶点都被访问过为止,下图即为一个图的深度优先搜索遍历过程。
用标记矩阵实现DFS核心代码:
int sign[MAX];//标记矩阵,用来判断顶点是否被访问过
//深度优先遍历
void DFS(MGraph G, int v){
cout<<G.vertex[v]<<" ";
sign[v] = 1;
for(int i=0; i<G.vertexnum; i++){
if( (G.e[v][i]!=INFINITE) && !sign[i] ){ //顶点有边,并且没有被访问过
DFS(G,i);
}
}
}
全部代码
//这里讨论无向图
#include <iostream>
using namespace std;
#define MAX 50
#define INFINITE 32767
//图的邻接矩阵表示
struct MGraph{
int vertexnum; //顶点的数量
int edgenum; //边的数量
char vertex[MAX]; //存储顶点的数组
int e[MAX][MAX]; //存储边权重的二维数组
};
int findvertex(MGraph G, char key);
//创建图
void createG(MGraph &G){
//1.先输入顶点数和顶点字符
cout<<"请输入顶点数:"<<endl;
cin>>G.vertexnum;
cout<<"请输入顶点字符:"<<endl;
for(int i=0; i<G.vertexnum; i++){
cin>>G.vertex[i];
}
//2.在输入边
cout<<"请输入边数:"<<endl;
cin>>G.edgenum;
//3.将边的数(也就是e中元素)初始化为无穷大
for(int i=0; i<G.vertexnum; i++){
for(int j=0; j<G.vertexnum; j++){
G.e[i][j] = INFINITE;//有权图初始化边为无穷大。无权图初始化为0
}
}
//4.修改已知边的权重
for(int i=0; i<G.edgenum; i++){
char k,j;//起点、终点
int w;//权重
cout<<"输入边,起点、终点、权重:例如 A B 10"<<endl;
cin>>k>>j>>w;
G.e[findvertex(G,k)][findvertex(G,j)] = w;
}
}
//查找顶点是否存在
int findvertex(MGraph G, char key){
for(int i=0; i<G.vertexnum; i++){
if(G.vertex[i] == key){
return i; //如果存在返回顶点所在下标
}
}
return -1;
}
//遍历
void print(MGraph G){
for(int i=0; i<G.vertexnum; i++){
for(int j=0; j<G.vertexnum; j++){
cout<<G.e[i][j]<<" ";
}
cout<<endl;
}
}
int sign[MAX];//标记矩阵,用来判断顶点是否被访问过
//深度优先遍历
void DFS(MGraph G, int v){
cout<<G.vertex[v]<<" ";
sign[v] = 1;
for(int i=0; i<G.vertexnum; i++){
if( (G.e[v][i]!=INFINITE) && !sign[i] ){ //顶点有边,并且没有被访问过
DFS(G,i);
}
}
}
int main(){
MGraph G;
createG(G);
print(G);
cout<<endl<<endl;
DFS(G,0);
return 0;
}