图的宽度优先遍历与广度优先遍历
一、图的宽度优先遍历
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; } } } }
流程解读