forked from shijiebei2009/Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDirectedGraphByAdjacencyMatrix.java
171 lines (156 loc) · 5.14 KB
/
DirectedGraphByAdjacencyMatrix.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package cn.codepub.algorithms.graph;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;
import java.util.Scanner;
/**
* <p>
* Created with IntelliJ IDEA. 2015/12/3 22:15
* </p>
* <p>
* ClassName:DirectedGraphByAdjacencyMatrix
* </p>
* <p>
* Description:使用邻接矩阵实现有向图的深度优先及广度优先
* </P>
*
* @author Wang Xu
* @version V1.0.0
* @since V1.0.0
*/
public class DirectedGraphByAdjacencyMatrix {
private String[] vertex;//顶点集合
private int[][] edges;//边的集合
public static void main(String[] args) {
DirectedGraphByAdjacencyMatrix directedGraphByAdjacencyMatrix = new DirectedGraphByAdjacencyMatrix();
directedGraphByAdjacencyMatrix.createGraph();
directedGraphByAdjacencyMatrix.depthFirstSearch();
directedGraphByAdjacencyMatrix.breadthFirstSearch();
}
public void breadthFirstSearch() {
//设置访问标记数组
System.out.println("\nBreadth First Search:");
boolean[] visited = new boolean[vertex.length];
Queue<Integer> queue = new ArrayDeque<>();
for (int i = 0; i < vertex.length; i++) {
if (!visited[i]) {
System.out.print(vertex[i] + "\t");
queue.add(i);
visited[i] = true;
}
while (!queue.isEmpty()) {
int remove = queue.remove();
int count = 0;
for (int j = getNextVertex(remove, count); j >= 0; j = getNextVertex(remove, count)) {
if (!visited[j]) {
visited[j] = true;
System.out.print(vertex[j] + "\t");
queue.add(j);
} else {
count++;
}
}
}
}
}
/**
* 寻找与当前点有边相连的下一个顶点
*
* @param row 查找该行
* @param col 从该列开始查找
* @return
*/
private int getNextVertex(int row, int col) {
for (int j = col; j < edges[row].length; j++) {
if (edges[row][j] == 1) {
return j;
}
}
return -1;
}
/**
* 根据用户输入构造图
*/
public void createGraph() {
Scanner scanner = new Scanner(System.in);
System.out.println("please input vertex number:");
int vertexNum = scanner.nextInt();
System.out.println("please input edge number:");
int edgeNum = scanner.nextInt();
//无向图有n个顶点,最多有n*(n-1)/2条边
// vertex: n = > edge: (n-1)*n/2
if (vertexNum < 1 || edgeNum < 1 || edgeNum > (vertexNum - 1) * vertexNum / 2) {
System.err.println("input error, invalid vertex or edges!");
return;
}
//init vertex and edges
vertex = new String[vertexNum];
edges = new int[vertexNum][vertexNum];
System.out.println("input the vertex by space:");
for (int i = 0; i < vertexNum; i++) {
vertex[i] = scanner.next();
}
System.out.println("input the edge between vertex by pair:");
for (int i = 0; i < edgeNum; i++) {
String v1 = scanner.next();
String v2 = scanner.next();
int start = getPosition(v1);
int end = getPosition(v2);
if (start == -1 || end == -1) {
System.err.println(v1 + " or " + v2 + " are invalid!");
}
//更新边的邻接矩阵
edges[start][end] = 1;
}
System.out.println("打印顶点如下:" + Arrays.toString(vertex));
System.out.println("打印边的邻接矩阵如下:");
for (int temp[] : edges) {
System.out.println(Arrays.toString(temp));
}
}
/**
* 对外暴露的调用接口
*/
public void depthFirstSearch() {
//设置访问标记数组
boolean[] visited = new boolean[vertex.length];
System.out.println("Depth First Search:");
for (int i = 0; i < vertex.length; i++) {
if (!visited[i]) {
depthFirstSearch(visited, i);
}
}
}
/**
* 内部递归的深度优先实现
*
* @param visited
* @param i
*/
private void depthFirstSearch(boolean[] visited, int i) {
visited[i] = true;
System.out.print(vertex[i] + "\t");
int count = 0;
for (int j = getNextVertex(i, count); j >= 0; j = getNextVertex(i, count)) {
if (!visited[j]) {
depthFirstSearch(visited, j);
} else {
count++;
}
}
}
/**
* 返回顶点在集合中的位置
*
* @param s
* @return
*/
public int getPosition(String s) {
for (int i = 0; i < vertex.length; i++) {
if (vertex[i].equalsIgnoreCase(s)) {
return i;
}
}
return -1;
}
}