-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathGraph.java
136 lines (112 loc) · 3.59 KB
/
Graph.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
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.TreeSet;
/**
* 红黑树的实现方式(图的最终实现方式)
* 在以下 V表示顶点数 E表示图的边数
* 空间复杂度 O(V + E) 这里V和E都是必要的,极端情况下可能E=0
* 建图时间 O(ElogV)
* 两点是否相邻 O(logV)
* 查找所有邻边 O(degree(V)) 默认为顶点的度, 如果是完全图或者稠密图接近O(V)
*/
class Graph implements Cloneable {
private int V; // 图的顶点数
private int E; // 图的边数
private TreeSet<Integer>[] adj; // 图方隈
public Graph(String filename) {
File file = new File(filename);
try(Scanner scanner = new Scanner(file)){
V = scanner.nextInt();
if (V < 0)
throw new IllegalArgumentException("V must be non-negative");
adj = new TreeSet[V];
for (int i = 0; i < V; i++) {
adj[i] = new TreeSet<Integer>();
}
E = scanner.nextInt();
if (E < 0)
throw new IllegalArgumentException("E must be non-negative");
for (int i=0; i < E; i++) {
int a = scanner.nextInt();
validateVertex(a);
int b = scanner.nextInt();
validateVertex(b);
if (a == b)
throw new IllegalArgumentException("Self Loop is Detected.");
if (adj[a].contains(b))
throw new IllegalArgumentException("Parallel Edges are Detected.");
adj[a].add(b);
adj[b].add(a);
}
} catch(IOException e) {
e.printStackTrace();
}
}
public int V() {
return V;
}
public int E() {
return E;
}
// 两个顶点是否有边
public boolean hasEdge(int v, int w) {
validateVertex(v);
validateVertex(w);
return adj[v].contains(w);
}
// 获取一个顶点的邻边
public Iterable<Integer> adj(int v) {
validateVertex(v);
return adj[v];
}
// 获取一个项点的度(有多少条邻边)
public int degree(int v) {
validateVertex(v);
return adj[v].size();
}
public void validateVertex(int v) {
if (v < 0 || v >= V)
throw new IllegalArgumentException("vertex "+v+" is invalid.");
}
public void removeEdge(int v, int w) {
validateVertex(v);
validateVertex(w);
if (adj[v].contains(w)) E--;
adj[v].remove(w);
}
@Override
public Object clone(){
try{
Graph cloned = (Graph) super.clone();
cloned.adj = new TreeSet[V];
for(int v = 0; v < V; v ++){
cloned.adj[v] = new TreeSet<Integer>();
for(int w: adj[v])
cloned.adj[v].add(w);
}
return cloned;
}
catch (CloneNotSupportedException e){
e.printStackTrace();
}
return null;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("V = %d, E = %d\n", V, E));
for (int v=0; v < V; v++) {
sb.append(String.format("%d: ", v));
for (int w: adj[v]) {
sb.append(String.format("%d ", w));
}
sb.append("\n");
}
return sb.toString();
}
public static void main(String[] args) {
Graph adj = new Graph("./Graph/g.txt");
System.out.println(adj);
}
}