所以我需要一些帮助未来的一种方式来找到一个最低的生成树。假设我有我的曲线图形式的一个邻接表:

A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35

第一封信告诉这点你是在寻找和数量告诉了多少个连接到任何其他节点。例如,一个具有两个连接-每一B和一.在那之后,该数字如下信件简单地告诉重的边缘。B具有重12和我已经重的25个。所以我原本计划表示这整个事情作为一个串阵列 叫 Graph[8].每个行会是一个不同的老虎的阵列。我有困难搞清楚如何完成这一任Prims或Kruskalls算法。

有帮助吗?

解决方案

假设我有我的树形式的一个邻接表

重要的是(对你的理解)注意到你有一个连接 曲线图 在这样的一个邻接的清单,但我认为这只是一个错字。我将提出这一点作为一个编辑,但我只是希望你能意识到这一点。事实上,它是一个曲线图并不是一棵树可以看出,从这些行:

A 2 B 12 I 25
B 3 C 10 H 40 I 8

在这里,你有一个圆圈已经在A-B-I:

     A
  12/_\25
   B 8 I

具有一个圆的定义意味着它不能被一棵树!还有一件事可以看到的方式,我提出了这个子图:边缘有权重,不结。


现在让我们看看你的提供,例如:

A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35

首先我们可以看到,这个邻接表要么是不正确的或已经优化了你的需求。这可以(例如)进行

E 2 F 60 G 38
F 0

第一线在这里表示的边缘从E,F,但第二线说F了一定程度的0,但程度的定义是通过这边射的。

这是我的邻接关系的列表将是什么样子,如果它是'完全':

A 2 B 12 I 25
B 4 A 12 C 10 H 40 I 8
C 3 B 10 D 18 G 55
D 2 C 18 E 44
E 3 D 44 F 60 G 38
F 1 E 60
G 3 C 55 E 38 H 35
H 3 B 40 G 35 I 35

我们可以看到很多冗余的,因为每一个边缘发生的两倍,这就是为什么你的'优化'邻接表更适合你的需要-它会这'完全'的例子一个会做很多无用的检查。然而,你应该 依靠这如果你可以确保所有数据给你代码已经是'优化'(或者更确切地说,在这种格式)!我将以此为鉴于从现在开始。


让我们来谈谈你的数据结构。你当然可以使用您提出列的串,但是老实说,我宁愿让你喜欢的东西@AmirAfghani提出的数据结构。使用他的方法会使你的工作更容易(因为它-因为他已经指出的那样-将接近你的 精神表示)和更加有效(我猜,不要依赖这个猜测;)),为,你会做 很多 操作上串其他方式。在标题你问之后Prim的算法,但是在实际问题,你说 要么 Prim或验。我会去验,只是因为他算法是更容易的方式和你似乎接受两个。


验的算法

验的算法是相当简单的,它基本上是:

  • 开始与每一个节点,但是没有边

重复下尽可能经常:

  • 从所有的未用/未选边缘选择一个最少的重量(如果有多于一:只要拿起他们中的一个)
  • 如果这种优势会造成一个圆圈,如果是这样,标记为选择和'放弃它。
  • 如果它不会造成一个圆圈,使用它并将它标记使用/选择。

这就是全部。它真的很简单。但是我想提一件事情在这一点上,我认为它最适合在这里:有没有"最低生成树"在一般情况,但是"最低生成树",因为可以有很多,因此结果可能会有所不同!


回到你的数据结构!你现在可以看到为什么这将是一个坏主意使用一系列的串如数据结构。你会重复许多操作上的串(例如检查重量的每一个边缘)并 串不可改变的, 这意味着你不能简单地'扔掉'之一的边缘,或者标记的一个边缘无论在什么方式。使用一种不同的方法,你可能仅仅设置的重量为1,或甚至删除该项的边缘!


深先搜索

从我所看到的我认为你的主要问题是决定是否会导致边缘圆,或者,对不对?决定这个,你可能会不得不呼叫一个深度的第一个搜索算法,并使用其返回的价值。基本的想法是这样的:开始从其中一个节点(我会叫这个节点将根),并试图找到一种方法,节点在另一端,所选择的边缘(我会叫这个节目节点)。(当然,图中的哪个没有这种边缘尚未)

  • 选择一个未访问的边缘射到你的根
  • 标志这种选择的边缘,因为访问(或类似的东西,不管你喜欢)
  • 重复最后两个步骤的节点上的另一边参观了边缘
  • 每当没有未访问的边缘,去回一个边缘
  • 如果你回来时你根本没有未访问边缘的事件给它的剩余的,你做。return false.
  • 如果你在任何时点参观你的目标节点,你都做了。返回正确的。

现在,如果这种方法返回 true 这边就会造成一圈。

其他提示

这不是直接回答你的问题(似乎你正在做学业),但我认为它会帮助你开始。为什么不创建一个更紧密地匹配你的心理模型并从那里建立的数据结构?

class GraphNode { 

    final String name;
    final List<GraphEdge> adjacentNodes;

    public GraphNode(String name) { 
        this.name = name;
        adjacentNodes = new ArrayList<GraphEdge>();
    }

    public void addAdjacency(GraphNode node, int weight) { 
        adjacentNodes.add(new GraphEdge(node, weight));
    }

}

class GraphEdge {

    final GraphNode node;
    final int weight;

    public GraphEdge(GraphEdge node, int weight) {
        this.node = node;
        this.weight = weight;
    }

}
.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top