将边存储在数据结构中

时间:2011-04-16 01:14:39

标签: java data-structures

我有一个名为Edge的类,它有属性source id,target id和weight。我想将这个边缘存储在一个集合数据结构中,因此在集合中不会有重复的边缘(即:具有相同源和目标id的边缘)。

问题在于: 我想为此数据结构添加Edge。如果数据结构中已经存在边缘,我不需要再次添加它,我只需要添加现有边的权重和我想要添加的边。

我很确定我必须覆盖集合的add函数。有人可以给我一个指针吗?为此在java中使用的最佳数据结构是什么?

3 个答案:

答案 0 :(得分:3)

一些建议。

您想要的基础数据结构可能是一个地图(HashMap可能是最好的具体实现),而不是一个集合。键应该是(源,目标)对,值可以是您的Edge对象。如果你非常关心重复,有办法解决这个问题,其中一种方法是实际只存储权重作为值。

其次,这是为了一个Graph类。如果您设计好接口,它会隐藏内部实现细节。我建议高度使用组合而不是继承。换句话说,你的图表有一张地图,而不是一张地图。

另请查看现有代码,例如JGraphT,它已经有一个加权有向图,与上面描述的相同。有时最好不要从头开始重新制作东西。

祝你好运。

答案 1 :(得分:1)

另一种方法是在您自己的类中包装边集,它提供了您希望支持的接口。

这是在组合和继承之间进行选择的特定情况。一般来说,组合比继承更受欢迎,尽管它也有它的位置。

例如,这是一个可能类的粗略草图(编辑:使用地图)

   public class Edge { ... }

   public class EdgeData { 
       public Edge getEdge() { ... }
       public float getWeight() { ... }
   }

   public class Edges {
       private Map<Edge,EdgeData> m_edges = new HashMap<Edge,EdgeData>();
       public addEdge( EdgeData edge ) { 
            // Do what you've said above.

       }
       public Map<Edge,EdgeData> getEdges() { return Collections.unmodifiableMap( m_edges ); }
   }

答案 2 :(得分:1)

好吧,Set.add()方法返回一个布尔值,指示新项是否已成功添加到集合中。如果它返回false是因为该项已经存在。基于此,您可以轻松编写算法。丑陋的部分是必须迭代集合来更新值,对吗?

if(!edges.add(newEdge)){
   Iterator<Edge> iter = edges.iterator();
   while(iter.hasNext()){
    Edge edge = iter.next();
    if(edge.equals(newEdge)){
        edge.updateWeight(newEdge.getWeight()); //this.weight+=moreWeight
    }
   }
}

基于此,我假设您想要的只是一种美化所有迭代样板代码的方法。

我喜欢的解决方案是使用LambdaJ Collections来更新现有Edge的权重。

if (!edges.add(newEdge)) {
   with(edges).first(is(newEdge)).updateWeight(newEdge.getWeight());
}

我不知道你在寻找什么,但这种方法只有三行代码。从我的观点来看,这很简单。

我写了一个小例子来说明这个想法:

Jedi obiwan = new Jedi("Obiwan", 30, 40); // name, age and power
Jedi luke = new Jedi("Luke", 18, 25);
Jedi mace = new Jedi("Mace-Windu", 100, 450);
Jedi yoda = new Jedi("Yoda", 150, 1000);

Jedi obiAgain = new Jedi("Obiwan", 11, 40);

Set<Jedi> jedis = new HashSet<Jedi>(asList(obiwan, luke, mace, yoda));

if (!jedis.add(obiAgain)) {
     with(jedis).first(is(obiAgain)).updatePower(obiAgain.getPower());
}

System.out.println(jedis);