JAVA实现图的深度优先搜索和广度优先搜索
来源:互联网 发布:天气预报哪个软件好 编辑:程序博客网 时间:2024/05/21 11:12
1、深度优先搜索介绍
图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。
它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。
显然,深度优先搜索是一个递归的过程。
2、广度优先搜索介绍
广度优先搜索算法(Breadth First Search),又称为"宽度优先搜索"或"横向优先搜索",简称BFS。
它的思想是:从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。
换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远,依次访问和v有路径相通且路径长度为1,2...的顶点。
3、代码实现
深度优先搜索需要用到Stack
广度优先搜索需要用到Queue
顶点类:
public class Vertex { public char label; // 标识是否已经被访问过了 public boolean isVisit; public Vertex(char label, boolean isVisit) { this.label = label; this.isVisit = isVisit; }}
图类:
public class Graph { // 顶点的数组 private Vertex[] vertexList; // 邻接矩阵 private int[][] adjMat; // 数组最大大小 private int maxSize; // 当前数组大小 private int nVertex; /** * 初始化顶点数组、邻接矩阵 */ public Graph(int maxSize) { this.maxSize = maxSize; vertexList = new Vertex[maxSize]; adjMat = new int[maxSize][maxSize]; for (int i = 0; i < maxSize; i++) { for (int j = 0; j < maxSize; j++) { adjMat[i][j] = 0; } } nVertex = 0; } /** * 添加顶点 */ public void addVertex(char label) { vertexList[nVertex++] = new Vertex(label, false); } /** * 添加边 */ public void addEdge(int start, int end) { adjMat[start][end] = 1; adjMat[end][start] = 1; } /** * 深度优先搜索 */ public void dfs() { // 从0号顶点开始 int v = 0; String result = vertexList[v].label + " "; vertexList[v].isVisit = true; MyStack stack = new MyStack(); stack.push(v); while (!stack.isEmpty()) { v = stack.peek(); // 得到未访问过的邻接点 int unvisitedVertex = getUnvisitedVertex(v); if(unvisitedVertex == -1) { stack.pop(); } else{ result += vertexList[unvisitedVertex].label + " "; vertexList[unvisitedVertex].isVisit = true; stack.push(unvisitedVertex); } } System.out.println(result); // 将访问信息重置 resetVisit(); } /** * 广度优先搜索 */ public void bfs() { // 从0号顶点开始 int v = 0; vertexList[v].isVisit = true; String result = vertexList[v].label + " "; MyQueue queue = new MyQueue(100); queue.insert(v); while (!queue.isEmpty()) { v = queue.peek(); // 得到未访问过的邻接点 int unvisitedVertex = getUnvisitedVertex(v); if(unvisitedVertex == -1) { queue.remove(); } else { vertexList[unvisitedVertex].isVisit = true; result += vertexList[unvisitedVertex].label + " "; queue.insert(unvisitedVertex); } } System.out.println(result); // 将访问信息重置 resetVisit(); } /** * 获取未访问过的邻接点 */ public int getUnvisitedVertex(int v) { for (int i = 0; i < nVertex; i++) { if(adjMat[v][i] == 1 && vertexList[i].isVisit == false) { return i; } } return -1; } /** * 将访问信息的属性重置 */ private void resetVisit() { for (int i = 0; i < vertexList.length; i++) { vertexList[i].isVisit = false; } } /** * 打印图矩阵 */ public void printGraph() { System.out.println("********************************************"); System.out.print("\\ \t"); for (int i = 0; i < maxSize; i++) { System.out.print(vertexList[i].label + "\t"); } System.out.println(); for (int i = 0; i < maxSize; i++) { System.out.print(vertexList[i].label + "\t"); for (int j = 0; j < maxSize; j++) { System.out.print(adjMat[i][j] + "\t"); } System.out.println(); } System.out.println("********************************************"); }}测试类:
public class Test { public static void main(String[] args) { Graph graph = new Graph(10); graph.addVertex('A'); graph.addVertex('B'); graph.addVertex('C'); graph.addVertex('D'); graph.addVertex('E'); graph.addVertex('F'); graph.addVertex('G'); graph.addVertex('H'); graph.addVertex('I'); graph.addVertex('J'); graph.addEdge(0,1); graph.addEdge(1,2); graph.addEdge(2,3); graph.addEdge(0,4); graph.addEdge(4,5); graph.addEdge(5,6); graph.addEdge(0,7); graph.addEdge(7,8); graph.addEdge(8,9); graph.printGraph(); graph.dfs(); graph.bfs(); }}
Stack类:
public class MyStack {//底层实现是一个数组private int[] arr;private int top;/** * 默认的构造方法 */public MyStack() {arr = new int[10];top = -1;}/** * 带参数构造方法,参数为数组初始化大小 */public MyStack(int maxsize) {arr = new int[maxsize];top = -1;}/** * 添加数据 */public void push(int value) {arr[++top] = value;}/** * 移除数据 */public int pop() {return arr[top--];}/** * 查看数据 */public int peek() {return arr[top];}/** * 判断是否为空 */public boolean isEmpty() {return top == -1;}/** * 判断是否满了 */public boolean isFull() {return top == arr.length - 1;}}
Queue类:
public class MyQueue {//底层使用数组private int[] arr;//有效数据的大小private int elements;//队头private int front;//队尾private int end;/** * 默认构造方法 */public MyQueue() {arr = new int[10];elements = 0;front = 0;end = -1;}/** * 带参数的构造方法,参数为数组的大小 */public MyQueue(int maxsize) {arr = new int[maxsize];elements = 0;front = 0;end = -1;}/** * 添加数据,从队尾插入 */public void insert(int value) {arr[++end] = value;elements++;}/** * 删除数据,从队头删除 */public int remove() {elements--;return arr[front++];}/** * 查看数据,从队头查看 */public int peek() {return arr[front];}/** * 判断是否为空 */public boolean isEmpty() {return elements == 0;}/** * 判断是否满了 */public boolean isFull() {return elements == arr.length;}}
阅读全文
0 1
- Java实现深度优先搜索和广度优先搜索
- 基于图的深度优先搜索和广度优先搜索java实现
- java实现无向图的深度优先搜索和广度优先搜索
- java实现图的深度优先搜索和广度优先搜索
- JAVA实现图的深度优先搜索和广度优先搜索
- 广度优先搜索与深度优先搜索的 java 实现
- 深度优先搜索和广度优先搜索的代码实现
- 图的深度优先搜索和广度优先搜索模板
- 图的广度优先搜索和深度优先搜索
- 图的广度优先搜索和深度优先搜索
- 图的深度优先搜索和广度优先搜索
- 图的深度优先搜索和广度优先搜索
- 图的深度优先搜索和广度优先搜索
- 图的深度优先搜索和广度优先搜索
- 图的深度优先搜索和广度优先搜索
- 图的深度优先搜索和广度优先搜索
- 《图的深度优先搜索和广度优先搜索》
- 图的深度、广度优先搜索(JAVA实现)
- PQ-源码解析
- 求最大公约数2
- 存储过程、存储函数及触发器简介
- POJ-1236(tarjan缩点)
- Java求一维数组之和
- JAVA实现图的深度优先搜索和广度优先搜索
- 搬运工整理之HoloLens头戴设备连接PC 03
- Android中更改SQLite数据库中的数据后,刷新ListView。
- Win7系统设置路由器限制上网的方法
- USACO Section 1.2 Milking Cows
- TCP的定时器系列 — 超时重传定时器(有图有代码有真相!!!)
- 使用BmFont制作NGUI的图片字体
- 写给Android App开发人员看的Android底层知识(6)
- java 基于socket套接字的低层次网络编程