题目如下:
无向图的DFS算法:按照教材中的定义方式,完整实现图的DFS算法,给定图数据文件(tinyG.txt),能够输出DFS的节点遍历结果,及每个节点的Pre和Post值,和连通分量的个数与节点构成。类名:GraphDFS。
我的解答如下:
代码:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
struct Vertex
{
int v; //节点
int pre; //pre值
int post; //post值
int group; //连通分量标记
};
class GraphDFS
{
public:
GraphDFS(char const * inFileName);
~GraphDFS();
void dfs();
void show();
private:
void explore(Vertex& v,int group);
Vertex* vertex; //顶点
int** arc; //矩阵
bool* visited; //用于保存节点是否被访问
int vertexNum,arcNum; //节点数,边数
int count; //访问的总数
int groups; //连通分量数目
vector<Vertex*> vec_PtrVertex;//保存节点访问顺序
};
int main(int argc, char const *argv[])
{
char const * inFileName= "tinyG.txt";
GraphDFS graph(inFileName);
graph.dfs();
graph.show();
return 0;
}
GraphDFS::GraphDFS(char const * inFileName)
{
ifstream inFile(inFileName);
inFile >> vertexNum >> arcNum; //读入节点数与边数
vertex =new Vertex[vertexNum];
arc = new int*[vertexNum];
for (int i = 0; i < vertexNum; ++i)
{
arc[i] = new int[vertexNum];
}
visited = new bool[vertexNum];
count = 0;
int first[arcNum],second[arcNum];
int i = 0;
while(inFile>>first[i]>>second[i]) //读入各边的前后两个节点
++i;
for (int i = 0; i < vertexNum; ++i) //初始化顶点数组
{
vertex[i].v = i;
}
for (int i = 0; i < vertexNum; ++i) //初始化邻接矩阵
{
for (int j = 0; j < vertexNum; ++j)
{
arc[i][j] = 0;
}
}
for (int i = 0; i < arcNum; ++i) //生成邻接矩阵
{
arc[first[i]][second[i]] = 1;
arc[second[i]][first[i]] = 1;
}
inFile.close();
}
GraphDFS::~GraphDFS()
{
delete[] vertex;
for (int i = 0; i < arcNum; ++i)
{
delete[] arc[i];
}
delete[] arc;
delete[] visited;
}
void GraphDFS::dfs()
{
groups = 0; //初始化连通分量为0个
for (int i = 0; i < vertexNum; ++i) //初始化节点全部没有被访问
{
visited[vertex[i].v] = false;
}
for (int i = 0; i < vertexNum; ++i) //开始dfs遍历
{
if (!visited[vertex[i].v])
{
++groups;
explore(vertex[i],groups);
}
}
}
void GraphDFS::explore(Vertex& vert,int groups)
{
visited[vert.v] = true; //设置节点被访问
vert.pre = ++count; //保存pre值
vec_PtrVertex.push_back(&vert); //保存访问顺序
vert.group = groups; //保存所属连通分量
for (int i = 0; i < vertexNum; ++i) //遍历下一个节点
{
if (arc[vert.v][vertex[i].v] && !visited[vertex[i].v])
{
explore(vertex[i],groups);
}
}
vert.post = ++count; //保存post值
}
void GraphDFS::show()
{
cout<<"节点遍历结果:"<<endl;
for(vector<Vertex*>::iterator iter = vec_PtrVertex.begin();
iter!=vec_PtrVertex.end();
++iter)
{
cout<<(*iter)->v<<":\tpre="<<(*iter)->pre
<<" post="<<(*iter)->post<<endl;
}
cout<<"其中,有"<<groups<<"个连通分量\n如下:"<<endl;
for (int i = 1; i <= groups; ++i)
{
cout<<"连通分量"<<i<<":"<<endl;
for(vector<Vertex*>::iterator iter = vec_PtrVertex.begin();
iter!=vec_PtrVertex.end();
++iter)
{
if ((*iter)->group == i)
{
cout<<(*iter)->v<<":\tpre="<<(*iter)->pre
<<" post="<<(*iter)->post<<endl;
};
}
cout<<endl;
}
}
结果如下: