拓扑排序——插件加载顺序

拓扑排序

问题描述

有如下插件间依赖关系:

  • 插件1依赖于插件0
  • 插件2依赖于插件0
  • 插件3依赖于插件0
  • 插件4依赖于插件1
  • 插件5依赖于插件1
  • 插件6依赖于插件2和插件3
  • 插件7依赖于插件2和插件5

求一种插件加载队列,使得被依赖插件先于依赖插件加载。

解决方案

利用拓扑排序,根据插件间的两两依赖关系,得出合适的插件加载顺序。将插件看作节点,插件间的依赖关系看作两个插件节点之间的有向边,如插件A依赖于插件B,则有一条从B到A的有向边。据此,可得到一幅有向图。

由上述问题,可得有向图如下所示:
在这里插入图片描述

首先找出入度为0的节点,这说明该节点所代表的插件不依赖于其他插件。然后将其放入加载队列中并从图中去除,并把该节点所指节点的入度减一。再次循环遍历入度为0的节点,重复上述过程,直至所有入度为0的节点放入加载队列。

代码
#include <iostream>
#include <vector>
#include <list>
#include <queue>

using namespace std;

class Graph
{
private:    
	int m_numOfVertexs;    
	vector<list<int>> m_adjacency;
public:    
	Graph(int numOfVertexs) : m_numOfVertexs(numOfVertexs), m_adjacency(numOfVertexs, list<int>()) {}
	
    	void addEdge(int source, int target)    
    	{        
    		m_adjacency[source].push_back(target);    
    	}
    	
    	vector<int> topoSortByKahn() const    
    	{        
    		// 求每个节点的入度        
    		vector<int> inDegrees(m_numOfVertexs, 0);
    		for (auto iter = m_adjacency.begin(); iter != m_adjacency.end(); iter++)            
    			for (auto jter = iter->begin(); jter != iter->end(); jter++)                
    				inDegrees[*jter]++;
        	// 将入度为零的节点入队        
        	queue<int> cache;        
        	for (int i = 0; i < inDegrees.size(); i++)        		
        	{            
        		if (inDegrees[i] == 0)                		
        			cache.push(i);        
        	}                
        	// 宽度优先遍历        
        	vector<int> result;        
        	while (!cache.empty())        
        	{            
        		int vertexs = cache.front();
        		cache.pop();            
        		result.push_back(vertexs);
        		for (auto iter = m_adjacency[vertexs].begin(); iter != m_adjacency[vertexs].end(); iter++)            
        		{                
        			inDegrees[*iter]--;
        			if (inDegrees[*iter] == 0)
        	                    cache.push(*iter);            		
        	        }        
        	 }        
        	 return result;    		
	}
};

int main()
{    
	Graph graph(8);    
	graph.addEdge(0, 1);    
	graph.addEdge(0, 2);    
	graph.addEdge(0, 3);    
	graph.addEdge(1, 4);    
	graph.addEdge(1, 5);    
	graph.addEdge(2, 6);    
	graph.addEdge(2, 7);    
	graph.addEdge(3, 6);    
	graph.addEdge(5, 7);    
	auto loadQueue = graph.topoSortByKahn();    
	for (int i = 0; i < loadQueue.size(); i++)    
	{        
		cout << loadQueue[i] << " ";    
	}    
	cout << endl;    return 0;}
测试结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值