图的拓扑序列(BFS_如果节点带着入度信息)

发布于:2024-05-15 ⋅ 阅读:(145) ⋅ 点赞:(0)

 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;
}


网站公告

今日签到

点亮在社区的每一天
去签到