图的宽度优先遍历与广度优先遍历

一、图的宽度优先遍历

1,利用队列实现
2,从源节点开始依次按照宽度进队列,然后弹出
3,每弹出一个点,把该节点所有没有进过队列的邻接点放入队列
4,直到队列变空

代码实现:

//从node出发,进行宽度优先遍历
    public static void bfs(Node node) {
        if (node == null) {
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        HashSet<Node> set = new HashSet<>(); //set,去重机制,例如防止图中有环
        queue.add(node);
        set.add(node);
        while (!queue.isEmpty()) {
            Node cur = queue.poll();
            System.out.println(cur.value);//弹出后进行打印(可以把打印换成处理)
            for (Node next : cur.nexts) {
                if (!set.contains(next)) { //这一句确保不添加重复节点入队列
                    set.add(next);
                    queue.add(next);
                }
            }
        }
    }

二、图的广度优先遍历

1,利用实现
2,从源节点开始把节点按照深度放入栈(同时放入set集合),然后弹出
3,每弹出一个点A,把该节点A下一个没有进过栈(通过set.contains进行判断)的邻节点B(加入有B)压入栈,压栈之前先把该节点A重新入栈,再压节点B,然后把节点B注册到set集合中,
最后打印B
4,循环步骤3,直到栈空

代码

//从某一个节点出发,进行深度优先遍历
    public static void dfs(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        HashSet<Node> set = new HashSet<>();
        stack.add(node);
        set.add(node);
        System.out.println(node.value);
        while (!stack.isEmpty()) {
            Node cur = stack.pop();
            for (Node next : cur.nexts) {
                if (!set.contains(next)) { //如果set中无此节点B
                    stack.push(cur);  //再次把cur压入栈中
                    stack.push(next); //把节点B压入栈中
                    set.add(next); //set中注册节点B
                    System.out.println(next.value); //打印这个节点B
                    break;
                }
            }
        }
    }

流程解读

 

posted @ 2021-08-13 16:09  zh_小猿  阅读(490)  评论(0编辑  收藏  举报