6

I was solving BFS problem. I used PriorityQueue but I was getting wrong answer, then I used LinkedList, I got right ans. I'm unable to find the difference between them. Here are both the codes. Why both the answers are different?

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 && 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 && visited[k]==0)
                {
                    dist[k]=dist[u]+1;
                    q.add(k);
                    visited[k]=1;
                }   
            }
        }

Also when I used Adjacency List instead of Adjacency matrix, Priority Queue implementation gave right ans.

vikkz
  • 85
  • 1
  • 1
  • 8
  • What is your code trying to do? and on which line does it not do what you expect when you look at it in your debugger? A LinkedList with one element does the same thing as a PriorityQueue with one element. – Peter Lawrey Oct 21 '16 at 11:19
  • Its' simple bfs to find distance to all nodes. I dont know the test cases. I was practicing on online judges. – vikkz Oct 21 '16 at 15:26
  • You probably wanted a [Queue](https://docs.oracle.com/javase/7/docs/api/java/util/Queue.html) rather than a `PriorityQueue`. Should be simple enough to change. – Jim Mischel Oct 21 '16 at 16:16

3 Answers3

15

As the documentation says:

An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.

LinkedList preserves the insertion order, PriorityQueue does not. So your iteration order changes, which makes your implementation that uses PriorityQueue something other than BFS.

uoyilmaz
  • 3,035
  • 14
  • 25
  • So what I tried was make my comparable implementation return 0 each time compareTo was called. Wouldn't this be similar to maintaining the insertion order ? – Shilpa Sep 11 '19 at 02:42
3

PriortiyQueue as well as Linkedlist implement the Queue Interface and perform operations same the way as a Queue (FIFO). The difference between PriorityQueue and Linkedlist is at the time of insertion PriorityQueue will be sorted as well as ordered as per the natural order but we can add a Commparator also in order to define the particular order of sorting for a record, while as LinkedList will be just ordered. So while you are trying to add elements in PriorityQueue, they will get sorted on the basis of their natural order or as per the comparator function.

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);
  }

}

Output:

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]
Yolomep
  • 173
  • 1
  • 5
  • 16
0

Your problem is basically: why do you think that two arbitrary classes that well, are, in the end, different classes .. do the same thing?!

In other words: your lesson today should be: you shouldn't reach out to other people to explain your experiments. The better approach is: at that point in time, when you write your code, you better make sure that you understand each and every detail of your code.

Meaning: when you start to use a new class from the Java libraries, go and read its javadoc! And when you don't do that up-front but you directly start your experiments; and you run into surprises: look up things then.

Of course it is convenient to have other people explain that to you, but the essence of being a good programmer is intrinsic motivation to find out yourself what your code is (or will be) doing!

And of course, the answer to your question is: your two examples make use of different kind of lists, that have different behavior; as specified in their corresponding Javadoc (this versus that).

GhostCat
  • 137,827
  • 25
  • 176
  • 248