深度优先遍历 广度优先遍历JAVA

来源:互联网 发布:土库曼斯坦 知乎 编辑:程序博客网 时间:2024/05/20 08:23
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;    }}
原创粉丝点击