图的广度优先遍历、深度优先遍历(递归、非递归)

import org.omg.CORBA.PUBLIC_MEMBER;

import java.util.*;

public class Recursion4 {

    /**
     * 深度优先搜索,使用递归
     *
     * @param graphNode
     * @param visited
     */
    public void dfs(GraphNode graphNode, List visited) {
        if (visited.contains(graphNode)) {
            return;
        }
        //递归,不能new的对象可以放在函数参数中
        //此时需要把已遍历的点存储起来,需要有个集合,可是递归方法中不能new集合,所以可以放在函数的参数中
        visited.add(graphNode);
        System.out.print(graphNode.label + " ");
        for (int i = 0; i < graphNode.edgeList.size(); i++) {
            dfs(graphNode.edgeList.get(i).getRightNode(), visited);
            //System.out.println("当前节点值:" + graphNode.getLabel());
        }
    }//dfs
    //0 1 3 5 4 7 2 6

    /**
     * 深度优先搜索,不使用递归
     *
     * @param graphNode
     * @param visited
     */
    public void dfsNoRecur(GraphNode graphNode, List visited) {
        Stack stack = new Stack<>();
        stack.add(graphNode);
        System.out.print(graphNode.label + " ");//首先输出第一个元素
        while (!stack.isEmpty()) {
            GraphNode node = stack.pop();
//            System.out.print(node.label + " ");//不能在这里输出
            for (int i = 0; i < node.edgeList.size(); i++) {
                if (!visited.contains(node.edgeList.get(i).getRightNode())) {
                    visited.add(node.edgeList.get(i).getRightNode());
                    stack.push(node);
                    stack.push(node.edgeList.get(i).getRightNode());
                    System.out.print(node.edgeList.get(i).getRightNode().label + " ");//把最新的节点输出来即可
                    break;//如果当前节点有多个相邻节点,则第一个节点先输出,并且这个节点进栈。下次时第一个节点已输出,则从第二个相邻节点找
                }
            }
        }
    }//dfsNoRecur
    //0 1 3 5 4 7 2 6


    /**
     * 广度优先遍历
     * @param graphNode
     * @param visited
     */
    public void bfs(GraphNode graphNode, List visited) {
        Queue graphNodeQueue = new LinkedList<>();
        graphNodeQueue.add(graphNode);
        while (!graphNodeQueue.isEmpty()) {
            GraphNode node = graphNodeQueue.poll();//弹出当前节点
            System.out.print(node.label + " ");
            for (int i = 0; i < node.edgeList.size(); i++) {
                if (!visited.contains(node.edgeList.get(i).getRightNode())) {
                    visited.add(node.edgeList.get(i).getRightNode());
                    graphNodeQueue.offer(node.edgeList.get(i).getRightNode());//把当前节点的相邻节点加入队列中
                }
            }
        }
    }//bfs


    public static void main(String[] args) {
        MyGraph myGraph = new MyGraph();
        myGraph.initGraph();
        Recursion4 recursion4 = new Recursion4();
        System.out.println("深度优先遍历,递归:");
        recursion4.dfs(myGraph.getGraphNodeList().get(0), new ArrayList());//深度优先遍历,递归
        System.out.println();
        System.out.println("深度优先遍历,非递归:");
        recursion4.dfsNoRecur(myGraph.getGraphNodeList().get(0), new ArrayList());//深度优先遍历,非递归
        System.out.println();
        System.out.println("广度优先遍历:");
        recursion4.bfs(myGraph.getGraphNodeList().get(0), new ArrayList());//广度优先遍历
    }
}//Recursion4

class GraphNode {
    List edgeList = null;
    Integer label = null;

    public GraphNode(Integer label) {
        this.label = label;
        if (edgeList == null) {//每个点都有edgeList
            edgeList = new ArrayList<>();
        }
    }

    public void addEdge(GraphEdge edge) {
        edgeList.add(edge);
    }

    public Integer getLabel() {
        return label;
    }
}//GraphNode

class GraphEdge {
    GraphNode leftNode;
    GraphNode rightNode;

    public GraphEdge(GraphNode leftNode, GraphNode rightNode) {
        this.rightNode = rightNode;
        this.leftNode = leftNode;
    }

    public GraphNode getRightNode() {
        return rightNode;
    }

    public GraphNode getLeftNode() {
        return leftNode;
    }
}//GraphEdge

class MyGraph {
    List graphNodeList = new ArrayList<>();

    public void initGraph() {
        for (int i = 0; i < 8; i++) {
            graphNodeList.add(new GraphNode(i));
        }
        GraphEdge graphEdge01 = new GraphEdge(graphNodeList.get(0), graphNodeList.get(1));
        GraphEdge graphEdge02 = new GraphEdge(graphNodeList.get(0), graphNodeList.get(2));
        GraphEdge graphEdge13 = new GraphEdge(graphNodeList.get(1), graphNodeList.get(3));
        GraphEdge graphEdge14 = new GraphEdge(graphNodeList.get(1), graphNodeList.get(4));
        GraphEdge graphEdge35 = new GraphEdge(graphNodeList.get(3), graphNodeList.get(5));
        GraphEdge graphEdge45 = new GraphEdge(graphNodeList.get(4), graphNodeList.get(5));
        GraphEdge graphEdge26 = new GraphEdge(graphNodeList.get(2), graphNodeList.get(6));
        GraphEdge graphEdge47 = new GraphEdge(graphNodeList.get(4), graphNodeList.get(7));

        graphNodeList.get(0).addEdge(graphEdge01);
        graphNodeList.get(0).addEdge(graphEdge02);

        graphNodeList.get(1).addEdge(graphEdge13);
        graphNodeList.get(1).addEdge(graphEdge14);

        graphNodeList.get(3).addEdge(graphEdge35);
        graphNodeList.get(4).addEdge(graphEdge45);
        graphNodeList.get(2).addEdge(graphEdge26);

        graphNodeList.get(4).addEdge(graphEdge47);
    }

    public List getGraphNodeList() {
        return graphNodeList;
    }

}//MyGraph

深度优先遍历,递归:
0 1 3 5 4 7 2 6 
深度优先遍历,非递归:
0 1 3 5 4 7 2 6 
广度优先遍历:
0 1 2 3 4 6 5 7 

图的广度优先遍历、深度优先遍历(递归、非递归)_第1张图片

参考:

https://blog.csdn.net/qq_32595453/article/details/80737706 图的广度与深度优先遍历(Java)

https://blog.csdn.net/lemon_tree12138/article/details/47319659 Java实现图的深度和广度优先遍历算法

你可能感兴趣的:(Java,算法,图,深度优先,广度优先,递归,非递归)