web-dev-qa-db-fra.com

Changez priorityQueue en max priorityqueue

J'ai la file d'attente prioritaire dans Java of Integers:

 PriorityQueue<Integer> pq= new PriorityQueue<Integer>();

Lorsque j'appelle pq.poll(), j'obtiens l'élément minimum.

Question: comment changer le code pour obtenir le maximum d'éléments?

79
Borut Flis

Que diriez-vous comme ça:

PriorityQueue<Integer> queue = new PriorityQueue<>(10, Collections.reverseOrder());
queue.offer(1);
queue.offer(2);
queue.offer(3);
//...

Integer val = null;
while( (val = queue.poll()) != null) {
    System.out.println(val);
}

La Collections.reverseOrder() fournit une Comparator qui trierait les éléments de la PriorityQueue dans un ordre opposé à leur ordre naturel dans ce cas.

161
Edwin Dalorzo

Vous pouvez utiliser l'expression lambda depuis Java 8.

Le code suivant affichera 10, le plus grand.

PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);
pq.add(10);
pq.add(5);
System.out.println(pq.peek());

La fonction lambda prend deux nombres entiers comme paramètres d'entrée, les soustrait l'un de l'autre et renvoie le résultat arithmétique. La fonction lambda implémente l'interface fonctionnelle, Comparator<T>. (Ceci est utilisé sur place, par opposition à une classe anonyme ou à une implémentation discrète.)

42
Guangtong Shen

Vous pouvez fournir un objet Comparator personnalisé qui classe les éléments dans l'ordre inverse:

PriorityQueue<Integer> pq = new PriorityQueue<Integer>(defaultSize, new Comparator<Integer>() {
    public int compare(Integer lhs, Integer rhs) {
        if (lhs < rhs) return +1;
        if (lhs.equals(rhs)) return 0;
        return -1;
    }
});

Désormais, la file d'attente prioritaire inversera toutes ses comparaisons, vous obtiendrez donc l'élément maximum plutôt que l'élément minimum.

J'espère que cela t'aides!

19
templatetypedef
PriorityQueue<Integer> pq = new PriorityQueue<Integer> (
  new Comparator<Integer> () {
    public int compare(Integer a, Integer b) {
       return b - a;
    }
  }
);
12
Varun Juneja

Les éléments de la file d'attente prioritaire sont classés en fonction de leur ordre naturel ou d'un comparateur fourni au moment de la construction de la file d'attente.

Le comparateur doit remplacer la méthode de comparaison.

int compare(T o1, T o2)

La méthode de comparaison par défaut renvoie un entier négatif, zéro ou un entier positif, car le premier argument est inférieur, égal ou supérieur au second.

La PriorityQueue par défaut fournie par Java est Min-Heap. Si vous voulez un tas maximum, suivez le code

public class Sample {
    public static void main(String[] args) {
        PriorityQueue<Integer> q = new PriorityQueue<Integer>(new Comparator<Integer>() {

            public int compare(Integer lhs, Integer rhs) {
                if(lhs<rhs) return +1;
                if(lhs>rhs) return -1;
                return 0;
            }
        });
        q.add(13);
        q.add(4);q.add(14);q.add(-4);q.add(1);
        while (!q.isEmpty()) {
            System.out.println(q.poll());
        }
    }

}

Référence: https://docs.Oracle.com/javase/7/docs/api/Java/util/PriorityQueue.html#comparator ()

7
rohan

Voici un exemple de Max-Heap en Java: 

PriorityQueue<Integer> pq1= new PriorityQueue<Integer>(10, new Comparator<Integer>() {
public int compare(Integer x, Integer y) {
if (x < y) return 1;
if (x > y) return -1;
return 0;
}
});
pq1.add(5);
pq1.add(10);
pq1.add(-1);
System.out.println("Peek: "+pq1.peek());

La sortie sera 10

4
Nobal

Vous pouvez utiliser MinMaxPriorityQueue (qui fait partie de la bibliothèque Guava): voici la documentation . Au lieu de poll(), vous devez appeler la méthode pollLast().

3
Chthonic Project

Vous pouvez essayer quelque chose comme:

PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> -1 * Integer.compare(x, y));

Ce qui fonctionne pour toute autre fonction de comparaison de base que vous pourriez avoir.

1
Horia Coman

Ceci peut être réalisé par le code ci-dessous dans Java 8 qui a introduit un constructeur qui ne prend qu'un comparateur.

PriorityQueue<Integer> maxPriorityQ = new PriorityQueue<Integer>(Collections.reverseOrder());
0
Anshu Shekhar

Je viens de lancer une simulation Monte-Carlo sur les deux comparateurs sur le tri double tas max et ils ont tous les deux abouti au même résultat: 

Ce sont les comparateurs max que j'ai utilisés:

(A) Comparateur intégré de collections

 PriorityQueue<Integer> heapLow = new PriorityQueue<Integer>(Collections.reverseOrder());

(B) comparateur personnalisé 

PriorityQueue<Integer> heapLow = new PriorityQueue<Integer>(new Comparator<Integer>() {
    int compare(Integer lhs, Integer rhs) {
        if (rhs > lhs) return +1;
        if (rhs < lhs) return -1;
        return 0;
    }
});
0
sivi

Définissez PriorityQueue sur MAX PriorityQueue Méthode 1: File d'attente pq = new PriorityQueue <> (Collections.reverseOrder ()); Méthode 2: File d'attente pq1 = new PriorityQueue <> ((a, b) -> b - a ); Regardons quelques exemples:

public class Example1 {
    public static void main(String[] args) {

        List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
        Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
        pq.addAll(ints);
        System.out.println("Priority Queue => " + pq);
        System.out.println("Max element in the list => " + pq.peek());
        System.out.println("......................");
        // another way
        Queue<Integer> pq1 = new PriorityQueue<>((a, b) -> b - a);
        pq1.addAll(ints);
        System.out.println("Priority Queue => " + pq1);
        System.out.println("Max element in the list => " + pq1.peek());
        /* OUTPUT
          Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
          Max element in the list => 888
          ......................
           Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
           Max element in the list => 888

         */


    }
}

Prenons une interview célèbre Problème: Le Kth plus grand élément d'un tableau utilisant PriorityQueue

public class KthLargestElement_1{
    public static void main(String[] args) {

        List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
        int k = 3;
        Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
        pq.addAll(ints);
        System.out.println("Priority Queue => " + pq);
        System.out.println("Max element in the list => " + pq.peek());
        while (--k > 0) {
            pq.poll();
        } // while
        System.out.println("Third largest => " + pq.peek());
/*
 Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
Third largest => 666

 */
    }
}

Autrement : 

public class KthLargestElement_2 {
    public static void main(String[] args) {
        List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
        int k = 3;

        Queue<Integer> pq1 = new PriorityQueue<>((a, b) -> b - a);
        pq1.addAll(ints);
        System.out.println("Priority Queue => " + pq1);
        System.out.println("Max element in the list => " + pq1.peek());
        while (--k > 0) {
            pq1.poll();
        } // while
        System.out.println("Third largest => " + pq1.peek());
        /*
          Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222] 
          Max element in the list => 888 
          Third largest => 666

         */
    }
}

Comme on peut le constater, les deux donnent le même résultat.

0
Soudipta Dutta
PriorityQueue<Integer> lowers = new PriorityQueue<>((o1, o2) -> -1 * o1.compareTo(o2));
0
Sumit Kumar Saha

Vous pouvez essayer de pousser des éléments avec le signe inverse. Exemple: ajouter a = 2 et b = 5, puis interroger b = 5.

PriorityQueue<Integer>  pq = new PriorityQueue<>();
pq.add(-a);
pq.add(-b);
System.out.print(-pq.poll());

Une fois que vous avez interrogé le début de la file d'attente, inversez le signe pour votre utilisation ..__ Ceci affichera 5 (élément plus grand) Peut être utilisé dans des implémentations naïves. Ce n'est certainement pas une solution fiable. Je ne le recommande pas.

0
striker28