Java - Graph的最佳实现结构是什么?

时间:2009-12-22 09:09:44

标签: java graph

图表非常大但没有定向。边缘未加权。

在我的实现中,我必须找到具有最大度数的顶点并在顶点和边缘上进行删除。

链接列表?数组列表?地图吗?

哪一个更适合我的实施?

8 个答案:

答案 0 :(得分:16)

表示图形的两个基本数据结构是

  • adjacency list

  • the adjacency matrix

请参阅http://en.wikipedia.org/wiki/Adjacency_listhttp://en.wikipedia.org/wiki/Adjacency_matrix 文章还讨论了这两种结构的利弊。

答案 1 :(得分:7)

我的建议是将顶点存储在优先级队列中。这样,您可以非常快速地访问具有最高程度的顶点。至于如何实现顶点,我会将每个相邻顶点存储在某种集合数据结构中,例如HashSet或TreeSet,以便能够有效地删除内容。我不会明确地表示边缘,不需要它。

代码,类似于:

class Graph {

  PriorityQueue<Vertex> vertexes;

  public Graph() {
    vertexes = new PriorityQueue<Vertex>(10,new Vertex());
  }

  public Vertex maxDegreeVertex() {
    return vertexes.peek();
  }

  ...

}

class Vertex implements Comparator<Vertex> {
  HashSet<Vertex> edges;

  public Vertex() {
    edges = new HashSet<Vertex>();
  }

  public compare(Vertex v1, Vertex v2) {
    v2.edges.size().compareTo(v1.edges.size());
  }

  ...

}

希望这有帮助。

答案 2 :(得分:3)

从上面提出的答案将是

使用LinkedList进行地图...

您的数据结构可能是这样的(根据您的要求而变化)......

Map<?, List<?>>
<Node-name, List-of-nodes-connected-to-it>

基本上,图表最好在HASHING的帮助下实现,上述数据结构对此有很大的帮助..

答案 3 :(得分:1)

如果你的算法需要查看最大度数,那么你想要一个按度数排序的数据结构,像PriorityQueue这样的东西会很好。

然后您需要存储图表本身。为了快速删除,我建议使用稀疏数组结构。如果必须使用java.util数据结构,则从顶点到连接顶点列表的HashMap提供O(1)删除。

如果你可以使用第三方图书馆,那么JGraph和JUNG似乎最受欢迎a list of answers here

答案 4 :(得分:1)

图表实现取决于您将如何处理它。但对于大多数情况,基于邻接列表的实现有帮助。

在Java中,您可以使用Map&lt;&gt;来完成。以下是我博客上基于Graph.Java的通用邻接列表。

答案 5 :(得分:0)

您还可以查看专门设计的库,例如JUNG

答案 6 :(得分:0)

取决于您有什么其他要求。一种天真,简单的方法可能是

class Node
{
  List<Node> edges;
  int id;
}

您将拥有图表中所有节点的列表。问题是这可能会变得不一致;例如节点A可能位于节点B的边缘列表中,但节点B可能不在节点A的列表中。为了解决这个问题,您可以将其建模为:

class Edge
{
  Node incidentA;
  Node incidentB;
}

class Node
{
  int id;
}

同样,您将拥有系统中所有边和节点的列表和列表。当然,分析这种数据结构的方式与其他方法完全不同。

答案 7 :(得分:0)

    public class Graph {
    private Set<Vertex>vertices;
    private Set<Edge>edges;
    private Map<Vertex,List<Edge>>adj;
    // Getter setter



    public Graph(Set<Vertex> vertices, Set<Edge> edges, Map<Vertex, List<Edge>> adj) {
        super();
        this.vertices = vertices;
        this.edges = edges;
        this.adj = adj;
    }
}

// Vertex class
public class Vertex {
    private String name;

    public Vertex(String name) {
        super();
        this.name = name;
    }


}

// Edge class 

public class Edge {
    private Vertex from;
    private Vertex to;
    private int weight;

    public Edge(Vertex from, Vertex to,int weight) {
        super();
        this.from = from;
        this.to = to;
        this.weight = weight;
    }


}

// Driver class 

import java.util.HashSet;
import java.util.Set;

public class Test {
    public static void  main(String[]args) {
        Graph gr = new Graph();
        Vertex a = new Vertex("a");
        Vertex b = new Vertex("b");
        Vertex c = new Vertex("c");
        Vertex d = new Vertex("d");
        Vertex e = new Vertex("e");
        Vertex f = new Vertex("f");
        Vertex g = new Vertex("g");


        Set<Vertex>vertices = gr.getVertices();
        if(vertices == null){
            vertices  = new HashSet<>();
            vertices.add(a);
            vertices.add(b);
            vertices.add(c);
            vertices.add(d);
            vertices.add(e);
            vertices.add(f);
            vertices.add(g);
        }

        Edge ae = new Edge(a, e, 3);        
        Edge ac = new Edge(a, c, 1);
        Edge cf = new Edge(c, f, 9);
        Edge cd = new Edge(c, d, 4);
        Edge eb = new Edge(e, b, 2);
        Edge bd = new Edge(b, d, 5);
        Edge df = new Edge(d, f, 7);

    Set<Edge>edges = gr.getEdges();
    if(edges == null){
        edges = new HashSet<Edge>();
        edges.add(ae);
        edges.add(ac);
        edges.add(cf);
        edges.add(cd);
        edges.add(eb);
        edges.add(bd);
        edges.add(bd);
    }
        gr.setVertices(vertices);
        gr.setEdges(edges);

    }

}