概念:
1)由点的集合和边的集合构成
2)虽然存在有向图和无向图的概念,但实际上都可以用有向图来表达
3)边上可能带有权值图结构的表达:
1)邻接表法
2)邻接矩阵法
3)除此之外还有其他众多的方式图如何搞定:
1)先用自己最熟练的方式,实现图结构的表达
2)在自己熟悉的结构上,实现所有常用的图算法作为模板
3)把面试题提供的图结构转化为自己熟悉的图结构,再调用模板或改写即可
1、点结构的描述
//点结构的描述
public class Node {
//当前节点值
public int value;
//代表有多少个节点是连接到当前节点的
public int in;
//代表从当前节点出发,可以连接到多少个节点
public int out;
//直接邻居,代表从当前节点出发连接到的节点
public ArrayList<Node> nexts;
//边,代表从当前节点出发连接到的节点所组成的边
public ArrayList<Edge> edges;
public Node(int value) {
this.value = value;
in = 0;
out = 0;
nexts = new ArrayList<>();
edges = new ArrayList<>();
}
}
2、有向边
//有向边
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;
}
}
3、图
//图
public class Graph {
//点集合,代表编号为N的节点是啥
public HashMap<Integer, Node> nodes;
//边集合
public HashSet<Edge> edges;
public Graph() {
nodes = new HashMap<>();
edges = new HashSet<>();
}
}
4、图结构转化
//把面试题提供的图结构转化为自己熟悉的图结构
// matrix 所有的边
// N*3 的矩阵
// [weight, from节点上面的值,to节点上面的值]
public static Graph createGraph(Integer[][] matrix) {
//新建一个图
Graph graph = new Graph();
for (int i = 0; i < matrix.length; i++) {
// matrix[0][0], matrix[0][1] matrix[0][2]
// 依次取出权重、开始节点值、结束节点值
Integer from = matrix[i][0];
Integer to = matrix[i][1];
Integer weight = 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 newEdge = new Edge(weight, fromNode, toNode);
fromNode.nexts.add(toNode);
fromNode.out++;
toNode.in++;
fromNode.edges.add(newEdge);
graph.edges.add(newEdge);
}
return graph;
}