way:找入度为0的节点删除,减少其他节点的入度,继续找入度为0的节点,直到删除完所有的图节点。(遍历node的neighbors就能得到neighbors的入度信息)
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;
//边结构的描述
class Edge
{
public:
//边的起始节点
Node *from;
//边的终点节点
Node *to;
//边的权重
int weight;
public:
Edge(Node *from, Node *to, int weight)
{
this->from = from;
this->to = to;
this->weight = weight;
}
};
//点结构的描述
class Node
{
public:
//编号值
int value;
//入度
int in;
//出度
int out;
//邻接的点
vector<Node*> nexts;
//邻接的边
vector<Edge*> edges;
public:
Node()
{
}
Node(int value)
{
this->value = value;
in = 0;
out = 0;
}
};
//图结构的描述
class Graph
{
public:
map<int, Node*> nodes;
set<Edge*> edges;
Graph()
{
}
};
//利用边结构描述的图来构建图结构
//[0,7,5] [from,to,weight]
//[0,1,3] [from,to,weight]
Graph* createGraph(vector<vector<int>> matrix)
{
Graph *graph = new Graph();
int m = matrix.size();
for(int i=0; i<m; i++)
{
int from = matrix[i][0];
int to = matrix[i][1];
int weight = matrix[i][2];
//将起点结构放到图里面
if(!graph->nodes.count(from))
{
Node *fromNode =new Node(from);
graph->nodes[from] = fromNode;
}
//将终点结构放到图里面
if(!graph->nodes.count(to))
{
Node *toNode=new Node(to);
graph->nodes[to] = toNode;
}
//将起点和终点的边结构也放到图里面(点可能已经存在过,边一定是新的)
Node *fromNode = graph->nodes[from];
Node *toNode = graph->nodes[to];
Edge *newEdge = new Edge(fromNode, toNode, weight);
fromNode->nexts.push_back(toNode);
fromNode->edges.push_back(newEdge);
fromNode->out++;
toNode->in++;
graph->edges.insert(newEdge);
}
return graph;
}
vector<Node*> topSort(Graph *graph)
{
//收集节点入度映射,将0入度放入que中
map<Node*,int>indegreeMap;
queue<Node*>zeroQue;
for(auto pa:graph->nodes)
{
indegreeMap[pa.second]=pa.second->in;
if(indegreeMap[pa.second]==0)
{
zeroQue.push(pa.second);
}
}
vector<Node*>result;
//开始按入度为0删除节点,同时减少其他节点入度,删除入度为0...
while(!zeroQue.empty())
{
Node *cur=zeroQue.front();
zeroQue.pop();
result.push_back(cur);
for(auto next: cur->nexts)
{
indegreeMap[next]=indegreeMap[next]-1;
if(indegreeMap[next]==0)
{
zeroQue.push(next);
}
}
}
return result;
}