深度优先遍历 广度优先遍历JAVA
2017-11-25 16:50
351 查看
package graph; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; /** * @Author GJL * @Desription * @Date 2017/11/25 * @Modified By: **/ public class BFS { public static void main(String[] args) { Graph graph = new Graph(6); graph.addNode(new GraphNode("A")); graph.addNode(new GraphNode("B")); graph.addNode(new GraphNode("C")); graph.addNode(new GraphNode("D")); graph.addNode(new GraphNode("E")); graph.addNode(new GraphNode("F")); graph.addEdge(0,1); graph.addEdge(0,2); graph.addEdge(0,3); graph.addEdge(1,4); graph.addEdge(2,4); graph.addEdge(3,4); graph.addEdge(4,5); //graph.bfs(0); graph.printMatrx(); System.out.println(); graph.dfs(0); } } class Graph{ //保存节点的数组 GraphNode [] graphNodes; //初始化时候 数组的大小 int size; //加入节点时候 已经存在的节点数 int curSize; //保存节点之间的联通关系 int[][] relation; public Graph(int size) { this.graphNodes = new GraphNode[size]; this.size = size; this.curSize = 0; this.relation = new int[size][size]; } public void addNode(GraphNode graphNode){ if(curSize<=size){ graphNodes[curSize++] = graphNode; }else{ System.out.println("节点数组已满"); } } public void addEdge(int start,int end){ if(start<size && end<size){ relation[start][end] = 1; relation[end][start] = 1; }else{ System.out.println("请输入正确的start end"); } } /** * @param nodeIndex 节点数组下标 */ public void bfs(int nodeIndex){ //利用队列 来存储那些与 已经遍历节点的相连节点索引 LinkedList list = new LinkedList(); //节点设置访问值为 true 节点索引入队列 graphNodes[nodeIndex].setVisted(true); list.offer(nodeIndex); while(!list.isEmpty()){ //获取索引 int index = (int)list.poll(); //获取节点 并打印 name值 System.out.println( graphNodes[index].getName()); for(int i = 0;i<curSize;i++){ if(!graphNodes[i].getVisted() && relation[index][i] == 1){ //如果该节点与index节点联通 获取 该节点 并把该节点置位访问过 GraphNode node = graphNodes[i]; node.setVisted(true); //入队列 list.offer(i); } } } } //深度优先搜索 利用栈 可以尝试使用LinkedList 或者自己实现栈结构 入栈 addFirst() 出栈 removeFirst() 获取 栈顶元素 getFirst() public void dfs(int nodeIndex){ LinkedList<Integer> list = new LinkedList(); //设置改图的第一个索引节点为 遍历 过后 的状态 graphNodes[nodeIndex].setVisted(true); //打印 其name 值 System.out.println(graphNodes[nodeIndex].getName()); //将该节点索引入栈 list.addFirst(nodeIndex); //当栈 不为空时候 一直循环 while(!list.isEmpty()){ //只是取出栈顶的index值 (并没有删除 节点) int index = list.getFirst(); //调用 一个 获取 当前节点 的联通节点的索引 函数 获取 其中 一个 可用索引(即 并未 遍历过)//从这 我们 可以看出 list 维护的列表的大小 一层只是 一个 这就是深度搜索 优于 广度遍历 的地方 占用内存 少一点 int j = getNextAdjNodeIndex(index); //如果 获取 到 索引 那么 对应节点 置为 访问过 并且 打印 入栈,否则 出栈 (后续再 继续 循环 回溯) if(j!= -1){ graphNodes[j].setVisted(true); System.out.println(graphNodes[j].getName()); list.addFirst(j); }else{ list.removeFirst(); } } } //通过索引p来获取 邻接矩阵中与该 节点联通 的 节点索引 private int getNextAdjNodeIndex(int p) { for(int i=0; i<curSize;i++){ if(!graphNodes[i].getVisted() && relation[p][i] == 1){ return i; } } return -1; } public void printMatrx(){ for(int[] arr: relation){ System.out.println(); for(int i:arr){ System.out.print(i); } } } } class GraphNode{ private String name; private boolean visted; public GraphNode(String name) { this.name = name; this.visted = false; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean getVisted() { return visted; } public void setVisted(boolean visted) { this.visted = visted; } }
相关文章推荐
- java实现图的遍历(深度优先遍历和广度优先遍历)
- 二叉树的深度和广度优先遍历 - Java实现
- Java数据结构----图--深度优先遍历BFS和广度优先遍历DFS
- 数据结构和算法之:图的深度优先和广度优先遍历及其Java实现
- 深度优先和广度优先遍历及其 Java 实现
- 图的理解:深度优先和广度优先遍历及其 Java 实现
- 数据结构--图的理解:深度优先和广度优先遍历及其 Java 实现
- Java数据结构----图--深度优先遍历BFS和广度优先遍历DFS
- 二叉树的深度和广度优先遍历 - Java实现-2
- 深度优先和广度优先遍历及其 Java 实现
- 图的理解:深度优先和广度优先遍历及其 Java 实现
- 存储结构与邻接矩阵,深度优先和广度优先遍历及Java实现
- Java图的遍历(深度优先遍历、广度优先遍历)
- java 图的邻接矩阵表示,深度优先遍历,广度优先遍历
- 深度优先和广度优先遍历及其 Java 实现
- Java 实现深度优先和广度优先遍历
- 图的理解:深度优先和广度优先遍历及其 Java 实现
- Java图的建立以及深度广度优先遍历(邻接矩阵)
- java 图的邻接矩阵表示,深度优先遍历,广度优先遍历
- 图的深度优先和广度优先遍历及其Java实现