- 图的广度优先搜索(BFS)、深度优先搜索(DFS)
package ccnu.offer.graph;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
public class Demo01 {
public static void test1(int vertexNum, char[] vertex, int[][] matrix) {
Graph g = new Graph(vertexNum, vertex, matrix);
ArrayList<Integer> visitedSerials = traverseByBFS(g, 1);
System.out.println("邻接矩阵法");
System.out.print("BFS:");
for (Integer visited : visitedSerials) {
System.out.print(vertex[visited]);
}
System.out.println();
Arrays.fill(g.visited, false);
for (int distance : minDistance(g, 0)) {
System.out.print(distance);
}
System.out.println();
Arrays.fill(g.visited, false);
System.out.print("DFS:");
traverseByDFS(g, 0);
}
public static void test2(int vertexNum, char[] vertexs, int[][] matrix) {
Graph2 g = new Graph2(vertexNum);
Graph2[] g2 = g.create(vertexs, matrix);
ArrayList<Integer> visitedSerials = traverseByBFS(g2, 1);
System.out.println("邻接表法");
System.out.print("BFS:");
for (Integer visited : visitedSerials) {
System.out.print(g2[visited].vertex);
}
Arrays.fill(Graph2.visited, false);
System.out.print("\nDFS:");
traverseByDFS(g2, 0);
}
public static void main(String[] args) {
int vertexNum = 11;
char[] vertex = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K' };
int[][] matrix = new int[][] { { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, { 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
test1(vertexNum, vertex, matrix);
System.out.println();
test2(vertexNum, vertex, matrix);
}
public static ArrayList<Integer> traverseByBFS(Graph g, int i) {
ArrayList<Integer> visitedSerialOfAll = new ArrayList<Integer>();
if (!g.visited[i]) {
visitedSerialOfAll.addAll(BFS(g, i));
}
for (int ii = 0; ii < g.vertexNum; ii++) {
if (!g.visited[ii]) {
visitedSerialOfAll.addAll(BFS(g, ii));
}
}
return visitedSerialOfAll;
}
public static ArrayList<Integer> BFS(Graph g, int i) {
ArrayList<Integer> visitedSerialOfPart = new ArrayList<Integer>();
LinkedList<Integer> l = new LinkedList<Integer>();
visitedSerialOfPart.add(i);
g.visited[i] = true;
l.addLast(i);
while (!l.isEmpty()) {
int ii = l.removeFirst();
ArrayList<Integer> vertexs = g.getAllNeighbors(ii);
while (!vertexs.isEmpty()) {
int iii = vertexs.get(0);
vertexs.remove(0);
if (!g.visited[iii]) {
visitedSerialOfPart.add(iii);
g.visited[iii] = true;
l.addLast(iii);
}
}
}
return visitedSerialOfPart;
}
public static ArrayList<Integer> traverseByBFS(Graph2[] g, int i) {
ArrayList<Integer> visitedSerialOfAll = new ArrayList<Integer>();
if (!Graph2.visited[i]) {
visitedSerialOfAll.addAll(BFS(g, i));
}
for (int ii = 0; ii < Graph2.vertexNum; ii++) {
if (!Graph2.visited[ii]) {
visitedSerialOfAll.addAll(BFS(g, ii));
}
}
return visitedSerialOfAll;
}
public static ArrayList<Integer> BFS(Graph2[] g, int i) {
ArrayList<Integer> visitedSerialOfPart = new ArrayList<Integer>();
LinkedList<Integer> l = new LinkedList<Integer>();
visitedSerialOfPart.add(i);
Graph2.visited[i] = true;
l.addLast(i);
while (!l.isEmpty()) {
int ii = l.removeFirst();
Graph2 cur = g[ii];
while (cur.next != null) {
cur = cur.next;
int iii = Graph2.indexOf(g, cur.vertex);
if (!Graph2.visited[iii]) {
visitedSerialOfPart.add(iii);
Graph2.visited[iii] = true;
l.addLast(iii);
}
}
}
return visitedSerialOfPart;
}
public static void traverseByDFS(Graph g, int i) {
if (!g.visited[i]) {
DFS(g, i);
}
for (int ii = 0; ii < g.vertexNum; ii++) {
if (!g.visited[ii]) {
DFS(g, ii);
}
}
}
public static void DFS(Graph g, int i) {
System.out.print(g.vertex[i]);
g.visited[i] = true;
ArrayList<Integer> vertexs = g.getAllNeighbors(i);
while (!vertexs.isEmpty()) {
int iii = vertexs.get(0);
vertexs.remove(0);
if (!g.visited[iii]) {
DFS(g, iii);
}
}
}
public static void traverseByDFS(Graph2[] g, int i) {
if (!Graph2.visited[i]) {
DFS(g, i);
}
for (int ii = 0; ii < Graph2.vertexNum; ii++) {
if (!Graph2.visited[ii]) {
DFS(g, ii);
}
}
}
public static void DFS(Graph2[] g, int i) {
System.out.print(g[i].vertex);
Graph2.visited[i] = true;
Graph2 cur = g[i];
while (cur.next != null) {
cur = cur.next;
int ii = Graph2.indexOf(g, cur.vertex);
if (!Graph2.visited[ii]) {
DFS(g, ii);
}
}
}
public static int[] minDistance(Graph g, int i) {
int[] minDistanceSerial = new int[g.vertexNum];
LinkedList<Integer> l = new LinkedList<Integer>();
minDistanceSerial[i] = 0;
g.visited[i] = true;
l.addLast(i);
while (!l.isEmpty()) {
int ii = l.removeFirst();
ArrayList<Integer> vertexs = g.getAllNeighbors(ii);
while (!vertexs.isEmpty()) {
int iii = vertexs.get(0);
vertexs.remove(0);
if (!g.visited[iii]) {
minDistanceSerial[iii] = minDistanceSerial[ii] + 1;
g.visited[iii] = true;
l.addLast(iii);
}
}
}
return minDistanceSerial;
}
private static class Graph {
private int vertexNum;
private char[] vertex = null;
private int[][] matrix = null;
private boolean[] visited = null;
public Graph(int vertexNum, char[] vertex, int[][] matrix) {
this.vertexNum = vertexNum;
this.vertex = vertex;
this.matrix = matrix;
visited = new boolean[vertexNum];
}
public ArrayList<Integer> getAllNeighbors(int i) {
ArrayList<Integer> vertexs = new ArrayList<Integer>();
for (int ii = 0; ii < vertexNum; ii++) {
if (matrix[i][ii] == 1) {
vertexs.add(ii);
}
}
return vertexs;
}
}
private static class Graph2 {
char vertex;
private Graph2 next;
private static int vertexNum;
private static boolean visited[] = null;
public Graph2(char vertex) {
this.vertex = vertex;
}
public Graph2(int vertexNum) {
this.vertexNum = vertexNum;
this.visited = new boolean[this.vertexNum];
}
public Graph2[] create(char[] vertexs, int[][] matrix) {
Graph2[] g2 = new Graph2[vertexNum];
for (int i = 0; i < matrix.length; i++) {
g2[i] = new Graph2(vertexs[i]);
Graph2 cur = g2[i];
for (int ii = 0; ii < matrix[i].length; ii++) {
if (matrix[i][ii] != 0) {
Graph2 tmp = new Graph2(vertexs[ii]);
cur.next = tmp;
cur = tmp;
}
}
}
return g2;
}
public static int indexOf(Graph2[] g, char vertex) {
for (int i = 0; i < vertexNum; i++) {
if (g[i].vertex == vertex) {
return i;
}
}
return -1;
}
}
}