算法--图的拓扑排序

图的拓扑排序

算法性质-有待进一步分析

拥有以下性质的前提:
图是无环图。

若深度优先后,对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
这与现实相违背。
故不是这种情况。

综合,若假设成立,则在所有可能情况都无法满足假设。
故,假设不成立。得证。
原创文章 134 获赞 87 访问量 6万+

猜你喜欢

转载自blog.csdn.net/x13262608581/article/details/105752908