Java图的基本实现

接口:

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;
    });
  }

}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值