приоритетная очередь против связанного списка java

#java #algorithm #data-structures #graph #graph-algorithm

#java #алгоритм #структуры данных #График #график-алгоритм

Вопрос:

Я решал BFS проблему. Я использовал PriorityQueue, но получал неправильный ответ, затем я использовал LinkedList , я получил правильные ответы. Я не могу найти разницу между ними. Вот оба кода. Почему оба ответа разные?

 Code1:    
        LinkedList q=new LinkedList();
        q.add(src);
        dist[src]=0;
        visited[src]=1;
        while(!q.isEmpty()){
            u=(int)(Integer) q.remove(0);
            for (int k = 0; k < n; k  ) {
                if(a[u][k]==1 amp;amp; visited[k]==0)
                {
                    dist[k]=dist[u] 1;
                    q.add(k);
                    visited[k]=1;
                }   
            }
        }

Code 2: 
    PriorityQueue<Integer> q= new PriorityQueue<>();
        q.add(src);            
        dist[src]=0;
        visited[src]=1;
        while(!q.isEmpty()){
            u=q.remove();               
            for (int k = 0; k < n; k  ) {
                if(a[u][k]==1 amp;amp; visited[k]==0)
                {
                    dist[k]=dist[u] 1;
                    q.add(k);
                    visited[k]=1;
                }   
            }
        }
  

Также, когда я использовал список смежности вместо матрицы смежности, реализация очереди приоритетов давала правильные ответы.

Комментарии:

1. Что пытается сделать ваш код? и в какой строке он не выполняет то, что вы ожидаете, когда смотрите на него в своем отладчике? LinkedList с одним элементом выполняет то же самое, что и PriorityQueue с одним элементом.

2. Это простая bfs для определения расстояния до всех узлов. Я не знаю тестовых примеров. Я практиковался на онлайн-судьях.

3. Вы, вероятно, хотели очередь , а не PriorityQueue . Должно быть достаточно простым для изменения.

Ответ №1:

Как говорится в документации:

Неограниченная приоритетная очередь, основанная на куче приоритетов. Элементы приоритетной очереди упорядочиваются в соответствии с их естественным порядком или с помощью компаратора, предоставляемого во время построения очереди, в зависимости от того, какой конструктор используется.

LinkedList сохраняет порядок вставки, PriorityQueue — нет. Итак, порядок ваших итераций меняется, что делает вашу реализацию, использующую PriorityQueue, чем-то отличным от BFS.

Комментарии:

1. Итак, что я попытался, так это заставить мою сопоставимую реализацию возвращать 0 каждый раз, когда вызывался compareTo. Разве это не было бы похоже на поддержание порядка вставки?

Ответ №2:

PriortiyQueue, а также Linkedlist реализуют интерфейс очереди и выполняют операции таким же образом, как и очередь (FIFO). Разница между PriorityQueue и Linkedlist заключается в том, что во время вставки PriorityQueue будет отсортирован, а также упорядочен в соответствии с естественным порядком, но мы можем добавить Commparator также для того, чтобы определить конкретный порядок сортировки для записи, в то время как в качестве LinkedList будет просто упорядочен. Итак, пока вы пытаетесь добавить элементы в PriorityQueue, они будут отсортированы на основе их естественного порядка или в соответствии с функцией сравнения.

 import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;

public class QueueInJava {

public static void main(String[] args) {
    Queue<String> queue = new LinkedList<>(); 
    queue.add("Ishfaq");
    queue.add("Ramzan");
    queue.add("Nagoo");
    queue.add("Bangalore");
    
    System.out.println("Linked List Queue is:"   queue);
    System.out.println("Linked List Queue Peek is :"   queue.peek());
    
    queue.poll();
    System.out.println("Linked List Queue after remove is:"   queue);
    
    
    Queue<Integer> queuenew = new PriorityQueue<>();
    
    
    queuenew.add(2);
    queuenew.add(3);
    queuenew.add(1);
    queuenew.add(0);
    queuenew.add(4);
    
    System.out.println("Priority Queue is:"   queuenew);
    System.out.println("Priority Queue Peek is :"   queuenew.peek());
    
    int ieleFirst=queuenew.remove();
    System.out.println("Priority Queue Element Removed is:"   ieleFirst);
    int ieleSecond=queuenew.remove();
    System.out.println("Priority Queue Element Removed is:"   ieleSecond);
    System.out.println("Priority Queue after remove is:"   queuenew);
  }

}
  

Вывод:

 Linked List Queue is: [Ishfaq, Ramzan, Nagoo, Bangalore]

Linked List Queue Peek is: Ishfaq

Linked List Queue after remove() is: [Ramzan, Nagoo, Bangalore]

Priority Queue is: [0, 1, 2, 3, 4]

Priority Queue Peek is: 0

Priority Queue Element Removed is: 0

Priority Queue Element Removed is: 1

Priority Queue after remove() is: [2, 3, 4]
  

Ответ №3:

Ваша проблема в основном: почему вы думаете, что два произвольных класса, которые, ну, в конце концов, являются разными классами .., делают одно и то же?!

Другими словами: ваш урок сегодня должен быть таким: вы не должны обращаться к другим людям, чтобы объяснить свои эксперименты. Лучший подход таков: в тот момент времени, когда вы пишете свой код, вам лучше убедиться, что вы понимаете каждую деталь вашего кода.

Значение: когда вы начнете использовать новый класс из библиотек Java, перейдите и прочитайте его javadoc! И когда вы не делаете этого заранее, а сразу начинаете свои эксперименты; и вы сталкиваетесь с сюрпризами: тогда ищите вещи.

Конечно, удобно, когда вам это объясняют другие люди, но суть хорошего программиста заключается в внутренней мотивации самому выяснить, что делает (или будет делать) ваш код!

И, конечно, ответ на ваш вопрос таков: в ваших двух примерах используются списки разного типа, которые имеют разное поведение; как указано в их соответствующем Javadoc (это по сравнению с тем).

Комментарии:

1. Хорошие моменты, но должен был быть комментарий. Нет голосования «за» или «против».