1. 基本概念
图是由顶点和边组成的数据结构。
度是指与该顶点相邻的边的个数。有向图细分为出度和入度。
权(weight):边可以有权重,代表从源顶点到目标顶点的距离,费用或其他度量。
路径被定义为从一个顶点到另一个顶点的一系列连续的边。
路径长度:
- 不考虑权重,长度就是边的数量。
- 考虑权重,一般就是权重累加。
图的连通性:如果两个顶点之间存在路径,就说明这两个顶点是连通的,如果所有顶点都连通,则该图被称之为连通图,如子图连通,则称为连通分量。
2. 设计顶点和边的类
public class Vertex {
// 顶点的名字,用来区分顶点
String name;
// 与该顶点有关的边的集合
List<Edge> edges;
// 判断是否已经被遍历
boolean visited = false;
public Vertex(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Edge {
// 表示边上被箭头指向(箭头)的顶点
Vertex linked;
// 权重
int weight;
public Edge(Vertex linked) {
this.linked = linked;
weight = 1;
}
public Edge(Vertex linked, int weight) {
this.linked = linked;
this.weight = weight;
}
}
3. 图的DFS和BFS代码
借用的图结构为:
public class Graph {
public static void main(String[] args) {
Vertex v1 = new Vertex("1");
Vertex v2 = new Vertex("2");
Vertex v3 = new Vertex("3");
Vertex v4 = new Vertex("4");
Vertex v5 = new Vertex("5");
Vertex v6 = new Vertex("6");
// JDK版本太低,用不了of方法
v1.edges = new ArrayList<>();
v1.edges.add(new Edge(v3));
v1.edges.add(new Edge(v2));
v1.edges.add(new Edge(v6));
v2.edges = new ArrayList<>();
v2.edges.add(new Edge(v4));
v3.edges = new ArrayList<>();
v3.edges.add(new Edge(v4));
v3.edges.add(new Edge(v6));
v4.edges = new ArrayList<>();
v4.edges.add(new Edge(v5));
v5.edges = new ArrayList<>();
v6.edges = new ArrayList<>();
v6.edges.add(new Edge(v5));
// dfs2(v1);
//1 6 5 2 4 3
bfs(v1);
//1 3 2 6 4 5
}
// 深度优先搜索遍历图(递归)
public static void dfs1(Vertex v) {
v.visited = true;
System.out.print(v.name + " ");
for (Edge i : v.edges) {
if(!i.linked.visited){
dfs1(i.linked);
}
}
}
// 使用栈来实现dfs
public static void dfs2(Vertex v) {
Deque<Vertex> deque = new LinkedList<>();
deque.push(v);
while (!deque.isEmpty()){
Vertex pop = deque.pop();
pop.visited = true;
System.out.print(pop.name + " ");
for(Edge i : pop.edges){
if(!i.linked.visited){
deque.push(i.linked);
}
}
}
}
// 使用宽度优先搜索遍历图BFS
public static void bfs(Vertex v) {
Deque<Vertex> deque = new LinkedList<>();
v.visited = true;
deque.offer(v);
while(!deque.isEmpty()){
Vertex poll = deque.poll();
System.out.print(poll.name + " ");
for (Edge i : poll.edges){
if(!i.linked.visited){
i.linked.visited = true;
deque.offer(i.linked);
}
}
}
}
}