How would i compare two objects in custom tree set implementation? - java

I need to compare two objects in insert method off the tree set. But i am unable to fathom out where and how to implement Comparable or Comparator. My code looks as follows:
This is my Node creation for the binary tree.
Node.java
public class Node {
private Object data;
private Node left, right;
//initial case when a Node of a binary tree gets created. both left and right subtrees point to null
public Node (){
left = right = null;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
This is my MyBinaryTree class where i need to implement insert method:
MyBinaryTree.java
public class MyBinaryTree implements Comparable<Node> {
Node root;
public MyBinaryTree(){
root = null;
}
void insert(Object x){
Node newrec = new Node(); //Node constructor gets called and sets up a root node with empty
//subtrees
newrec.setData(x);
if(root == null){
root = newrec;
}
else{
Node a,b;
a = b = root;
while(a!=null){
b=a;
if( ( newrec.getData() ).compareTo( a.getData() ) ) {
i am stuck here! how would i compare these objects using Comparable?
}
}
}
}
void inorder(Node root){
}
#Override
public int compareTo(Node o) {
// TODO Auto-generated method stub
int i = (o.)
return 0;
}
}

You need to be able to compare, not just nodes, but the data contained in those nodes. That means that your Node either needs to be limited to taking objects that are Comparable, or your tree needs to take a Comparator that it can use to compare them.
If you really want to support both, then when the time comes to do the comparison, if a Comparator has been provided, use its compare method, otherwise cast the data to Comparable<? super E> where E is the type of Node data (see below), and then use its compareTo method.
That brings me to the next point. Your Node class should probably not simply contain Object as its data, but instead be declared as Node<E> implements Comparable<Node<E>>, and then your tree can be declared as MyBinaryTree<E>. I would also change the constructor for Node to take the data as a parameter, rather than calling the setter immediately after creating one. There is no reason you would ever want to create a Node with no data.
I would strongly suggest looking through the source code for some of the generic collections in the java.util package, which comes with the JDK. In particular, I referred to the source of TreeMap.java to see how they handled both Comparable and non-Comparable elements, since the class isn't declared in such a way as to require the elements to be Comparable. (If they aren't, and there is no Comparator, a ClassCastException would occur where they try to cast the object to Comparable<? super K>.) Seeing how they have implemented similar code will be a great help to you. You may also want to review Java generics.

Please refer below code
package com.example.treeset;
import java.util.Comparator;
import java.util.TreeSet;
public class MyCompUser {
public static void main(String a[]){
//By using name comparator (String comparison)
TreeSet<Empl> nameComp = new TreeSet<Empl>(new MyNameComp());
nameComp.add(new Empl("Ram",3000));
nameComp.add(new Empl("John",6000));
nameComp.add(new Empl("Crish",2000));
nameComp.add(new Empl("Tom",2400));
for(Empl e:nameComp){
System.out.println(e);
}
System.out.println("===========================");
//By using salary comparator (int comparison)
TreeSet<Empl> salComp = new TreeSet<Empl>(new MySalaryComp());
salComp.add(new Empl("Ram",3000));
salComp.add(new Empl("John",6000));
salComp.add(new Empl("Crish",2000));
salComp.add(new Empl("Tom",2400));
for(Empl e:salComp){
System.out.println(e);
}
}
}
class MyNameComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
return e1.getName().compareTo(e2.getName());
}
}
class MySalaryComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
if(e1.getSalary() > e2.getSalary()){
return 1;
} else {
return -1;
}
}
}
class Empl{
private String name;
private int salary;
public Empl(String n, int s){
this.name = n;
this.salary = s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public String toString(){
return "Name: "+this.name+"-- Salary: "+this.salary;
}
}

Related

Java Iterable<Node> inheritance

Before all, here is a Minimal Working Example of my code on GitHub:
https://github.com/rmwesley/DancingLinks_MWE
I've been trying to implement the Dancing Links' algorithm by D. Knuth to solve the Exact Cover problem.
The code works. Problem is, I want to implement an Iterator.
In fact, the Iterator works for Node.java.
But not for Column.java, as I will further detail.
I've tried completely refactoring the code and doing some crazy modifications, but to no avail.
I left some of my best trials as commented lines of code.
These were the least garbagey ones.
My current design is as follows:
Given a problem matrix, I aimed at constructing the main data structure with 4-way nodes.
So first I implemented Node.java, a 4-way circularly linked data structure.
Then I extend Node.java in Column.java, which is the "backbone" of the structure.
Column elements then make up the main row.
Rows of Nodes are then linked with the rest of the structure with .addRow().
That is, new rows come below the last added row and above the column. Remember, circular.
See the schematics in D. Knuth's paper: https://arxiv.org/abs/cs/0011047.
With this, the full structure can be initialized from a given problem matrix.
"this" in Column serves as the head itself, so no elements are added above or below it.
Here is my source code:
Node.java
public class Node implements Iterable<Node> {
private Node upNode;
private Node downNode;
private Node leftNode;
private Node rightNode;
private Column column;
public Node() {
upNode = this;
downNode = this;
leftNode = this;
rightNode = this;
column = null;
}
#Override
public String toString() {
String str = this.column.getSize() + " ";
for (Node node : this){
str += node.column.getSize() + " ";
}
return str;
}
#Override
public java.util.Iterator<Node> iterator(){
Node currNode = this;
return new NodeIter(this);
}
public Column getColumn(){
return this.column;
}
public void setColumn(Column column){
this.column = column;
}
public Node getR(){
return this.rightNode;
}
public Node getD(){
return this.downNode;
}
public Node getL(){
return this.leftNode;
}
public Node getU(){
return this.upNode;
}
void removeHoriz() {
this.rightNode.leftNode = this.leftNode;
this.leftNode.rightNode = this.rightNode;
}
void removeVert() {
this.downNode.upNode = this.upNode;
this.upNode.downNode = this.downNode;
}
void restoreVert() {
this.downNode.upNode = this;
this.upNode.downNode = this;
}
void restoreHoriz() {
this.rightNode.leftNode = this;
this.leftNode.rightNode = this;
}
//Create an horizontal link between nodes
public void linkD(Node other) {
this.downNode = other;
other.upNode = this;
}
//Create a vertical link between nodes
public void linkR(Node other) {
this.rightNode = other;
other.leftNode = this;
}
void addHoriz(Node other) {
other.rightNode = this.rightNode;
other.leftNode = this;
}
void addVert(Node other) {
other.downNode = this.downNode;
other.upNode = this;
}
}
Column.java
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
//public class Column extends Node implements Iterable<Column>{
public class Column extends Node {
private int size;
private String name;
public Column() {
super();
this.setColumn(this);
size = 0;
name = new String();
}
public Column(int length) {
this();
Column currColumn = this;
for(int i = 0; i < length; i++){
currColumn.setName("" + i);
Column nextColumn = new Column();
currColumn.linkR(nextColumn);
currColumn = nextColumn;
}
currColumn.linkR(this);
}
public void addRow(int[] vector) throws Exception {
Column currColumn = this;
Node firstNode = new Node();
Node currNode = firstNode;
Node prevNode = currNode;
for(int index=0; index < vector.length; index++){
currColumn = currColumn.getR();
if(vector[index] == 0) continue;
currColumn.increment();
currColumn.getU().linkD(currNode);
currNode.linkD(currColumn);
currNode.setColumn(currColumn);
prevNode = currNode;
currNode = new Node();
prevNode.linkR(currNode);
}
currColumn = currColumn.getR();
prevNode.linkR(firstNode);
if(currColumn != this){
throw new Exception("Differ in length");
}
}
public Column(int[][] matrix) throws Exception {
this(matrix[0].length);
for(int i = 0; i < matrix.length; i++){
this.addRow(matrix[i]);
}
}
#Override
public Column getR(){
return (Column) super.getR();
}
#Override
public Column getL(){
return (Column) super.getL();
}
#Override
public String toString(){
String str = "";
//for (Column currColumn : this) str += currColumn.getSize() + " ";
for (Column currColumn = this.getR();
currColumn != this;
currColumn = currColumn.getR()){
str += currColumn.getSize() + " ";
}
return str;
}
public String getName(){
return this.name;
}
public int getSize(){
return this.size;
}
public void setSize(int size){
this.size = size;
}
public void setName(String name){
this.name = name;
}
public void increment(){
this.size++;
}
public void decrement(){
this.size--;
}
/*
#Override
public Iterator<Column> iterator(){
return new Iterator<Column>(){
private Column currNode = Column.this;
#Override
public boolean hasNext(){
return currNode.getR() != Column.this;
}
#Override
public Column next(){
if (!hasNext()) throw new NoSuchElementException();
currNode = currNode.getR();
return currNode;
}
};
}
*/
}
NodeIter.java
public class NodeIter implements java.util.Iterator<Node>{
private Node head;
private Node current;
public NodeIter(Node node){
this.head = this.current = node;
}
#Override
public boolean hasNext(){
return current.getR() != head;
}
#Override
public Node next(){
if (!hasNext()) throw new java.util.NoSuchElementException();
current = current.getR();
return current;
}
}
Commented lines give these errors when uncommented:
src/Column.java:5: error: Iterable cannot be inherited with different arguments: <Column> and <Node>
public class Column extends Node implements Iterable<Column>{
^
src/Column.java:111: error: iterator() in Column cannot implement iterator() in Iterable
public Iterator<Column> iterator(){
^
return type Iterator<Column> is not compatible with Iterator<Node>
where T is a type-variable:
T extends Object declared in interface Iterable
src/Column.java:76: error: incompatible types: Node cannot be converted to Column
for (Column currColumn : this) str += currColumn.getSize() + " ";
How do I make Column.java iterable?
I've been coding in Java recently, but without carefully considering design patterns.
So I fully believe I am suffering the consequences of bad code design.
Should I make some abstract class or make use of some Generic Type?
Like Node and Column, just so I can implement Iterable.
Am I wrong?
Does anyone have any pointers?
Tried using generics and overriding .iterator() method with different return types in Column.java.
Even tried using completely different class structures.
The Node class has an implementation of the Iterable interface in the form of one method:
#Override
public java.util.Iterator<Node> iterator(){
Node currNode = this;
return new NodeIter(this);
}
(BTW the first line of this method is not doing anything useful)
You are trying to make Node's subclass Column implement Iterable, meaning you want to add an overriding method like this:
#Override
public Iterator<Column> iterator()
Such an override which only differs in return type is not allowed in Java, hence the compilation error.
The fundamental problem is that, since Node is an Iterable, all its subclasses will also be an Iterable due to inheritance.
I guess you would like to write code like this:
for(Node n : node) {
for(Column c : n.getColumn()) {
c.increment();
}
}
Currently I think you could do this:
for(Node n : node) {
for(Node c : n.getColumn()) {
((Column) c).increment();
}
}
Where you are casting the iterand to Column in order to access Column methods.
I do think the design is weird when I read this for instance:
public Column() {
super();
this.setColumn(this);
eh? So a Column is a Node which has a column field? Seems like the design is conflicted about whether a Column is-a Node, or a Node has-a Column... I feel like your iterable problem will magically disappear once you figure that out.
EDIT: I don't fully grasp the algorithm and data structure yet (although I read a bit about it). From what I've understood I think you should create something like the following structure:
class Matrix {
Column[] columns;
Matrix(int[][] input) {
// init Columns
}
}
class Column {
String name;
int size;
Node firstNode;
}
class Node {
Node up;
Node down;
Node left;
Node right;
}
And avoid sub classing, it's usually not needed. Better to work with interfaces and collaborators.

I want to make a treemap structure. And I want to find a previouse tree

class Fran
{
String name;
int size;
Fran(String name,int size)
{ this.name=name; this.size=size; }
String getName()
{ return this.name; }
int getSize()
{ return this.size; }
}
class Node
{
Fran fran;
Node preNode;
Node[] children=new Node[10];
int childCount=0;
Node child;
/* is there child? */
int isChild=0;
Node(Fran fran)
{
this.fran=fran;
}
Node(Node preNode,Fran fran)
{
this.fran=fran;
this.preNode=preNode;
}
void setChild(Node preNode,Node child)
{
this.preNode=preNode;
this.child=child;
this.children[childCount]=child;
this.isChild=1;
this.childCount++;
}
int getChildCount()
{ return childCount; }
Node preNode()
{ return this.preNode; }
String[] getName()
{
String[] t=new String[childCount];
if(childCount==0) {
t[0]=this.fran.getName();
return t;
}
else
{
for(int i=0;i<=childCount-1;i++)
{
t[i]=children[i].fran.getName();
}
return t;
}
}
int[] getSize()
{
int[] t=new int[childCount];
if(childCount==0) {
t[0]=this.fran.getSize();
return t;
}
else
{
for(int i=0;i<=childCount-1;i++)
{
t[i]=children[i].fran.getSize();
}
return t;
}
}
String getN()
{
return this.fran.getName();
}
}
void setup()
{
Fran aa=new Fran("apt",36);
Fran bb=new Fran("bpt",26);
Fran cc=new Fran("cpt",16);
/* Fran dd=new Fran("dpt",56); */
Node a=new Node(aa);
Node b=new Node(bb);
Node c=new Node(cc);
a.setChild(a,b);
a.setChild(a,c);
print(a.getN());
Node f=b.preNode();
print(f.getN());
}
I want to make a tree structure. And I want to return a previouse node.
Node a->b, a->c . And I want to make b.preNode() -> Node a.
But I have NullpointerException, how can I solve this problem?
Thank you
First, you have to clearly decide what you want to do. You have not made that clear at all. Is a the root, and b and c are its children? Or is a the root, b is its child, and c is the child of b?
You need an add method that will add a child to a node:
Node a = new Node (...);
Node b = new Node(...);
a.add(b); // this should hook them together
The add method should set the parent of b to a, and set the child of a to b.
In addition, note that you have some stylistic mistakes. You should remove all your code setting variables and put it all together in the constructor. It is very hard at the moment to see what happens when you create a node because you have the code spread over your whole class.
You should also consider removing the Fran class and put the data in Node. Why have two classes? It adds overhead, complexity, and does not seem to achieve anything. That's just style, but it would clean up your code a lot.

Object oriented design, designing a tree

I'm creating a (atypical)tree in Java that will be composed of three classes: node, branch and leaf
Each node stores the branches it is connected to in a HashSet. The branch is supposed to lead to a descendent node or a leaf, but I'm not sure how to code that. Would I just have two separate variables, one Node and one Leaf in the branch class, along with two sets of getters and setters, even though I will never use both? Is there a best practice in this regard?
I was thinking maybe make node and leaf subclasses of the same superclass, but they have absolutely nothing in common in terms of code(i.e. different variable types, functions, etc.).
EDIT:
Node references branches and
each Branch references a Node or a Leaf
I'd probably go with something like this:
interface BranchDestination {
boolean isLeaf();
}
class Node implements BranchDestination {
private Set branches;
public boolean isLeaf() {
return false;
}
...
}
class Leaf implements BranchDestination {
public boolean isLeaf() {
return true;
}
...
}
class Branch {
BranchDestination destination;
...
}
I do like the idea of defining an interface for the leaf / node classes, and implement that interface in each. I would define a simple function in that interface (syntax might be wrong below, but it's pseduo-ish code):
interface BranchItem {
public object[] GetVals();
}
public class Branch
{
public BranchItem item;
}
public class Leaf implements BranchItem
{
private object myVal = <your data here>;
public object[] GetVals() {
return new object[] { myVal };
}
}
public class Node implements BranchItem
{
private myBranches[] = <List of Branches>;
public object[] GetVals() {
object[] myArray = new object[];
foreach (BranchItem b in myBranches)
{
myArray.addTo(b.item.GetVals());
}
return myArray;
}
}
When traversing your node, simply iterate over the Branches and call GetVals().
The Leaf class will simply returns it's stored value.
The Node Class will recursively loop over it's branches, calling GetVals() on each and add it to it's own returned array.
This is but a simple implementation. If you want sort order, handle collisions or duplicate data, or anything of that nature it could get more complicated.
Make the Leaf class with the basic information.
Make the Branch class which holds references to Leafs.
Make the Node class which holds references to Brahces.
Then try look up Recursion and how to use it to make such constructs :)
Here is my go at it. Though not very elegant, it gets the job done.
Here is the Leaf class:
public class Leaf {
private String text;
public Leaf(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setString(String newString) {
text = newString;
}
#Override
public String toString() {
return text;
}
}
And here is the Branch class:
public class Branch<T> {
private String text;
private HashSet<T> list;
public Branch(String text) {
this.text = text;
list = new HashSet<>();
}
public String getText() {
return text;
}
public void setText(String newText) {
text = newText;
}
public HashSet<T> getHashSet() {
return list;
}
public void setHashSet(HashSet<T> newList) {
list = newList;
}
public String getAllLeaves() {
StringBuilder sb = new StringBuilder();
sb.append(text).append("\n");
for(T t : list) {
sb.append("\t\t");
sb.append(t.toString()).append("\n");
}
return sb.toString();
}
#Override
public String toString() {
return text;
}
}
Lastly the Node class:
public class Node<T> {
private String text;
private HashSet<T> list;
public Node(String text) {
this.text = text;
list = new HashSet<>();
}
public String getText() {
return text;
}
public void setText(String newText) {
text = newText;
}
public HashSet<T> getHashSet() {
return list;
}
public void setHashSet(HashSet<T> newList) {
list = newList;
}
}
Little test program to try it out:
public class TreeConstruct {
public static void main(String[] args) {
Leaf l1 = new Leaf("Leaf 1");
Leaf l2 = new Leaf("Leaf 2");
Leaf l3 = new Leaf("Leaf 3");
Leaf l4 = new Leaf("Leaf 4");
Branch<Leaf> b1 = new Branch("Branch 1");
Branch<Leaf> b2 = new Branch("Branch 2");
Node<Branch> n1 = new Node("Node 1");
b1.getHashSet().add(l1);
b1.getHashSet().add(l2);
b1.getHashSet().add(l3);
b2.getHashSet().add(l4);
n1.getHashSet().add(b1);
n1.getHashSet().add(b2);
System.out.println(printNodeTree(n1));
}
public static String printNodeTree(Node<Branch> n) {
StringBuilder sb = new StringBuilder();
sb.append(n.getText()).append("\n");
for(Branch b : n.getHashSet()) {
sb.append("\t");
sb.append(b.getAllLeaves());
}
return sb.toString();
}
}
The output will be:
Node 1
Branch 1
Leaf 1
Leaf 3
Leaf 2
Branch 2
Leaf 4
Hope this helps!

Doubly linked lists

I have an assignment that I am terribly lost on involving doubly linked lists (note, we are supposed to create it from scratch, not using built-in API's). The program is supposed to keep track of credit cards basically. My professor wants us to use doubly-linked lists to accomplish this. The problem is, the book does not go into detail on the subject (doesn't even show pseudo code involving doubly linked lists), it merely describes what a doubly linked list is and then talks with pictures and no code in a small paragraph. But anyway, I'm done complaining. I understand perfectly well how to create a node class and how it works. The problem is how do I use the nodes to create the list? Here is what I have so far.
public class CardInfo
{
private String name;
private String cardVendor;
private String dateOpened;
private double lastBalance;
private int accountStatus;
private final int MAX_NAME_LENGTH = 25;
private final int MAX_VENDOR_LENGTH = 15;
CardInfo()
{
}
CardInfo(String n, String v, String d, double b, int s)
{
setName(n);
setCardVendor(v);
setDateOpened(d);
setLastBalance(b);
setAccountStatus(s);
}
public String getName()
{
return name;
}
public String getCardVendor()
{
return cardVendor;
}
public String getDateOpened()
{
return dateOpened;
}
public double getLastBalance()
{
return lastBalance;
}
public int getAccountStatus()
{
return accountStatus;
}
public void setName(String n)
{
if (n.length() > MAX_NAME_LENGTH)
throw new IllegalArgumentException("Too Many Characters");
else
name = n;
}
public void setCardVendor(String v)
{
if (v.length() > MAX_VENDOR_LENGTH)
throw new IllegalArgumentException("Too Many Characters");
else
cardVendor = v;
}
public void setDateOpened(String d)
{
dateOpened = d;
}
public void setLastBalance(double b)
{
lastBalance = b;
}
public void setAccountStatus(int s)
{
accountStatus = s;
}
public String toString()
{
return String.format("%-25s %-15s $%-s %-s %-s",
name, cardVendor, lastBalance, dateOpened, accountStatus);
}
}
public class CardInfoNode
{
CardInfo thisCard;
CardInfoNode next;
CardInfoNode prev;
CardInfoNode()
{
}
public void setCardInfo(CardInfo info)
{
thisCard.setName(info.getName());
thisCard.setCardVendor(info.getCardVendor());
thisCard.setLastBalance(info.getLastBalance());
thisCard.setDateOpened(info.getDateOpened());
thisCard.setAccountStatus(info.getAccountStatus());
}
public CardInfo getInfo()
{
return thisCard;
}
public void setNext(CardInfoNode node)
{
next = node;
}
public void setPrev(CardInfoNode node)
{
prev = node;
}
public CardInfoNode getNext()
{
return next;
}
public CardInfoNode getPrev()
{
return prev;
}
}
public class CardList
{
CardInfoNode head;
CardInfoNode current;
CardInfoNode tail;
CardList()
{
head = current = tail = null;
}
public void insertCardInfo(CardInfo info)
{
if(head == null)
{
head = new CardInfoNode();
head.setCardInfo(info);
head.setNext(tail);
tail.setPrev(node) // here lies the problem. tail must be set to something
// to make it doubly-linked. but tail is null since it's
// and end point of the list.
}
}
}
Here is the assignment itself if it helps to clarify what is required and more importantly, the parts I'm not understanding. Thanks
https://docs.google.com/open?id=0B3vVwsO0eQRaQlRSZG95eXlPcVE
if(head == null)
{
head = new CardInfoNode();
head.setCardInfo(info);
head.setNext(tail);
tail.setPrev(node) // here lies the problem. tail must be set to something
// to make it doubly-linked. but tail is null since it's
// and end point of the list.
}
the above code is for when u not have any nodes in list, here u r going to add nodes to ur list.I.e. ist node to list
here u r pointing head & tail to same node
I assume CardList is meant to encapsulate the actual doubly-linked-list implementation.
Consider the base case of a DLL with only a single node: the node's prev and next references will be null (or itself). The list's encapsulation's head and tail references will both be the single node (as the node is both the start and end of the list). What's so difficult to understand about that?
NB: Assuming that CardList is an encapsulation of the DLL structure (rather than an operation) there's no reason for it to have a CardInfoNode current field, as that kind of state information is only useful to algorithms that work on the structure, which would be maintaining that themselves (it also makes your class thread-unsafe).

Implementing Java Priority Queue

public class PriorityQueue<T> {
private PriorityNode<T> head, tail;
private int numItems;
public PriorityQueue(){
numItems = 0;
head=null;
tail=null;
}
public void add(int priority, T value){
PriorityNode<T> newNode = new PriorityNode<T>(priority,value);
if(numItems == 0){
head = newNode;
tail = newNode;
}
else{
head.setNext(newNode);
head = newNode;
}
}
}
Where PriorityNode is defined as:
public class PriorityNode<T> implements Comparable<T> {
private T value;
private PriorityNode<T> next;
private int priority;
public PriorityNode(int priority,T newValue){
value = newValue;
next = null;
priority = 0;
}
public PriorityNode(T newValue){
value = newValue;
next = null;
priority = 0;
}
public void setPriority(int priority){
this.priority = priority;
}
public int getPriority(){
return this.priority;
}
public T getValue(){
return value;
}
public PriorityNode<T> getNext(){
return next;
}
public void setNext(PriorityNode<T> nextNode){
this.next = nextNode;
}
public void setValue(T newValue){
value = newValue;
}
#Override
public int compareTo(int pri) {
// TODO Auto-generated method stub
if(this.priority<pri){
return -1;
}
else if(this.priority == pri){
return 0;
}
else{
return 1;
}
}
}
I'm having a lot of difficulty using the Comparator here and implementing a priority queue - please point me in the right direction.
Don't use a tree structure to implement a priority queue. Use a heap. It is more space-efficient, requires fewer memory allocations, and is O(log(N)) for most operations.
Regarding the implementing of the comparator, implementing the Comparator<T> or Comparable<T> interface requires the public int compareTo(T o) method to be overridden.
In the example code given, the compareTo(T) method is not overridden (the compareTo(int) method is defined, but that is not the same method signature), therefore, it will probably lead to a compiler error.
I think you are making it a bit too tough on yourself, a priority queue is efficiently implemented with array-based heaps: simpler and more efficient (read: contiguous memory areas).

Categories