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的结果和之前的程序相比将会有很大的不同。