图的拓扑排序

无环有向图可以进行拓扑排序,形象一点说就是,很多件有依赖关系的工作,怎么安排才能一步步进行下去。

拓扑排序的思想很简单,使用邻接表存储图的话,拓扑排序在O(|V|+|E|)的时间内可以完成。下面介绍两种拓扑排序方法。

1、简单的拓扑排序

首先,找出所有入度为0的节点,放入一个队列,然后,取出一个入度为零的节点,删除该节点以及该节点与其它节点的边,将新产生的入度为0的节点加入队列,最后当队列为空且处理完了所有节点则完成了拓扑排序,否则说明有环。

2、基于DFS的拓扑排序

拓扑排序可以简单的使用一次DFS来完成,将节点按照DFS完成时间逆序排即可获得一个拓扑排序的结果,但是在DFS过程中需要记录是否有环,即使有环也能得到一个拓扑排序,忽略了部分依赖条件。

void top_sort1_graph(struct graph *g)
{
	queue<size_t> q;
	size_t counter = 0;
	size_t *topnum = new size_t[g->n];
	size_t *indegree = new size_t[g->n];
	for (size_t i = 0; i < g->n; i++) {
		indegree[i] = g->v[i].indegree;
		if (indegree[i] == 0)
			q.push(i);
	}
	while (!q.empty()) {
		size_t id = q.front();
		struct vertex &v = g->v[id];
		struct edge *e = v.next;
		while (e) {
			if (--indegree[e->id] == 0)
				q.push(e->id);
			e = e->next;
		}
		topnum[counter++] = id;
		q.pop();
	}
	cout << "top sort1: ";
	if (counter != g->n) {
		cout << "graph has a cycle.";
	} else {
		for (size_t i = 0; i < g->n; i++) {
			cout << g->v[topnum[i]].name;
			if (i != g->n - 1)
				cout << ", ";
		}
	}
	cout << endl;
	delete [] indegree;
	delete [] topnum;
}

void top_sort2_graph(struct graph *g)
{
	const size_t white = 0, gray = 1, black = 2;
	size_t counter = 0;
	size_t *vert = new size_t[g->n];
	size_t *flag = new size_t[g->n];
	for (size_t i = 0; i < g->n; i++) {
		flag[i] = white;
	}
	for (size_t i = 0; i < g->n; i++) {
		if (flag[i] != white)
			continue;
		stack<size_t> s;
		flag[i] = gray;
		s.push(i);
		while (!s.empty()) {
			size_t id = s.top();
			struct edge *e = g->v[id].next;
			while (e) {
				if (flag[e->id] == white) {
					flag[e->id] = gray;
					s.push(e->id);
					e = g->v[e->id].next;
				} else {
					e = e->next;
				}
			}
			id = s.top();
			flag[id] = black;
			vert[counter++] = id;
			s.pop();
		}
	}
	cout << "top sort2: ";
	for (size_t i = counter; i != 0; i--) {
		cout << g->v[vert[i-1]].name;
		if (i != 1)
			cout << ", ";
	}
	cout << endl;
	delete [] vert;
	delete [] flag;
}
    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/notishell/article/details/9843861
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞