左神算法基础class6—题目1图的存储与表达

1.题目:图的存储与表达

图的存储方式:1)邻接表2)邻接矩阵
如何表达图?生成图?

2.分析

(1)邻接表法

①无权重
在这里插入图片描述
如果为无向图既有1–>2,也有2–>1.
②有权重
在这里插入图片描述

(2)邻接矩阵

在这里插入图片描述

(3)矩阵表达(题目常出现)

纵向有三列,每一列分别为权重weight、来源from、指向to
在这里插入图片描述

3.图在内存中的存储

在内存中,常用类来表达。

(1)class Graph

Graph类有点和边两大部分,使用hash_map存储节点,使用hash_set存储边的信息

class Graph
{
public:
	unordered_map<int,Node*> nodes;
	unordered_set<Edge*> edges; 
	Graph(){};		
};

下面来解释节点和边的构成

(2)class Node

节点有五部分数据,分别是节点的值value、入度in、出度out、当前节点的下一个节点nexts、以及与从当前节点出发的边。

class Node
{
public:
	int value;
	int	out;
	int in;
	list<Node*> nexts;
	list<Edge*> edges;

	Node(int val,int inn = 0,int outt = 0):value(val),in(inn),out(outt){}
	
};

(3)class Edge

节点有三部分数据,分别是边上的权重、当前边的from和to节点

class Edge
{
public:
	int weight;
	Node* from;
	Node* to;

	Edge(int wgt,Node* f,Node* t):weight(wgt),from(f),to(t){}
	
};

(4)class GraphGenerator

把产生图函数封装成了类。注意:采用(3)中矩阵的方式
图的产生过程如下,
①先生成一个graph对象,对数组按行遍历,第一个元素赋给权重,第二、第三元素表示节点值赋给from和to;
②判断当前图中以from、to为值得节点存在否,不存在则创建图中的节点
③再把图中from和to节点拿出来,建立边;
④补充from节点的指向节点to、边、出度。补充to节点的入度;
⑤把建立的边加到图里的边。

class GraphGenerator
{
public:
	Graph createGraph(vector<vector<int> > matrix)
	{
		Graph graph;//需要graph的node和edge 、node有五个data、edge有三个data 
		for(int i = 0; i < matrix.size();++i)
		{
			int weight = matrix[i][0];
			int from = matrix[i][1];
			int to = matrix[i][2];
			//Graph的node里不含有from节点、to节点时建上 
			if(graph.nodes.find(from) == graph.nodes.end())
				graph.nodes[from] = new Node(from);
			if(graph.nodes.find(to) == graph.nodes.end())
				graph.nodes[to] = new Node(to);
			//拿出from,to点
			Node* fromNode = graph.nodes[from];		
			Node* toNode = graph.nodes[to];
			//Node* fromNode = graph.nodes.find(from)->second;		
			//Node* toNode = graph.nodes.find(to)->second;
			//新建边 
			Edge* newEdge = new Edge(weight, fromNode, toNode);
			
			//增加节点的四个数据 
			fromNode->nexts.push_back(toNode);
			fromNode->edges.push_back(newEdge);
			fromNode->out++;
			toNode->in++;
			
			
			graph.edges.insert(newEdge);	
		}
		return graph; 
	} 
};

(5)测试

输出graph中的所有节点以及边

	//test 
	unordered_map<int,Node*>::iterator ite1 = graph.nodes.begin();
	while(ite1 != graph.nodes.end())
	{
	 	cout << "节点: "<<(ite1)->second->value<<"、";
		//cout << "节点: "<<(ite1)->first<<"、";
	 	ite1++;
	}
	cout<<endl<<"-----------------------------------------------"<<endl ;
	unordered_set<Edge*>::iterator ite = graph.edges.begin();
	while(ite != graph.edges.end())
	{
	 	cout << "边权为 "<<(*ite)->weight<<"    ";
	 	cout<<(*ite)->from->value <<"---->"<<(*ite)->to->value<<endl; 
	 	ite++;
	}
	cout<<endl<<"-----------------------------------------------"<<endl ;

4.完整代码

#include <iostream>

#include<unordered_map> 
#include<unordered_set>
#include<list>
#include<vector> 
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

class Edge;
class Node
{
public:
	int value;
	int	out;
	int in;
	list<Node*> nexts;
	list<Edge*> edges;

	Node(int val,int inn = 0,int outt = 0):value(val),in(inn),out(outt){}	
};

class Edge
{
public:
	int weight;
	Node* from;
	Node* to;

	Edge(int wgt,Node* f,Node* t):weight(wgt),from(f),to(t){}	
};

class Graph
{
public:
	unordered_map<int,Node*> nodes;
	unordered_set<Edge*> edges; 

	Graph(){};		
};

class GraphGenerator
{
public:
	Graph createGraph(vector<vector<int> > matrix)
	{
		Graph graph;//需要graph的node和edge 、node有五个data、edge有三个data 
		for(int i = 0; i < matrix.size();++i)
		{
			int weight = matrix[i][0];
			int from = matrix[i][1];
			int to = matrix[i][2];
			//Graph的node里不含有from节点、to节点时建上 
			if(graph.nodes.find(from) == graph.nodes.end())
				graph.nodes[from] = new Node(from);
			if(graph.nodes.find(to) == graph.nodes.end())
				graph.nodes[to] = new Node(to);
			//拿出from,to点
			Node* fromNode = graph.nodes[from];		
			Node* toNode = graph.nodes[to];
			//Node* fromNode = graph.nodes.find(from)->second;		
			//Node* toNode = graph.nodes.find(to)->second;
			//新建边 
			Edge* newEdge = new Edge(weight, fromNode, toNode);
			
			//增加节点的四个数据 
			fromNode->nexts.push_back(toNode);
			fromNode->edges.push_back(newEdge);
			fromNode->out++;
			toNode->in++;
			
			
			graph.edges.insert(newEdge);	
		}
		return graph; 
	} 
};

int main(int argc, char** argv) {
	GraphGenerator g;
	vector<vector<int> > matrix= {{7,1,2},{5,1,3},{2,2,3}};
	Graph graph = g.createGraph(matrix);

	//test 
	unordered_map<int,Node*>::iterator ite1 = graph.nodes.begin();
	while(ite1 != graph.nodes.end())
	{
	 	cout << "节点: "<<(ite1)->second->value<<"、";
		//cout << "节点: "<<(ite1)->first<<"、";
	 	ite1++;
	}
	cout<<endl<<"-----------------------------------------------"<<endl ;
	unordered_set<Edge*>::iterator ite = graph.edges.begin();
	while(ite != graph.edges.end())
	{
	 	cout << "边权为 "<<(*ite)->weight<<"    ";
	 	cout<<(*ite)->from->value <<"---->"<<(*ite)->to->value<<endl; 
	 	ite++;
	}
	cout<<endl<<"-----------------------------------------------"<<endl ;
	
	return 0;
}

在这里插入图片描述
在这里插入图片描述

发布了51 篇原创文章 · 获赞 1 · 访问量 1358

猜你喜欢

转载自blog.csdn.net/shi_xiao_xuan/article/details/104860257