/
UndirectedGraphByAdjacencyList.java
209 lines (189 loc) · 6.95 KB
/
UndirectedGraphByAdjacencyList.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package cn.codepub.algorithms.graph;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Scanner;
/**
* <p>
* Created with IntelliJ IDEA. 2015/12/2 20:33
* </p>
* <p>
* ClassName:UndirectedGraphByAdjacencyList
* </p>
* <p>
* Description:使用邻接表实现的无向图深度优先及广度优先
* </P>
*
* @author Wang Xu
* @version V1.0.0
* @since V1.0.0
*/
public class UndirectedGraphByAdjacencyList {
public static void main(String[] args) {
// test data following
// please input vertex number:
// 7
// please input edge number:
// 7
// input the vertex by space:
// a b c d e f g
// input the edge between vertex by pair:
// a c a d a f b c c d e g f g
// 打印顶点如下:
// a b c d e f g
// 打印边的邻接表如下:
// a--c--d--f b--c c--a--b--d d--a--c e--g f--a--g g--e--f
// Depth First Search:
// a c b d f g e
// Breadth First Search:
// a c d f b g e
// Process finished with exit code 0
UndirectedGraphByAdjacencyList undirectedGraphAdjacencyList = new UndirectedGraphByAdjacencyList();
undirectedGraphAdjacencyList.createGraph();
undirectedGraphAdjacencyList.depthFirstSearch();
undirectedGraphAdjacencyList.breadthFirstSearch();
}
private void breadthFirstSearch() {
boolean visited[] = new boolean[vertexes.length];
Queue<Integer> queue = new ArrayDeque();
System.out.println("\nBreadth First Search:");
for (int i = 0; i < vertexes.length; i++) {
if (!visited[i]) {
queue.add(i);
}
while (!queue.isEmpty()) {
Integer remove = queue.remove();
if (!visited[remove]) {
String data = vertexes[remove].data;
System.out.print(data + "\t");
visited[remove] = true;
}
Edge firstEdge = vertexes[remove].firstEdge;
while (firstEdge != null) {
if (!visited[firstEdge.vertex]) {
queue.add(firstEdge.vertex);
}
firstEdge = firstEdge.nextEdge;
}
}
}
}
public void depthFirstSearch() {
System.out.println("\nDepth First Search:");
boolean[] visited = new boolean[vertexes.length];
for (int i = 0; i < vertexes.length; i++) {
if (!visited[i]) {
depthFirstSearch(visited, i);
}
}
}
private void depthFirstSearch(boolean[] visited, int i) {
System.out.print(vertexes[i].data + "\t");
visited[i] = true;
Edge firstEdge = vertexes[i].firstEdge;
while (firstEdge != null) {
if (!visited[firstEdge.vertex]) {
depthFirstSearch(visited, firstEdge.vertex);
}
firstEdge = firstEdge.nextEdge;
}
}
//邻接表中边对应的链表的顶点
private class Edge {
int vertex;//该边所指向顶点的位置
Edge nextEdge;//指向下一条弧的指针
}
//邻接表中表的顶点
private class Vertex {
String data;//顶点信息
Edge firstEdge;//指向第一条依附该顶点的弧
}
private Vertex[] vertexes;//顶点数组
/**
* 根据用户输入构造图
*/
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
vertexes = new Vertex[vertexNum];
System.out.println("input the vertex by space:");
for (int i = 0; i < vertexNum; i++) {
vertexes[i] = new Vertex();
vertexes[i].data = scanner.next();
vertexes[i].firstEdge = null;
}
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!");
}
if (vertexes[start].firstEdge == null) {
Edge edge = new Edge();
edge.vertex = end;
edge.nextEdge = null;
vertexes[start].firstEdge = edge;
} else {
Edge firstEdge = vertexes[start].firstEdge;
while (firstEdge.nextEdge != null) {
firstEdge = firstEdge.nextEdge;
}
Edge edge = new Edge();
edge.vertex = end;
edge.nextEdge = null;
firstEdge.nextEdge = edge;
}
//无向图,需要进行双向链接
if (vertexes[end].firstEdge == null) {
Edge edge = new Edge();
edge.vertex = start;
edge.nextEdge = null;
vertexes[end].firstEdge = edge;
} else {
Edge firstEdge = vertexes[end].firstEdge;
while (firstEdge.nextEdge != null) {
firstEdge = firstEdge.nextEdge;
}
Edge edge = new Edge();
edge.vertex = start;
edge.nextEdge = null;
firstEdge.nextEdge = edge;
}
}
System.out.println("打印顶点如下:");
for (int i = 0; i < vertexes.length; i++) {
String data = vertexes[i].data;
System.out.print(data + "\t");
}
System.out.println("\n打印边的邻接表如下:");
for (int i = 0; i < vertexes.length; i++) {
Edge firstEdge = vertexes[i].firstEdge;
System.out.print(vertexes[i].data);
while (firstEdge != null) {
System.out.print("--" + vertexes[firstEdge.vertex].data);
firstEdge = firstEdge.nextEdge;
}
System.out.print("\t");
}
}
private int getPosition(String v1) {
for (int i = 0; i < vertexes.length; i++) {
if (vertexes[i].data.equals(v1)) {
return i;
}
}
return -1;
}
}