【图数据结构的遍历】java实现广度优先和深度优先遍历
宽度优先搜索(BFS)遍历图需要使用队列queue数据结构; 深度优先搜索(DFS, Depth First Search)的实现
需要使用到栈stack数据结构。
java中虽然有Queue接口,单java并没有给出具体的队列实现类,而Java中让LinkedList类实现了Queue接口,所以使用队列的时候,一般采用LinkedList。因为LinkedList是双向链表,可以很方便的实现队列的所有功能。
java中定义队列 一般这样定义: Queue queue = new LinkedList();
java中的栈由java.util.Stack类实现,是一个后进先出(last in first out,LIFO)的堆栈,在Vector类的基础上扩展5个方法而来。
E push(E item)
把项压入堆栈顶部。
E pop()
移除堆栈顶部的对象,并作为此函数的值返回该对象。
E peek()
查看堆栈顶部的对象,但不从堆栈中移除它。
boolean empty()
测试堆栈是否为空。
int search(Object o)
返回对象在堆栈中的位置,以 1 为基数。
BFS和DFS遍历代码实现如下:
import java.util.*;
/**
* 使用java实现图的图的广度优先 和深度优先遍历算法。
*/
public class GraphLoopTest {
private Map<String, List<String>> graph = new HashMap<>();
private Stack<String> stack = new Stack<>();
private Queue<String> queue = new LinkedList<>();
private Map<String, Boolean> status = new HashMap<>();
/**
* 初始化图数据:使用邻居表来表示图数据。
*/
public void initGraphData() {
// 图结构如下
// 1
// / | \
// 2 | 3
// / \ | / \
// 4 5 6 7
// \ \ /
// 8 9
graph.put("1", Arrays.asList("2", "3","5"));
graph.put("2", Arrays.asList("1", "4", "5"));
graph.put("3", Arrays.asList("1", "6", "7"));
graph.put("4", Arrays.asList("2", "8"));
graph.put("5", Arrays.asList("2","1"));
graph.put("6", Arrays.asList("3", "9"));
graph.put("7", Arrays.asList("3", "9"));
graph.put("8", Arrays.asList("4"));
graph.put("9", Arrays.asList("6", "7"));
}
/**
* 宽度优先搜索(BFS, Breadth First Search)
* BFS使用队列(queue)来实施算法过程
*/
/**
* 开始点
*
* @param startPoint
*/
public void BFSSearch(String startPoint) {
//1.把起始点放入queue;
queue.add(startPoint);
status.put(startPoint,true);
bfsLoop();
}
private void bfsLoop() {
if(queue.isEmpty()){
return;
}
// 1) 从queue中取出队列头的点;
String head = queue.poll();
System.out.println(head);
// 2) 找出与此点邻接的且尚未遍历的点,进行标记,然后全部放入queue中。
List<String> subs = graph.get(head);
for (String sub : subs) {
if(!status.getOrDefault(sub,false)){
queue.add(sub);
status.put(sub,true);
}
}
bfsLoop();
}
/**
* 深度优先搜索(DFS, Depth First Search)
* DFS使用队列(queue)来实施算法过程
* stack具有后进先出LIFO(Last Input First Output)的特性,DFS的操作步骤如下:
*/
// 1、把起始点放入stack;
// 2、重复下述3步骤,直到stack为空为止:
// 从stack中访问栈顶的点;
// 找出与此点邻接的且尚未遍历的点,进行标记,然后全部放入stack中;
// 如果此点没有尚未遍历的邻接点,则将此点从stack中弹出。
public void DFSSearch(String startPoint) {
stack.push(startPoint);
status.put(startPoint,true);
dfsLoop();
}
private void dfsLoop() {
if(stack.empty()){
return;
}
//弹出栈顶元素,并将其相邻结点
String top = stack.pop();
System.out.println(top);
List<String> subs = graph.get(top);
for (String sub : subs) {
if(!status.getOrDefault(sub,false)){
DFSSearch(sub);
}
}
}
public static void main(String[] args) {
GraphLoopTest test = new GraphLoopTest();
test.initGraphData();
test.BFSSearch("1");
//test.DFSSearch("1");
}
}