【问题标题】:Prim's algorithm, using a priority queuePrim 算法,使用优先级队列
【发布时间】:2026-02-10 21:55:01
【问题描述】:

我正在尝试使用优先级队列来实现 prim 算法。当我调用 offer() 方法时,它给了我一个类转换异常,说顶点不能转换为可比较的。有解决方法吗?

public static Collection<Edge> prims(Graph g, int start) {
            ArrayList<Edge> mst = new ArrayList<Edge>();
            PriorityQueue<Vertex> vertices = new PriorityQueue<Vertex>();
            Vertex startVertex;

        for (Vertex vertex : g.getVertices()) {
            vertices.offer(vertex);
            if (vertex.getId() == start) {
                startVertex = vertex;
            }
        }

        if (!mst.isEmpty()) {
            return mst;
        }

        return null;
    }
}

【问题讨论】:

    标签: java algorithm minimum-spanning-tree prims-algorithm


    【解决方案1】:

    Prims algorithm 使用 的权重来确定最佳路径。将顶点发布到PriorityQueue 将不起作用。

    我猜你的Edge 类将通过比较它们的长度来实现Comparable

    【讨论】:

      【解决方案2】:

      解决方案是让您的Vertex 类实现Comparable,或者在构造优先级队列时提供Comparator。 Java 集合框架需要一种方法来比较您的顶点(毕竟您将它们放入优先级队列中,而优先级意味着存在某些排序的必要性)。

      【讨论】:

      • 看看OldCurmudgeon的答案。据它说,您在解决此问题的方法中似乎存在上层设计缺陷。
      【解决方案3】:

      是的:你需要你的Vertex 方法来实现Comparable&lt;Vertex&gt;

      Java 的PriorityQueue 是堆的实现,它具有日志时间插入和日志时间删除最小元素。但是为了让它有意义,你需要有一个 minimum 的概念;这意味着您需要将放入 PriorityQueue 的任何内容设为 Comparable,以便可以比较堆中的两个元素。

      Comparable元素可以插入PriorityQueue的原因是你也可以在构造函数中指定Comparator,而不是使用Comparable元素。因此,作为替代方案,您可以保留 Vertex 类,但使用适当的构造函数(这也需要您指定初始容量):

      PriorityQueue<Vertex> vertices = new PriorityQueue<Vertex>(11,
          new Comparator<Vertex>() {
              //implement .compare() and .equals()
          });
      

      【讨论】: