拓扑排序——DFS

 DFS算法

拓扑排序,可以用深度优先搜索来实现,更确切的说,应该是深度优先遍历,遍历途中的所有顶点,而非只是搜索一个顶点到另一个顶点的路径。

注意,此邻接表为逆邻接表。输入的时候需要注意。s —> t,输入时,应该是addEdge(t, s);

然后递归处理每个顶点。对于顶点V来说,先输出祂可达到的所有顶点,也就是说,先把它依赖的所有顶点输出了,再输出自己。

DFS中,每个顶点被访问两次,每条边被访问一次,所以时间复杂度O(V+E);

/*
* 拓扑排序——DFS
*/
#include <iostream>
#include<vector>
#include<list>
using namespace std;

// 图结构
class Graph
{
public:
	int v;					// 顶点个数
	typedef vector<int>* node;
	node *adj;		// 邻接表
	Graph(int data):v(data)
	{
		adj = new node[v];
		for (int i = 0; i < v; ++i)
		{
			adj[i] = new vector<int>();		// 每个顶点后面跟着一条链
		}
	}
	void addEdge(int s, int t)
	{
		adj[s]->push_back(t);		// s->t, 逆邻接表的话,输入的时候,注意顺序,顶点从0开始
	}
	~Graph()
	{
		for (int i = 0; i < v; ++i)
		{
			delete adj[i];
		}
		delete []adj;
	}

	void print()
	{
		for (int i = 0; i < v; ++i)
		{
			cout << i << " 的入度: " ;
			for (int j = 0; j < adj[i]->size(); ++j)
			{
				cout << adj[i]->at(j) << " ";
			}
			std::cout << endl;
		}
	}

	void topoSortByDFS();
	void dfs(int v, vector<int> **adj, bool *visited);
};

void Graph::topoSortByDFS()
{
	bool *visited;
	visited = new bool[6]();		// 只有6个顶点
	for (int i = 0; i < v; ++i)
	{
		if (visited[i] == false)
		{
			visited[i] = true;
			dfs(i, adj, visited);
		}
	}
}

/****************************************************************
* @brief : 		dfs深度优先搜索
* @author : 	dyx
* @date : 		2019/8/28 10:34
* @version : 	ver 1.0
* @inparam : 
* @outparam : 
*****************************************************************/
void Graph::dfs(int v, vector<int> **adj, bool *visited)
{
	for (int i = 0; i < adj[v]->size(); ++i)
	{
		int w = adj[v]->at(i);
		if (visited[w] == true)
		{
			continue;
		}
		visited[w] = true;
		dfs(w, adj, visited);
	}
	cout << " -> " << v ;
}

int main()
{
	// 初始化一个拥有6个顶点的有向图
	const int n = 6;
	Graph G(n);	
	// (num1, num2);表示: num1 <- num2,2先于1执行
	G.addEdge(1,0);
	G.addEdge(2,0);
	G.addEdge(4,1);
	G.addEdge(3,1);
	G.addEdge(4,2);
	G.addEdge(5,3);
	G.addEdge(5,4);

	cout << "插入的数据:" << endl;
	G.print();
	cout << "输出topoDFS排序: " << endl;
	G.topoSortByDFS();
//	system("pause");        VS编译环境下,需要此行
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值