计科《算法设计与分析》第四周作业——无向图的DFS算法

题目如下:

无向图的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;
	}
}

结果如下:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值