什么是图
图是一个由点的集合和边的集合所构成的数据结构。
图分为有向图和无向图。其中无向图也可以理解为有向图,所以可以认为所有的图都是有向图。
比方说,有这么一张图。其中a指向bc,b指向c,c指向p。边是带方向的,所以这是一个有向图。
而无向图呢? a连b,b连c,c连a。完全可以理解为ab互相指向,bc互相指向,ca互相指向,所以无向图也可以理解为都是有向图。
而图的表达方式有很多,其中常见的有邻接表法,邻接矩阵法等等。图的算法不难,难的是图的数据结构的表达。
比如说,给定一个n * 3的二维数组,[1 , 3 , 5],[0 , 5 , 5 ],[2 , 6 , 5]其中[i][0]代表的是边的权重,[i][1],[i][2]代表的是边从哪到哪。给的是每条边的权重以及从哪到哪,根据每条边画出来的图是这样的。这也是一种图的表示。
甚至更可以用1维数组表示一张图,所以用不同的方式表达图,所用到的解法也不同,每一种coding都要练习,那是不是可以将结构进行统一?无论什么样的图,都转换成自己的结构,将抽象化的图通过代码变得具象化,面向对象编程的思想更多一些。
代码
通过代码将点进行转化,Node对象中封装了这个点的所有基本信息,点的值,连接到这个点上的边有多少,从这个点出去的边有多少。
/*
* 点的描述
* */
public class Node {
//点本身value
public int value;
//入度(有多少个点的边直接指向该点)
public int in;
//出度(从自己出发,直接指向别人的)
public int out;
//从自己出发能找到的边
public ArrayList<Edge> edges;
//从自己出发能找到的点
public ArrayList<Node> nexts;
public Node(int val){
this.value = val;
this.in = 0;
this.out = 0;
edges = new ArrayList<>();
nexts = new ArrayList<>();
}
}
边的描述信息,包含边的权重,从哪个点连接到哪个点。
/*
* 边的描述信息
* */
public class Edge {
//边的权重
public int weight;
//从哪个点出来
public Node from;
//连接到哪个点
public Node to;
public Edge(int weight,Node from,Node to){
this.weight = weight;
this.from = from;
this.to = to;
}
}
一个图是由多个点和边所组成,所以包含了所有的点信息和边的信息,其中HashMap是具体的点的值和封装的点的对象。
/*
* 图的描述,包含了所有的点和所有的边
* */
public class Graph {
public HashMap<Integer,Node> nodes;
public HashSet<Edge> edges;
public Graph(){
nodes = new HashMap<>();
edges = new HashSet<>();
}
}
生成图代码
以图形式为二维数组为例,[i][0]位置是边的权重,[i][1],[i][2]是从哪个点连到哪个点。
public class GraphGenerator {
public static Graph createGraph(int[][] matrix) {
Graph graph = new Graph();
for (int i = 0; i < matrix.length; i++) {
int weight = matrix[i][0];
int from = matrix[i][1];
int to = matrix[i][2];
if (!graph.nodes.containsKey(from)){
graph.nodes.put(from,new Node(from));
}
if (!graph.nodes.containsKey(to)){
graph.nodes.put(to,new Node(to));
}
Node fromNode = graph.nodes.get(from);
Node toNode = graph.nodes.get(to);
Edge edge = new Edge(weight,fromNode,toNode);
fromNode.nexts.add(toNode);
fromNode.out++;
toNode.in++;
fromNode.edges.add(edge);
graph.edges.add(edge);
}
return graph;
}
}