用C ++或Java实现图形

时间:2012-01-19 08:10:16

标签: java c++ graph

在C ++或Java中实现图形的最佳方法是什么?在C ++中,我正在考虑使用二维数组来完成它。在java中,我正在考虑一个arrayList。

6 个答案:

答案 0 :(得分:6)

首先,在我看来,语言选择并不是世界上最大的问题。除非您需要使用特定语言或可移植性,否则使用C ++或Java就足够了。话虽如此,你的问题似乎有些功课。您是否正在使用Prim's algorithm进行MST实施?

正如其他答案已经说过,有几种表示图形的方法。我最熟悉的用于表示图形的两个是:

  1. 一个Adjacency Matrix,它是一个2D数组,其中每个“行”和“列”是一个节点,矩阵该位置的值表示边缘(或边缘权重)和空 - 值(或0值,或其他一些标记/有意义值)表示无边
  2. 一个Adjacency List,它是一个2D数组(有点),其中 i -th列表是连接到(相邻)node I 的。有时,如果您的图表是定向/加权的,您也可以选择使列表成为节点名称和边缘权重对的列表。
  3. 在维基百科上的邻接列表文章(上面链接)中,有一节关于两个表示之间的权衡。

    关于MST算法的主题:

    你可能会使用邻接列表获得更好的性能,但这只是理论上的(我认为?)。在实施方面,有一些事项,如参考的地方考虑。但是,为了便于编码,我个人更喜欢使用邻接矩阵(我个人觉得它们更容易使用,特别是在加权图上),除非需要非常好的性能。

    邻接矩阵(C ++):

    vector<vector<int> > adj_Mat(n, vector<int>(n, 0));
    

    其中 n 是图中的节点数。然后adj_Mat[i][j]是节点 i j 之间边缘的权重。

    邻接列表(C ++):

    vector<vector<pair<int, int> > > adj_list(n);
    

    然后,如果 i -th节点的边缘权重 k 到节点 j ,我会做这样的事情(假设图是指示的)

    adj_list[i].push_back(pair<int, int>(j, k));
    

    现在,我的C ++真的很酷,因为我倾向于在编码竞赛中使用它来破解随机代码,所以这不是很好的代码,但它是编写这些数据表示的基本方法。

    对于大规模的咆哮感到抱歉,我希望它有所帮助。

答案 1 :(得分:2)

有两种常规方式来表示图表。

  1. 邻接矩阵:意思是如果你有n个节点然后你得到一个n乘n的矩阵,矩阵[i,j]表示节点之间是否有边(如果你想要的话,通常用布尔或int)权重)

  2. 邻接列表:为每个节点设置一个集合,指示它有边缘的节点。

  3. 对于第一种方法,2d数组是最好的,对于第二种方法,我会使用HashSet(或者如果你想要权重则使用HashMap)

    当选择一个而不是另一个时,您需要考虑图形大小,边缘数量与节点数量以及要在其上运行的算法。

答案 2 :(得分:1)

查看Boost Graph Library。有一个学习阶段,但一旦你得到它,你将永远不会回头。

答案 3 :(得分:0)

C ++比Java快。如果您想创建一个好的图形,您应该使用您需要的字段(例如图形节点的权重)创建自己的类型。您还应该创建一个Node类,它包含它的属性以及它所连接的其他节点的列表。 在Graph中你应该有它的节点,它的属性和函数的列表(例如bool isFlat()) 我认为这是实现图形比2D数组或ArrayList更好的方法。

答案 4 :(得分:0)

实现图形G=(V,E)的最有效方法取决于这些图的属性以及您倾向于对它们执行的操作类型。一般来说,对于稀疏图形,即|E| << |V|^2的图形,通常选择邻接列表(较慢但存储效率较高)。对于|E| =~ |V|^2的图形,邻接矩阵通常更好(更快,但内存密集)。

根据您打算如何处理图表,其他方法可能会更高效。

答案 5 :(得分:0)

如果你需要快速算法在C ++中使用基于数组的方法。 但是如果你编写算法,其他人应该在Java中使用基于OOP的方法。