1. 程式人生 > >拓撲排序(深搜實現)

拓撲排序(深搜實現)

這裡給大家介紹另外一種拓撲排序,這種是基於深搜實現的。
上圖:
在這裡插入圖片描述

如果我們按照節點編號順序從節點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)。

這裡總結一下拓撲排序:
*必須是有向圖
*必須是無環圖
*支援非連通圖
*不用考慮權值