图的定义和应用
- 图的定义
- 图是由一组顶点 和 能够将两个顶点相连的边组成的
- 图的应用
- 地图
无向图
图的术语
要表示一幅图,需要表示清楚部分内容
- 图中所有的顶点
- 所有顶点的边
下面是实现一个 无加权 无向图的Api
import java.util.LinkedList;
import java.util.Queue;
/**
* 无加权 无向图
*/
public class Graph {
/**
* 图中 顶点数
*/
private final int V;
/**
* 记录图中边的数量
*/
private int E;
/**
* 邻接表
*/
private Queue< Integer >[] adj;
public Graph (int v) {
this.V = v;
this.E = 0;
adj = new Queue[v];
for (int i = 0; i < v; ++i) {
adj[i] = new LinkedList<>();
}
}
/**
* 获得图的顶点数量
*
* @return
*/
public int V () {
return V;
}
/**
* 获得图中边的数量
*
* @return
*/
public int E () {
return E;
}
/**
* 顶点v 和 顶点w 之间关联起来 v - w
*
* @param v
* @param w
*/
public void addEage (int v, int w) {
adj[v].add(w);
adj[w].add(v);
}
/**
* 获取v 顶点关联的所有顶点
*
* @param v
* @return
*/
public Queue adj (int v) {
return adj[v];
}
}
图的搜索
- 深度优先搜索
深度优先搜索,是指在搜索的时候,遍历一个结点的子结点,发现子结点还有子结点,先向下搜索 ,回溯返回回来 在搜索兄弟结点
/**
* 深度优先搜索
*/
public class DepthFirstSearch {
/**
* 记录结点是否被搜索过,应为图可能是连通的 ,搜索会进入死循环
*/
private boolean[] marked;
/**
* 记录图中多少个结点和 我们传入的v结点相联通
*/
private int count;
/**
* 传入一个图,和一个要搜索的结点
* @param g
* @param v
*/
public DepthFirstSearch (Graph G , int v) {
marked = new boolean[G.V()];
count = 0;
dfs(G,v);
}
private void dfs (Graph G , int v) {
marked[v] = true;
for (Integer w : G.adj(v)) {
if (!marked[w])
dfs(G,w);
}
++count;
}
/**
* 判断w 和 v 顶点是否相通
* @param w
* @return
*/
public boolean marked (int w) {
return marked[w];
}
}
- 广度优先搜索
广度优先搜索的时候,指的是在搜索时,如果遇到一个结点 既有子结点 又有兄弟结点,先搜索兄弟结点后 在搜索子结点,(层次遍历)
/**
* 广度优先搜索
*/
public class BreathFirstSearch {
/**
* 记录结点是否被搜索到
*/
private boolean[] marked;
/**
* 与传入的结点v 能搜索到的结点的数量
*/
private int count;
/**
* 用一个队列才层次遍历图
*/
private Queue<Integer> waitQueue;
/**
* 初始化 将从v 出发能够的搜索到的结点 全部记录在了 marked中
* @param G
* @param v
*/
public BreathFirstSearch (Graph G, int v) {
marked = new boolean[G.V()];
count = 0;
waitQueue = new LinkedList<Integer>();
waitQueue.add(v);
bfs(G,v);
}
private void bfs (Graph G, int w) {
marked[w] = true;
while (!waitQueue.isEmpty()) {
Integer pollNode = waitQueue.poll();
for (Integer adj : G.adj(pollNode)) {
if (!marked[adj])
bfs(G,adj);
}
}
++count;
}
/**
* 判断顶点w 和 v 是否相同
* @param w
* @return
*/
public boolean marked (int w) {
return marked[w];
}
}