当前位置: 首页 > 知识库问答 >
问题:

使用自定义比较器在O(n)中创建PriorityQueue

林波鸿
2023-03-14

我试图用Priorityqueue和自定义比较器实现MST,但是我在O(n)时间内用它构建最小堆时遇到了问题。问题是Priorityqueue只有一个构造函数允许在O(n)中创建Priorityqueue,但它不使用任何比较器作为参数。我想让它使用我的自定义比较器。有解决这个问题的方法吗?AddAll()将失去对MST使用最小堆的目的,因为它是O(nlogn)方法。这是我的代码

ArrayList <edge>ar=new ArrayList<>(); 
   for(int i=0;i<e;i++)
   {
       int u=ss.nextInt();
       int v=ss.nextInt();
       int w=ss.nextInt();
       ar.add(new edge(u,v,w));
   }
   PriorityQueue <edge>pr=new PriorityQueue<edge>(ar);

我想使用的比较器:-

PriorityQueue <edge>ar=new PriorityQueue(11,new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
            edge n1=(edge) o1;
            edge n2=(edge) o2;
            if(n1.w<n2.w)
            {
                return -1;
            }
            else if(n1.w==n2.w)
            {
                if((n1.u+n1.v+n1.w)<=(n2.u+n2.v+n2.w))
                {
                    return -1;
                }   
                else
                {
                    return 1;
                }
            }
            else
            {
                return 1;
            }
        }
    });

共有1个答案

杨凌
2023-03-14

如果您没有在其他地方对列表进行min-heap-ordered,那么您将无法new PriorityQueue(...)任何内容,也无法避免创建堆的困难。这里的数学表示,对于平均情况,它是O(n),但它仍然不仅仅是迭代。

PriorityQueue<edge> pr = new PriorityQueue<edge>(ar, comp) {
    PriorityQueue(List<edge> ar, Comparator<edge> c) {
        this(c);
        for(int i = 0; i < queue.length; i++) {
            queue[i] = ar.get(i);
        }
        this.size = queue.length;
        heapify(); // O(n), except that heapify is private and thus you can't call it!!!
    }
}

现在我还没有对此进行测试,它只是从PriorityQueue源中得到一些指导,但它应该会为您指明正确的方向。

但有时您必须支付风笛手和创建堆顺序,这不仅仅是迭代。但是,由于heapify,它应该仍然在O(n)上。

class EdgeContainer implements Comparable<EdgeContainer> {

    private static final Comparator<edge> comp = ; // that comparator above
    private final edge edge;
    EdgeContainer(Edge edge) { this.edge = edge; }
    public int compareTo(EdgeContainer e) { return comp.compare(edge, e.edge); }
    public edge getEdge() { return edge; }
}

List <EdgeContainer>ar=new ArrayList<>(); 
for(int i=0;i<e;i++)
{
   int u=ss.nextInt();
   int v=ss.nextInt();
   int w=ss.nextInt();
   ar.add(new EdgeContainer(new edge(u,v,w)));
}

PriorityQueue<EdgeContainer> qr = new PriorityQueue(ar);
 类似资料:
  • 问题内容: 我想用自定义排序顺序在Java中创建一个。字符串排序的键需要根据第二个字符进行排序。这些值也是字符串。 样本图: 问题答案: 您可以像这样使用自定义比较器: 样品: 请注意,这只是假设字符在索引1处有一个字符。 另外,您也可以使用以下比较: 通常,此减法“技巧”是无效的,但在这里可以正常使用,因为减法2 不会溢出。 不过,上面的and 解决方案更具可读性。

  • 在我的PriorityQueue中,我有两种类型的客户,即VIP和常规客户。我想先为贵宾服务,再为常客服务。 如果CustomerID<100,则视为VIP。 如果客户是VIP,他会排在队列中VIP部分的最后 更新:我不想排序任何其他列除了VIP。我不想添加“日期”,因为它感觉像是一个黑客,而不是理解Java是如何工作的。

  • 问题内容: 为什么无论什么变量成立,它总是返回?即使使用clank搜索变量,它也会返回相同的结果。我错过了什么吗? 我的数组包含逗号分隔的值,我想在数组元素中的逗号之前基于字符串进行搜索。还有其他简单的解决方案吗?我还制作了一个自定义方法,该方法可以遍历数组并找到字符串,但是我正在寻找其他选择。 问题答案: JavaDoc on 声明必须已对数组进行排序,因此比较器实际上将数组值与搜索字符串进行比

  • 下面的代码片段适用于条件1,但不适用于条件2。

  • 问题内容: 我想为汽车清单开发一个排序演示。我正在使用数据表显示汽车列表。现在实际上我想按汽车颜色对列表进行排序。这里不是按字母顺序排序的。我想使用我的自定义排序顺序,例如先是红色汽车,然后是蓝色,等等。 为此,我尝试使用,但它只允许按字母顺序排序。 因此,任何人都可以指导我实现使用该技术的方法,以便使排序变得更快。 问题答案: 我建议你为汽车颜色创建一个枚举,而不要使用字符串,并且枚举的自然顺序

  • 如果我有以下列表: 并应用以下(Java8): 然后我会得到一个带有“Hello”和“World”的列表。