算法--圖的拓撲排序

圖的拓撲排序

算法性質

若深度優先後,對p,q兩節點。
設p的結束時間大於q的結束時間。
則,圖中不可能存在q到p的邊。

進一步,
拓撲排序後的節點序列,
前面的節點可能可以到達後面的節點,
但後面的節點不會到達前面的節點。

接口設計

template<typename Key, typename Value>
class TopologySort
{
public:
	typename typedef DataStruct::GraphStruct::Graph<Key, Value> InnerGraph;
	
	TopologySort(const InnerGraph& nGraph_);
	~TopologySort();

	DataStruct::Array::DynArray<typename DepthFirstVisit<Key, Value>::Node*> Run();
private:
	TopologySort(const TopologySort& nTopoAl_) = default;
	TopologySort& operator=(const TopologySort& nTopoAl_) = default;

private:
	typename DepthFirstVisit<Key, Value> m_alDepthFirstVisit;
};

實現

構造

template<typename Key, typename Value>
TopologySort<Key, Value>::TopologySort(const HighLevelStruct::Graph<Key, Value>& nGraph_)
	: m_alDepthFirstVisit(nGraph_)
{

}

析構

template<typename Key, typename Value>
TopologySort<Key, Value>::~TopologySort()
{

}

算法運行

template<typename Key, typename Value>
DataStruct::Array::DynArray<typename DepthFirstVisit<Key, Value>::Node*> TopologySort<Key, Value>::Run()
{
	DataStruct::Array::DynArray<typename DepthFirstVisit<Key, Value>::Node*> _arrNodes = m_alDepthFirstVisit.Run();
	_arrNodes.Sort([](DepthFirstVisit<Key, Value>::Node* pNode1_, DepthFirstVisit<Key, Value>::Node* pNode2_)
	{
		int _nRet = pNode1_->GetLastVisitTime() - pNode2_->GetLastVisitTime();
		if (_nRet > 0)
		{
			return -1;
		}
		else if (_nRet < 0)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	});

	return _arrNodes;
}

算法目標&算法的性質證明

證明:
對無環圖運行深度優先搜索算法,
深度優先算法處理後,若節點p的結束時間 > 節點q的結束時間,
則圖中可能存在p到q的邊,不可能存在q到p的邊

結合深度優先算法的性質
我們知道,
若算法處理後,節點p的結束時間 > 節點q的結束時間
則,
要麼 p,q在主循環某個節點t的visit中被訪問
此時,
a.1要麼在訪問鏈p->x1->...->xn->q中被訪問
a.2要麼在
t->x1->...->xk->y1->...->yn->q
t->x1->...->xk->z1->...->zm->p
其中,對xk可達節點按順序執行訪問時,先訪問y1,後z1中被訪問

b.要麼p,q分別在主循環某節點t1,t2的visit中被訪問
且t1在t2之後執行

綜合,a.1,a.2,b三種情況,
此時可以斷定
圖中
可能存在p->q的邊
也可能不存在p->q的邊

現在證明,圖中不存在q->p的邊,已知圖是無環圖。
則,p,q執行深度優先的情況可能是:
a.1.p,q在主循環某個節點p的visit中被訪問,在訪問鏈p->x1->...->xn->q中被訪問
若是這種情況,則p->x1->...->xn->q->p形成環路,與已知矛盾。故不是。
a.2.p,q在主循環某個節點t的visit中被訪問,在
t->x1->...->xk->y1->...->yn->q
t->x1->...->xk->z1->...->zm->p
其中,對xk可達節點按順序執行訪問時,先訪問y1,後z1中被訪問
若存在q->p的邊,則在y1分支訪問q時,對q所有可達且未訪問節點進行訪問時,會訪問p,
這與現實情況相違背。
故不是這種情況。
b.p,q分別在主循環某節點t1,t2的visit中被訪問
且t1在t2之後執行
若存在q->p的邊,
則在t2的visit中對q的所有可達且未被訪問節點進行訪問時,會訪問p
這與現實相違背。
故不是這種情況。

綜合,若假設成立,則在所有可能情況都無法滿足假設。
故,假設不成立。得證。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章