您的位置:首页 > 编程语言 > Java开发

深度优先搜索和广度优先搜索

2017-12-02 17:41 288 查看

邻接表数组法

图是点和边的集合。如下图所示:




假定所有的点都是以0-N的自然数来表示,用数组a
索引(下标)代表所有的点,数组的元素为一个保存了与该点直接相连的所有的点的容器(Bag)。即a
表示所有和点N直接相连的点的集合,如下图所示:



此种对图的描述方法称为邻接表数组法。

一个图(Graph)对象对外提供的API:

API含义
int V()顶点数
int E()边数
Iterable adj(int v)返回和v相邻的所有顶点
addEdge(int v, int w)向图中添加一条边v-w

构建一幅图

public class Graph {
public Graph(In in) {
int lines = in.readInt();
for (int i = 0; i < lines; i++) {
int v = in.readInt();
int w = in.readInt();
addEdge(v, w);
}
}
public void addEdge(int w, int w) {
adj[w].add(v);
adj[v].add(w);
E++;
}

}


深度优先搜索

作用:判断某定点和给定起点是否相连

特点:从离起点较远的点开始搜索

public class DFS{
private boolean[] marked;
public DFS(Graph g, int s) {
marked[] = new boolean[g.V()];//boolean数组记录图中所有顶点和起点s的相连情况
dfs(g, s);
}
public void dfs(Graph g, int v) {
marked[v] = true;
for (int w : v.adj()) {
if (!maked[w]) {//深度优先搜索每条边都会被访问两次,且第二次访问时总会发现该顶点已经被标记过
dfs(g, w);
}
}
}
public boolean marked(int v){
return marked[v];
}
}


广度优先搜索

作用:返回给定的两个顶点之间的一条路径

特点:从起点附近的点开始搜索

public class BFS {
private boolean[] marked;
private int[] edgeTo;//用edge[w]=v记录从v到w的一条边
private int s;//起点
public BFS(Graph g, int s) {
edgeTo = new int(V)[g.V()];
marked = new boolean[g.V()];
this.s = s;
}
public void bfs(Graph g, int s) {
Queue<Integer> queue = new Queue<Integer>(); //用队列保存身边的顶点
marked[s] = true;
queue.enqueue(s);
while(!queue.empty()) {
int v = queue.dequeue();
for (int w : g.adj(v)) {
if (!marked[w]) {
marked[w] = true;
queue.enqueue(w);//身边的点先入列
edgeTo[w] = v;
}
}
}
}

public Iterable<Integer> pathTo(int v) {
Stack stack = new Stack;
stack.add(v);
int i = v;
while(i != s){
i = edgeTo[i];
stack.push(i);
}
return stack;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息