接口:
public interface Graph<V,E> {
int edgesSize();
int verticesSize();
void addVertext(V v);
void addEdge(V from,V to);
void addEdge(V from,V to,E weight);
void removeVertext(V v);
void removeEdge(V form, V to);
void DFS(V begin,VertexVisitor<V> visitor);
void BFS(V begin,VertexVisitor<V> visitor);//广度优先
interface VertexVisitor<V>{
boolean visit(V v);
}
}
实现:
import java.util.*;
//有向图
@SuppressWarnings("all")
public class ListGraph<V, E> implements Graph<V, E> {
private Map<V, Vertex<V, E>> vertices = new HashMap<>();
private Set<Edge<V, E>> edges = new HashSet<>();
public ListGraph(Object[][] data) {
for (Object[] edge : data) {
if (edge.length == 1) {
this.addVertext((V) edge[0]);
} else if (edge.length == 2) {
this.addEdge((V) edge[0], (V) edge[1]);
} else if (edge.length == 3) {
this.addEdge((V) edge[0], (V) edge[1], (E) edge[2]);
}
}
}
public ListGraph() {
}
private static class Vertex<V, E> {
V value;
Set<Edge<V, E>> inEdges = new HashSet<>();
Set<Edge<V, E>> outEdges = new HashSet<>();
public Vertex(V value) {
this.value = value;
}
@Override
public boolean equals(Object obj) {
return Objects.equals(value, ((Vertex<V, E>) obj).value);
}
@Override
public int hashCode() {
return value.hashCode();
}
@Override
public String toString() {
String valueString = value == null ? "null" : value.toString();
return value == null ? "null" : value.toString();
}
}
private static class Edge<V, E> {
Vertex<V, E> from;
public Edge(Vertex<V, E> from, Vertex<V, E> to) {
this.from = from;
this.to = to;
}
Vertex<V, E> to;
E weight;
@Override
public boolean equals(Object obj) {
Edge<V, E> edge = (Edge<V, E>) obj;
return Objects.equals(from, edge.from) && Objects.equals(to, edge.to);
}
@Override
public int hashCode() {
int fromCode = from.hashCode();
int toCode = to.hashCode();
return fromCode * 31 + toCode;
}
@Override
public String toString() {
return "Edge [form =" + from + ", to=" + to + ", weight = " + weight + "]";
}
}
@Override
public int edgesSize() {
return edges.size();
}
@Override
public int verticesSize() {
return vertices.size();
}
@Override
public void addVertext(V v) {
vertices.put((V) v, new Vertex(v));
}
@Override
public void addEdge(V from, V to) {
addEdge(from, to, null);
}
@Override
public void addEdge(V from, V to, E weight) {
// 先判断from和to是否存在
Vertex<V, E> fromVertex = vertices.get(from);
if (fromVertex == null) {
fromVertex = new Vertex<V, E>(from);
vertices.put(from, fromVertex);
}
Vertex<V, E> toVertex = vertices.get(to);
if (toVertex == null) {
toVertex = new Vertex<V, E>(to);
vertices.put(to, toVertex);
}
Edge<V, E> edge = new Edge<>(fromVertex, toVertex);
edge.weight = weight;
if (fromVertex.outEdges.remove(edge)) {
toVertex.inEdges.remove(edge);
edges.remove(edge);
}
fromVertex.outEdges.add(edge);
toVertex.inEdges.add(edge);
edges.add(edge);
}
@Override
public void removeVertext(V v) {
Vertex<V, E> vertex = vertices.remove(v);
if (vertex == null)
return;
// 一边遍历一边删除东西太危险 舍弃
// vertex.inEdges.forEach((Edge<V,E> edge)->{
// removeEdge(edge.from.value, edge.to.value);
// });
// vertex.outEdges.forEach((Edge<V,E> edge)->{
// removeEdge(edge.from.value, edge.to.value);
// });
// 采用迭代器
Iterator<Edge<V, E>> iterator = vertex.outEdges.iterator();
while (iterator.hasNext()) {
Edge<V, E> edge = iterator.next();
edge.to.inEdges.remove(edge);
iterator.remove();
edges.remove(edge);
}
iterator = vertex.inEdges.iterator();
while (iterator.hasNext()) {
Edge<V, E> edge = iterator.next();
edge.from.outEdges.remove(edge);
iterator.remove();
edges.remove(edge);
}
}
@Override
public void removeEdge(V form, V to) {
Vertex<V, E> fromVertex = vertices.get(form);
Vertex<V, E> toVertex = vertices.get(to);
if (fromVertex == null || toVertex == null) {
return;
}
Edge<V, E> edge = new Edge<>(fromVertex, toVertex);
if (fromVertex.outEdges.remove(edge)) {
toVertex.inEdges.remove(edge);
edges.remove(edge);
}
}
// 递归实现深度优先
// @Override
// public void DFS(V begin) {
// Set<Vertex<V,E>> visitedVertices = new HashSet<>();
// Vertex<V,E> beginVertex = vertices.get(begin);
// if (beginVertex == null) return;
// DFS(beginVertex,visitedVertices);
// }
// private void DFS(Vertex<V, E> vertex, Set<Vertex<V, E>> visitedVertices) {
// System.out.print(vertex.value + " ");
// visitedVertices.add(vertex);
// for (Edge<V, E> edge : vertex.outEdges) {
// if (visitedVertices.contains(edge.to)) {
// continue;
// }
// DFS(edge.to, visitedVertices);
// }
// }
// 非递归实现深度优先
public void DFS(V begin, VertexVisitor<V> visitor) {
if (visitor == null)
return;
Set<Vertex<V, E>> visitedVertices = new HashSet<>();
Vertex<V, E> beginVertex = vertices.get(begin);
Stack<Vertex<V, E>> stack = new Stack<>();
if (beginVertex == null)
return;
// 先访问起点
stack.push(beginVertex);
visitor.visit(beginVertex.value);
visitedVertices.add(beginVertex);
while (!stack.isEmpty()) {
Vertex<V, E> vertex = stack.pop();
for (Edge<V, E> edge : vertex.outEdges) {
if (visitedVertices.contains(edge.to)) {
continue;
}
stack.push(edge.from);
stack.push(edge.to);
visitor.visit(edge.to.value);
visitedVertices.add(edge.to);
break;
}
}
}
@Override
public void BFS(V begin, VertexVisitor<V> visitor) {
if (visitor == null)
return;
Vertex<V, E> vertex = vertices.get(begin);
if (vertex == null)
return;
Queue<Vertex<V, E>> queue = new LinkedList();
Set<Vertex<V, E>> visitVertices = new HashSet<>();
queue.offer(vertex);
visitVertices.add(vertex);
while (!queue.isEmpty()) {
Vertex<V, E> vertexfoo = queue.poll();
if (visitor.visit(vertexfoo.value))
return;
for (Edge<V, E> edge : vertexfoo.outEdges) {
if (visitVertices.contains(edge.to)) {
continue;
}
queue.offer(edge.to);
visitVertices.add(edge.to);
}
}
}
public void print() {
System.out.println("------------打印顶点---------");
vertices.forEach((V key, Vertex<V, E> vertex) -> {
System.out.println(key);
System.out.println("------------out-----------");
System.out.println(vertex.outEdges);
System.out.println("------------in-----------");
System.out.println(vertex.inEdges);
System.out.println();
});
System.out.println("------------打印边---------");
edges.forEach((Edge<V, E> edge) -> {
System.out.println(edge);
});
}
public static void main(String[] args) {
ListGraph<String, Integer> graph = new ListGraph<>();
graph.addEdge("v0", "v4", 6);
graph.addEdge("v1", "v0", 9);
graph.addEdge("v1", "v2", 3);
graph.addEdge("v2", "v0", 2);
graph.addEdge("v2", "v3", 5);
graph.addEdge("v3", "v4", 1);
// graph.print();
graph.BFS("v1", (String s) -> {
System.out.print(s + " ");
return false;
});
System.out.println();
graph.DFS("v1", (String s) -> {
System.out.print(s + " ");
return false;
});
}
}