拓扑排序(深搜实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26760433/article/details/84242686

这里给大家介绍另外一种拓扑排序,这种是基于深搜实现的。
上图:
在这里插入图片描述

如果我们按照节点编号顺序从节点0开始深度优先搜索,就会得到下面这个序列。
5,6,3,2,8,7,0,4,1
把这个序列逆置一下,就会发现这是一个正确的拓扑序列。(可以好好想一下这个结论,我当时想了很久)
1,4,0,7,8,2,3,6,5

贴代码

#include<vector>
#include<iostream>
using namespace std;
class Graph
{
public:
	int v;                          //顶点个数
	vector<int> *adj;               //邻接表
	int *mark;                      //如果访问过,标记为1,否则为0

	Graph(int n);                          //构造函数
	~Graph();                              //析构函数
	void addEdge(int start,int end);       //添加边
	void TopsortbyDFS();                   //拓扑排序
};

Graph::Graph(int n)                       //构造函数
{
	v=n;
	adj=new vector<int>[n];
	mark=new int[n];
	for(int i=0;i<n;i++)                 //将所有顶点标记置为0,表示没有访问过
		mark[i]=0;
}
Graph::~Graph()                       //析构函数
{
	delete [] adj;
	delete [] mark;
}
void Graph::addEdge(int s,int e)
{
	adj[s].push_back(e);                          //添加边
}

void Do_topsort(Graph & g,int node,int *result,int &index)  //核心算法,参数分别为 (图
{                        //g,当前访问的顶点,储存结果数组,数组下标) 注意index要为引用																												
	g.mark[node]=1;                                   //已访问标记为1
	for( vector<int>::iterator ii=g.adj[node].begin();ii!=g.adj[node].end();ii++ )
	{
		if(g.mark[*ii] == 0)                                //如果该顶点的相邻顶点没有被访问
		{
			Do_topsort(g,*ii,result,index);
		}
	}
	result[index++]=node;                           //相当于后处理
}

void Graph::TopsortbyDFS()
{
	int *result = new int[v];                    //将结果保存在result数组中,待会逆序输出就是拓扑序列
	int index=0;                                 //result下标初始化为0
	for(int i=0;i<v;i++)                         //对所有顶点进行深搜
	{
		if(mark[i]==0)                            //如果mark为0,说明没有访问过
		{
			Do_topsort(*this,i,result,index);            //递归函数
		}
	}
	for(int i=v-1;i>=0;i--)                       //逆序输出
		cout<<result[i]<<" ";
}
int main()
{
	Graph g(9);
	g.addEdge(0,2);
	g.addEdge(0,7);
	g.addEdge(1,2);
	g.addEdge(1,4);
	g.addEdge(1,3);
	g.addEdge(2,3);
	g.addEdge(3,5);
	g.addEdge(3,6);
	g.addEdge(4,5);
	g.addEdge(7,8);
	g.addEdge(8,6);
	g.TopsortbyDFS();
	return 0;
}

运行结果:
代码的运行结果为:
时间复杂度和队列方法实现相同都为O(n+e)。

这里总结一下拓扑排序:
*必须是有向图
*必须是无环图
*支持非连通图
*不用考虑权值

猜你喜欢

转载自blog.csdn.net/qq_26760433/article/details/84242686