Java:[算法]深度优先搜索DFS
Posted K Depth
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java:[算法]深度优先搜索DFS相关的知识,希望对你有一定的参考价值。
package com.unit4.Graph;
import com.unit1.algs1_2.Stack;
/**
* @Author Kou
* @Date: 2021/4/26 15:55
* @Description: DFS
*/
public class DepthFirstPath {
private boolean[] marked; //此顶点是否已经调用了dfs();
private int[] edgeTo; //每个顶点到起点的路径。从起点到一个顶点已知的最后一条路径。
private final int s; //起点
public DepthFirstPath(Graph graph, int s) {
this.marked = new boolean[graph.VERTEX_NUM()];
this.edgeTo = new int[graph.VERTEX_NUM()];
this.s = s;
dfs(graph, s);
}
/**
* 深度优先搜索DFS
*
* @param graph a graph
* @param v 起点
*/
private void dfs(Graph graph, int v) {
marked[v] = true; //调用当前结点
for (int w : graph.adj(v)) {
if (!marked[w]) { //如果当前结点还没有被调用
edgeTo[w] = v; //记录最后一条已知的路径
dfs(graph, w);
}
}
}
/**
* 是否存在从s到v的路径
*
* @param v 终点
* @return Yes or No
*/
public boolean hasPathTo(int v) {
return marked[v];
}
/**
* s到v的路径,如果不存在则返回null
*
* @param v 终点
* @return Path from s to v
*/
public Iterable<Integer> pathTo(int v) {
if (!hasPathTo(v)) {
return null;
}
Stack<Integer> path = new Stack<>();
for (int x = v; x != s; x = edgeTo[x]) {
path.push(x);
}
path.push(s);
return path;
}
}
package com.unit4.Graph;
import java.util.Scanner;
/**
* 邻接表无向图
*/
public class Graph {
private final int VERTEX_NUM; //顶点数目
private int edgeNum; //边的数目
private Bag<Integer>[] adjacencyList; //邻接表
/**
* 创建一个含有VERTEX_NUM个顶点但不含有边的图
*
* @param VERTEX_NUM vertex number
*/
public Graph(int VERTEX_NUM) {
this.VERTEX_NUM = VERTEX_NUM;
this.edgeNum = 0;
adjacencyList = new Bag[VERTEX_NUM]; //创建邻接表
for (int v = 0; v < VERTEX_NUM; v++) { //将所有链表初始化为空
adjacencyList[v] = new Bag<>();
}
}
/**
* 从标准输入流中读取一幅图
*
* @param in 输入
*/
public Graph(Scanner in) {
this(in.nextInt()); //读取VERTEX并将图初始化
int edgeNum = in.nextInt(); //读取edgeNum
for (int i = 0; i < edgeNum; i++) {
//添加一条边
int v = in.nextInt(); //读取两个顶点
int w = in.nextInt();
addEdge(v, w);
}
}
public int VERTEX_NUM() {
return this.VERTEX_NUM;
}
public int edgeNum() {
return this.edgeNum;
}
/**
* add an edge
*
* @param v a vertex
* @param w another vertex
*/
public void addEdge(int v, int w) {
adjacencyList[v].add(w); //将w添加进v的链表中
adjacencyList[w].add(v); //将v添加进w的链表中
edgeNum++; //边的总数+1
}
/**
* 与v相邻的所有顶点
*
* @param v a vertex
* @return all of v's neighbors
*/
public Iterable<Integer> adj(int v) {
return adjacencyList[v];
}
/**
* 计算v的度数
*
* @param graph 图
* @param v v顶点
* @return 返回v的度数
*/
public static int degree(Graph graph, int v) {
int degree = 0;
for (int w : graph.adj(v)) {
degree++;
}
return degree;
}
/**
* 邻接表的字符串表示
*
* @return 邻接表字符串
*/
@Override
public String toString() {
String s = VERTEX_NUM + "vertices," + edgeNum + " edges\n";
for (int v = 0; v < VERTEX_NUM; v++) {
s = s + v + ": ";
for (int w : this.adj(v)) {
s = s + w + " ";
}
s = s + "\n";
}
return s;
}
}
package com.unit1.algs1_2;
import java.util.Iterator;
/**
* 下压堆栈 (链表实现)
* date 2021/3/20
*
* @param <Item>
* @author Kou
*/
public class Stack<Item> implements Iterable<Item> {
private Node first; // 栈顶(首元结点)
private int N; // 元素数量
private class Node {
//结点嵌套类
Item item;
Node next;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
public void push(Item item) {
//将元素压入栈
Node oldFirst = first;
first = new Node();
first.item = item;
first.next = oldFirst;
N++;
}
public Item pop() {
//出栈
Item item = first.item;
first = first.next;
N--;
return item;
}
public Iterator<Item> iterator() {
return new ReverseStack();
}
private class ReverseStack implements Iterator<Item> {
// 支持后进先出的迭代
private Node current = first;
public boolean hasNext() {
return current != null;
}
public Item next() {
Item item = (Item) current.item;
current = current.next;
return item;
}
public void remove() {
}
}
}
package com.unit4.Graph;
import java.util.Scanner;
/**
* @Author Kou
* @Date: 2021/4/26 16:31
* @Description: DFS测试用例
*/
public class DFSTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Graph graph = new Graph(in);
int s = in.nextInt();
DepthFirstPath dfs = new DepthFirstPath(graph, s);
for (int v = 0; v < graph.VERTEX_NUM(); v++) {
System.out.print(s + " to " + v + ": ");
if (dfs.hasPathTo(v)) {
for (int x : dfs.pathTo(v)) {
if (x == s) { //如果x等于起点
System.out.print(x);
} else {
System.out.print("-" + x);
}
}
}
System.out.println();
}
}
}
以上是关于Java:[算法]深度优先搜索DFS的主要内容,如果未能解决你的问题,请参考以下文章
数据结构与算法图遍历算法 ( 深度优先搜索 DFS | 深度优先搜索和广度优先搜索 | 深度优先搜索基本思想 | 深度优先搜索算法步骤 | 深度优先搜索理论示例 )