问题描述
图的算法本身都不难,但是,在面试中,我们却往往会死在图的算法上,这是为什么呢?
那是因为,图的算法虽然都不难,但是数据结构比较复杂多变,因为能表达图的数据结构实在是太多样化了,比如经典的邻接矩阵,邻接表等等。
因此,在面试中,拿到不熟悉的数据结构,还要在此基础上写出图的算法,那肯定就有难度了,因此,既然图的数据结构复杂,我们能否在面试中,把面试官给的复杂数据结构,转换成我们熟悉的数据结构来表示图呢?
当然可以了,因此,我们只需要准备一个我们自己熟悉的图的数据结构,然后,在面试中,将特殊的图的数据结构转换成我们自己的表示。
我的图的数据结构:
图:
//图就是节点和边的集合嘛
class Graph{
//节点集合
public HashMap<Integer,Node> nodes;
//边的集合
HashSet<Edges> edges;
public Graph(){
nodes=new HashMap<Integer, Node>();
edges=new HashSet<Edges>();
}
}
图的节点:
//节点数据结构,这是有向节点,无向节点可以由两个这个节点组合而成
class Node{
//节点的值
int value;
//入度
int in;
//出度
int out;
//指向的所有其余节点
ArrayList<Node> nexts;
//所有边
ArrayList<Edges> edges;
public Node(int value){
nexts=new ArrayList<>();
edges=new ArrayList<>();
in=0;
out=0;
this.value=value;
}
}
边的数据结构:
//边的数据结构
class Edges{
//权重
int weight;
//起始节点
Node from;
//终止节点
Node to;
public Edges(int weight,Node from,Node to){
this.weight=weight;
this.from=from;
this.to=to;
}
}
转换函数(将别人图的数据结构变成自己的):这里以一个特殊函数二维数组为例子,arr[][0]表示路径权重,arr[][1]表示始发节点,arr[][0]表示终止节点。
public static Graph createGtaph(int[][] arr){
//假设数组中第一位代表路径权重,第二位代表初始节点,第三位代表终止节点
Graph graph=new Graph();
for (int i = 0; i < arr.length; i++) {
//先提取出信息
int weight=arr[i][0];
int from=arr[i][1];
int to=arr[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);
//创建边
Edges ege=new Edges(weight,fromNode,toNode);
//开始设置节点直接关系
fromNode.nexts.add(toNode);
fromNode.out++;
toNode.in++;
fromNode.edges.add(ege);
graph.edges.add(ege);
}
return graph;
}