1. 程式人生 > >演算法學習-拓撲排序(佇列應用)

演算法學習-拓撲排序(佇列應用)

題目

對一個有向無環圖G進行拓撲排序,是將G中所有定點排成線性序列,使得途中任意一堆頂點u、v,若邊(u,v)∈E(G),則線上性序列中u出現在v之前。


分析

一個節點沒有節點指向(即入度為0)的時候可以順利輸出,如果有則不能。可以用鄰接矩陣的方式來儲存現有的圖,將某節點列下所有的相加後如果等於0這說明當前結點可輸出。

這裡給出關鍵程式碼和註釋

int graph[12][12];  // 結點數為n,用鄰接矩陣graph[n][n]儲存邊權
int indegree[12]; // 用indegree[n]儲存每個結點的入度,具體情境下會事先初始化
void topologic(int* toposort)
{
	int cnt = 0;       // 當前拓撲排序列表中有多少結點
	std::queue<int> q; // 儲存入度為0的結點:還可以用棧甚至隨機取
	for (int i = 0; i < 12; i++)
	{
		if (indegree[i] == 0)
		{
			q.push(i);
		}
	}
	int cur; // 當前入度為0的結點
	while (!q.empty())
	{
		cur = q.front();
		q.pop();
		toposort[cnt++] = cur;
		for (int i = 0; i < 12; i++)
		{
			if (graph[cur][i] != 0)
			{
				indegree[i]--;
				if (indegree[i] == 0)
				{
					q.push(i);
				}
			}
		}
	}
}

總結

拓撲排序的本質是不斷輸出入度為0的點,該演算法可用於判斷途中是否存在換

可以用佇列(或者棧)儲存入度為0的點,避免每次遍歷所有點;每次更新連線點的入度即可

拓撲排序其實是給定了結點的一組偏序關係。

拓撲的含義不限於此,在GIS中,他往往指點、線、面、體之間的相互鄰接關係,即“橡皮泥集合”。儲存這些關係,往往能夠對某些演算法帶來好處

計算不自交的空間曲面能否能夠圍城三維體。提示:任意三維邊都鄰接兩個三維曲面