BFS(Breadth First Search),中文名为宽度优先搜索,是横向遍历图的一种算法;这种算法必须借助队列才能够实现。
需求:输入edgeCount,startNode,edgeCount代表图有多少条边,startNode代表遍历的起点,接下来输入edgeCount组数据,每组有两个数node1与node2,代表一条边;最后输出BFS算法得到的序列,数和数之间使用空格隔开。
一、实现代码
import java.util.Scanner; import java.util.Queue; import java.util.LinkedList; class Node { int value; Node next = null; } public class BFS { private static boolean[] visited = new boolean[1024]; private static Node[] nodes = new Node[1024]; public static void main(String args[]) { init(); Scanner scanner = new Scanner(System.in); int edgeCount = scanner.nextInt(); int startNode = scanner.nextInt(); for (int i = 0; i < edgeCount; i++) { int nodeValue1 = scanner.nextInt(); int nodeValue2 = scanner.nextInt(); Node node1 = new Node(); node1.value = nodeValue2; node1.next = nodes[nodeValue1].next; nodes[nodeValue1].next = node1; Node node2 = new Node(); node2.value = nodeValue1; node2.next = nodes[nodeValue2].next; nodes[nodeValue2].next = node2; } visited[startNode] = true; bfs(visited, nodes, startNode, edgeCount); } private static void init() { for (int i = 0; i < visited.length; i++) { visited[i] = false; } for (int i = 0; i < nodes.length; i++) { nodes[i] = new Node(); } } public static void bfs(boolean[] visited, Node[] nodes, int startNode, int edgeCount) { Queue<Integer> queue = new LinkedList<Integer>(); queue.offer(startNode); System.out.print(startNode + " "); while (!queue.isEmpty()) { int top = queue.poll(); Node node = nodes[top].next; while (node != null) { if (visited[node.value] == false) { System.out.print(node.value + " "); visited[node.value] = true; queue.offer(node.value); } node = node.next; } } } } /* * 7 0 0 3 0 4 1 4 1 5 2 3 2 4 3 5 */
二、测试数据
输入:
7 0 0 3 0 4 1 4 1 5 2 3 2 4 3 5
输出:
0 4 3 2 1 5
7 0 0 3 0 4 1 4 1 5 2 3 2 4 3 5
输出:
0 4 3 2 1 5
三、ACM
题目链接:数据结构实验之图论二:基于邻接表的广度优先搜索遍历
AC代码(Java版):
import java.util.Scanner; import java.util.Queue; import java.util.LinkedList; class Node { int value; Node next = null; } public class Main { private static boolean[] visited = new boolean[1024]; private static Node[] nodes = new Node[1024]; public static void main(String args[]) { Scanner scanner = new Scanner(System.in); int sum = scanner.nextInt(); while ((sum--) != 0) { init(); int k = scanner.nextInt(); int edgeCount = scanner.nextInt(); int startNode = scanner.nextInt(); for (int i = 0; i < edgeCount; i++) { int nodeValue1 = scanner.nextInt(); int nodeValue2 = scanner.nextInt(); Node node1 = new Node(); node1.value = nodeValue2; node1.next = nodes[nodeValue1].next; nodes[nodeValue1].next = node1; Node node2 = new Node(); node2.value = nodeValue1; node2.next = nodes[nodeValue2].next; nodes[nodeValue2].next = node2; } visited[startNode] = true; bfs(visited, nodes, startNode, edgeCount); } } private static void init() { for (int i = 0; i < visited.length; i++) { visited[i] = false; } for (int i = 0; i < nodes.length; i++) { nodes[i] = new Node(); } } public static void bfs(boolean[] visited, Node[] nodes, int startNode, int edgeCount) { Queue<Integer> queue = new LinkedList<Integer>(); queue.offer(startNode); System.out.print(startNode + " "); while (!queue.isEmpty()) { int top = queue.poll(); Node node = nodes[top].next; sort(node); while (node != null) { if (visited[node.value] == false) { System.out.print(node.value + " "); visited[node.value] = true; queue.offer(node.value); } node = node.next; } } System.out.println(); } /** * 对邻接表进行排序 * * @param node */ private static void sort(Node node) { boolean flag = false; Node p; Node q; while (flag = !flag) { p = node; q = p.next; while (q != null) { if (p.value > q.value) { int temp = p.value; p.value = q.value; q.value = temp; flag = false; } else { p = p.next; q = p.next; } } } } }
需要注意的是在该题目中需要输入定点的个数,虽然没有什么用,但是作为题目的要求,还是需要写上的;另外,邻接表需要"排序",上面的sort方法是添加的方法,是一种变型的“冒泡排序”算法,实际上如果进行了排序,BFS的结果和之前的程序相比将会有很大的不同。