|
|
|
@ -0,0 +1,75 @@
|
|
|
|
|
## <center>图</center>
|
|
|
|
|
|
|
|
|
|
### 1、图的概念
|
|
|
|
|
|
|
|
|
|
* 由点的集合和边的集合构成
|
|
|
|
|
* 虽然存在有向图和无向图的概念,但实际上都可以用有向图来表达
|
|
|
|
|
* 边上可能带有权值
|
|
|
|
|
|
|
|
|
|
  图的表示方法邻接表法、邻接矩阵法等。题目会以各种方式给出图的表达方式,可以将它转化为一种熟悉的表达方式,方便操作。可以将图表示为节点和边的集合,参考下面代码Graph。
|
|
|
|
|
|
|
|
|
|
```Java
|
|
|
|
|
public class Graph {
|
|
|
|
|
public Map<Integer, Node> nodes;
|
|
|
|
|
public Set<Edge> edges;
|
|
|
|
|
|
|
|
|
|
public Graph() {
|
|
|
|
|
this.nodes = new HashMap<>();
|
|
|
|
|
this.edges = new HashSet<>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Node {
|
|
|
|
|
// 节点值
|
|
|
|
|
public int value;
|
|
|
|
|
// 入度
|
|
|
|
|
public int in;
|
|
|
|
|
// 出度
|
|
|
|
|
public int out;
|
|
|
|
|
// 相邻节点
|
|
|
|
|
public List<Node> nexts;
|
|
|
|
|
// 节点的边
|
|
|
|
|
public List<Edge> edges;
|
|
|
|
|
|
|
|
|
|
public Node(int value) {
|
|
|
|
|
this.value = value;
|
|
|
|
|
in = 0;
|
|
|
|
|
out = 0;
|
|
|
|
|
nexts = new ArrayList<>();
|
|
|
|
|
edges = 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 宽度优先遍历
|
|
|
|
|
|
|
|
|
|
* 利用队列实现
|
|
|
|
|
* 从源节点开始依次按照宽度进队列,然后弹出
|
|
|
|
|
* 每弹出一个点,把该节点所有没有进过队列的邻接点放入队列
|
|
|
|
|
* 直到队列变空
|
|
|
|
|
|
|
|
|
|
### 深度优先遍历
|
|
|
|
|
|
|
|
|
|
* 利用栈实现
|
|
|
|
|
* 从源节点开始把节点按照深度放入栈,然后弹出
|
|
|
|
|
* 每弹出一个点,把该节点下一个没有进过栈的邻接点放入栈
|
|
|
|
|
* 直到栈变空
|
|
|
|
|
|
|
|
|
|
### 拓扑排序
|
|
|
|
|
|
|
|
|
|
  拓扑排序是不唯一的
|