图的深度优先遍历和广度优先遍历

图的深度优先遍历和广度优先遍历

在这里插入图片描述

算法实现原理见注释


import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created by yangrs on 2020/6/6.
 */
public class GraphTraversal {

    public static void main(String[] args) {
        double[][] adjacentMatrix = new double[][]{
                {0,1,0,0,0,0,0,1,0}
                ,{1,0,1,0,1,0,0,0,0}
                ,{0,1,0,1,0,0,0,0,0}
                ,{0,0,1,0,1,1,0,0,0}
                ,{0,1,0,1,0,0,0,0,0}
                ,{0,0,0,1,0,0,1,1,0}
                ,{0,0,0,0,0,1,0,0,0}
                ,{1,0,0,0,0,1,0,0,1}
                ,{0,0,0,0,0,0,0,1,0}
        };
        Graph graph = new Graph(adjacentMatrix);
        System.out.println("DFS");
        graph.nodeReset();
        graph.dfs(graph.getNodes()[0]);
        System.out.println("BFS");
        graph.nodeReset();
        graph.bfs(graph.getNodes()[0]);

    }
}

class Graph {
    private double[][] adjacentMatrix;
    private int size;
    private Node[] nodes;

    public Graph(double[][] adjacentMatrix, int size) {
        this.adjacentMatrix = adjacentMatrix;
        this.size = size;
        this.nodes = new Node[this.size];
        for (int id = 0; id < this.size; id++) {
            this.nodes[id] = new Node(id,null);
        }
        for (int i = 0; i < this.adjacentMatrix.length; i++) {
            for (int j = 0; j < this.size; j++) {
                if (0 == this.adjacentMatrix[i][j]) continue;
                if (null == this.nodes[i].getChilds()) {
                    this.nodes[i].setChilds(new ArrayList<>());
                }
                this.nodes[i].getChilds().add(nodes[j]);
            }
        }
    }

    public Graph(double[][] adjacentMatrix) {
        this.adjacentMatrix = adjacentMatrix;
        this.size = adjacentMatrix.length;
        this.nodes = new Node[this.size];
        for (int id = 0; id < this.size; id++) {
            this.nodes[id] = new Node(id,null);
        }
        for (int i = 0; i < this.adjacentMatrix.length; i++) {
            for (int j = 0; j < this.size; j++) {
                if (0 == this.adjacentMatrix[i][j]) continue;
                if (null == this.nodes[i].getChilds()) {
                    this.nodes[i].setChilds(new ArrayList<>());
                }
                this.nodes[i].getChilds().add(nodes[j]);
            }
        }
    }

    public Graph() {
    }

    public void nodeReset() {
        for (Node node : this.nodes) {
            node.setVisited(false);
        }
    }

    /**
     * 深度优先搜索,每次访问一个节点,将节点入栈并标记为已访问,再依次访问节点的子节点。如果当前节点没有子节点或子节点均已被访问则出栈。
     * @param node
     */
    public void dfs(Node node) {
        node.setVisited(true);
        if (null != node.getChilds() && !node.getChilds().isEmpty()) {
            List<Node> children = node.getChilds();
            for (Node child : children) {
                if (!child.isVisited()) {
                    dfs(child);
                }
            }
        }
        System.out.println(node.getValue());
    }


    /**
     * 广度优先搜索,借助队列实现,先将根节点入队。然后做循环操作,每次循环弹出队头节点并将队头节点的子节点全部入队。循环操作直到对列为空
     * @param node
     */
    public void bfs(Node node) {
        Queue<Node> candidateQueue = new LinkedBlockingQueue<>();
        candidateQueue.add(node);
        node.setVisited(true);
        while(!candidateQueue.isEmpty()) {
            Node outNode = candidateQueue.poll();
            System.out.println(outNode.getValue());
            if (null != outNode.getChilds() && !outNode.getChilds().isEmpty()) {
                List<Node> children = outNode.getChilds();
                for (Node child : children) {
                    if (!child.isVisited()) {
                        child.setVisited(true);
                        candidateQueue.add(child);
                    }
                }
            }
        }

    }

    public double[][] getAdjacentMatrix() {
        return adjacentMatrix;
    }

    public void setAdjacentMatrix(double[][] adjacentMatrix) {
        this.adjacentMatrix = adjacentMatrix;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public Node[] getNodes() {
        return nodes;
    }

    public void setNodes(Node[] nodes) {
        this.nodes = nodes;
    }
}

class Node {
    private int value;

    private boolean visited = false;

    private List<Node> childs = new ArrayList<>();

    public Node(int value, List<Node> childs) {
        this.value = value;
        this.childs = childs;
    }

    public Node() {
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public boolean isVisited() {
        return visited;
    }

    public void setVisited(boolean visited) {
        this.visited = visited;
    }

    public List<Node> getChilds() {
        return childs;
    }

    public void setChilds(List<Node> childs) {
        this.childs = childs;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值