Java priority queue that extends comparable? - java

I am working on a class assignment and I don't quite understand how to use comparator in the way the assignment is asking.
The assignment reads:
"Complete the Priority Queue class
Your Priority Queue must use an anonymous function to decide priority
It must take the Function interface as a parameter to the constructor
You should still have the default constructor – and if no function is provide use the compareTo function of the class"
This is the class that I am working on...
public class PriorityQueue <Item extends Comparable<Item>> {
public PriorityQueue()
{
}
public PriorityQueue(Comparator<Item> compare )
{
}
private int size = 0;
private Node<Item> head = null;
private Comparator<Item> compare ;
private static class Node<Item>
{
private Item data;
private Node<Item> next;
public Node(Item data, Node<Item> next)
{
this.data = data;
this.next = next;
}
public Node(Item data)
{
this.data = data;
this.next = null;
}
public Node()
{
this.data = null;
this.next = null;
}
}
#Override
public int size() {
return size;
}
#Override
public Item dequeue() {
// TODO Auto-generated method stub
return null;
}
#Override
public void enqueue(Item item) {
Node<Item> curr = head;
Node<Item> prev = curr;
if (isEmpty())
{
head = new Node<Item>(item,null);
}
else
{
while (curr != null)
{
prev = curr;
curr = curr.next;
}
prev.next = new Node<Item>(item, curr);
}
size++;
}
#Override
public boolean isEmpty() {
return size == 0;
}
#Override
public void printQueue() {
Node<Item> curr = head;
while (curr != null)
{
System.out.println(curr.data);
curr = curr.next;
}
}
}
This is the process class that the queue will contain...
public class Process implements Comparable<Process> {
private ProcessPriorty priority;
private String name;
public Process(ProcessPriorty priority, String name) {
super();
this.priority = priority;
this.name = name;
}
public void setPriority(ProcessPriorty priority) {
this.priority = priority;
}
#Override
public String toString() {
return name + "... Priority = " + priority + ".";
}
public String getName() {
return name;
}
public ProcessPriorty getPriority() {
return priority;
}
#Override
public int compareTo(Process other) {
if(other == null)
{
return 1;
}
return this.priority.compareTo(other.priority) ;
}
}
I understand the concept of a queue and have even coded the enqueue method to work as a simple queue that inserts the items as they come in. The problem I am coming across is comparing the nodes within that method to sort the list by priority at insertion. Which I believe relates back to those three directions of the assignment. So, what am I suppose to do with the constructors, the Comparator variable, and how do I make it default to compareTo?

Well since you have a reference to the head of the queue, its pretty simple from there. You have 2 cases -
compare != null
compare == null
In the first case, you are interested in Comparator::compareTo. From the definition of a priority queue, all you have to do is traverse the queue beginning from head, and as soon as the item in enqueue(Item item) is greater than the current element in the traversal, you insert item before element. You'll use compare.compareTo(item, element) to determine their order.
In the second case you'll simply use item.compareTo(element) to make the above stated comparison, the traversal and insertion will be the same.

Related

Push method for Stack with Nodes

I am having trouble doing a homework assignment involving stacks and nodes in Java. I understand the concept of Stacks but am confused with Nodes. The assignment is to make a program using Stacks (Not java.util.Stack) that checks a mathematical expression for correct pairs of (), [], and {}s. We already have the Node program.
So basically my problem is I would like some help completing the Push Method of my PStack class.
PStack.java
class PStack {
private Node top;
public PStack() {
top=null;
}
public boolean isEmpty() {
return top==null;
}
public int pop() {
Node top1 = top;
top = top.getNext();
return top1.getData();
}
public void push(Node n) {
}
public int peek() {
return top.getData();
}
}
Node.java
public class Node {
private int data;
private Node nextnode;
public Node(int intial) {
data = intial;
nextnode = null;
}
public int getData() {
return data;
}
public Node getNext() {
return nextnode;
}
public void setData(int newdata) {
data = newdata;
}
public void setNode(Node next1node) {
nextnode = next1node;
}
}
I tried:
public void push(Node n) {
Node next = n;
top.getNext().setNode(n);
}
Result:
Exception in thread "main" java.lang.NullPointerException
at javaclass.stack.pStack.push(pStack.java:24)
at javaclass.stack.StackDriver.main(StackDriver.java:17)
public void push(Node n) {
n.setNode(top);
top = n;
}
Edit:
BTW, this is an odd implementation of a stack. It looks like it wants to be a stack of int primitives. Both peek() and pop() return an int. But then push takes an argument that should be an internal construct of the stack itself. It shouldn't take a Node object as an argument. It should take an int argument and wrap it with the Node object internally.
Also, Node.setNode should be named Node.setNext. It's just more consistent with what you are doing. A linked list node has a "next" member and a double linked list node has "next" and "previous" members. The getters and setters of the node object should be appropriately named for those members.
Like this:
PStack.java
public class PStack {
private Node top;
public boolean isEmpty() {
return top==null;
}
public int pop() {
Node top1 = top;
top = top.getNext();
return top1.getData();
}
public void push(int data) {
Node newtop = new Node(data);
newtop.setNext(top);
top = newtop;
}
public int peek() {
return top.getData();
}
}
Node.java
public class Node {
private int data;
private Node next;
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}

Adding nodes to a list in ascending order with Java

Is there a way to use the compareTo function when comparing objects, I'm not sure if it's just for Strings. I am trying add an node into its correct position in ascending order.
heres where I declare my attributes/constructor
private Node<E> head; //refers to the head of the node
private int size; // keeps track of the size of the list
// default constructor which creates empty ordered list
public OrderedList(){head = null; size = 0;}
Heres my insert function
public void insert(Object o)
{
Node n = new Node(o, null); // creates new node
// Node for first element greater than or equal
Node current = head.getLink();
Node before = head; // Node for right before the next one is found
// checks to see if list is empty
if(size == 0)
{
head = n;
}
// checks if element is smaller than the head
else if (o.compareTo(head.o) < 0)
{
n.getLink() = head;
head = n;
}
}
here is my node class
package project.pkg3;
public class Node<T>
{
private Object data;
private Node link;
public Node(Object o, Node l){data = o; link = l;}
public void setData(Object o){data = o;}
public void setLink(Node l){link = l;}
public Object getData(){return data;}
public Node getLink(){return link;}
}
I'm getting an error message when trying to check whether the element belongs in the front on this line
else if (o.compareTo(head.o) < 0)
telling me that it cannot find the symbol, which I'm not sure what that means
Im also getting another error message on this line
n.getLink() = head;
this one is telling me that it's an unexpected type
If your linked list must be sorted using compareTo(), then you need to make sure that the underlying data is comparable.
public class Node<T extends Comparable>
{
private T data;
private Node<T> link;
public Node(T o, Node<T> l) { data = o; link = l; }
public void setData(T o) { data = o; }
public void setLink(Node<T> l) {link = l; }
public T getData() { return data; }
public Node<T> getLink() { return link; }
}
Then this block
else if (o.compareTo(head.o) < 0)
{
n.getLink() = head;
head = n;
}
should be changed into this:
else if (
(o.getData() != null) ?
(o.getData().compareTo(head.getData()) < 0) :
(head.getData().compareTo(o.getData()) > 0)
)
{
n.setLink(head);
head = n;
}
I didn't look at your linked list implementation though, so I have no idea the other stuff are correct.
Your node class should implement java.lang.Comparable interface and override its compareTo() method as per your logic.
public class Node<T extends Comparable<T>>{
}
Your argument object would implement Comparable interface. For eg:
public class Name implements Comparable<Name> {
private String str1;
public int compareTo(Name o) {
//your logic here to compare object with itself
return this.str1.compareTo(o.str1);
}
}

insert method for Priority Queue using Linked Lists

Firstly I feel I should mention this is for an assignment. I'm not looking for a direct code answer just to point me in the right direction. We have been asked to implement a Priority Queue in a linked list.
I am struggling to write the first part of the insert() function. In the code I try to check if the head contains anything, if not it set's the head to pqItem. It does this, but when insert is called again for a second insert it doesn't recognise that head already has a PQueueItem in it and just overrides head instead of ignoring if (this.head == null). Am I not settting head correctly?
PQueue Class
package ci284.ass1.pqueue;
public class PQueue<T> {
private PQueueItem<T> head;
public static enum ORDER {
ASC, DESC;
}
public static ORDER DEFAULT_ORDER;
private ORDER order;
public PQueue() {
this.order = DEFAULT_ORDER;
head = null;
}
...
public void insert(T data, int priority) {
PQueueItem<T> pqItem = new PQueueItem<T>(data, priority);
PQueueItem<T> temp;
PQueueItem<T> prev;
System.out.println("This is pqItem " + pqItem);
if (this.order == ORDER.DESC || this.order == DEFAULT_ORDER){
if (this.head != null){
System.out.println("Not null " + head);
if (priority <= head.getPriority()){
}
else if (priority > head.getPriority()){
prev = head;
System.out.println(prev);
head.setNext(head);
prev = pqItem;
System.out.println(prev);
}
}
if (this.head == null){
System.out.println("Null " + head);
this.head = pqItem;
System.out.println("Null " + head);
}
}
}
PQueueItem Class
package ci284.ass1.pqueue;
public class PQueueItem<T> {
private int priority;
private T data;
private PQueueItem<T> next;
public PQueueItem(T data, int priority) {
this.data = data;
this.priority = priority;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public PQueueItem<T> getNext() {
return next;
}
public void setNext(PQueueItem<T> next) {
this.next = next;
}
public String toString() {
return String.format("[%s,%d]", data.toString(), priority);
}
}
JUnit Test for insert
#Test
public void testInsertStart(){
PQueue<String> pq = new PQueue<String>();
pq.insert("1",2);
String head = pq.pop();
assertEquals(head, "1");
System.out.println("Worked");
pq.insert("Hiya",3);
assertEquals(head, "Hiya");
}
The test returns:
org.junit.ComparisonFailure: expected:<1> but was:<Hiya>
and the console reads:
This is pqItem [1,2]
Null null
Null [1,2]
Worked
This is pqItem [Hiya,3]
Null null
Null [Hiya,3]
Here is some pseudocode code. (I have tested it by creating a queue)
public void insert(int priority, int data) {
Item item = new Item(priority, data);
if (head == null) {
head = item;
item.setNext(null);
} else {
Item next = head;
Item prev = next;
do {
if (priority > next.getPriority()) {
// break and insert
break;
}
prev = next;
next = next.getNext();
} while (next != null);
item.setNext(next);
if (item.getPriority() > head.getPriority()) {
head = item;
} else prev.setNext(item);
}
}
You had the following problems in your insert method:
prev = head;
head.setNext(head);
prev = pqItem;
What does this piece of code even do? Here is what it does:
You also did not consider the case in which you have more than two items in the queue. Imagine you have 5 items in the queue. And now you want to insert pqItem in the queue. pqItem has the least priority so it will get inserted at the end of the queue, right? Therefore, you need to traverse the queue (list) in order to get to the last item.

Understanding doubly linked circular list

I have an assignment in my CS class about circular doubly linked lists. We are given a Node class that sets up the links and such.
public class Node {
private Node previous, next;
private Object data;
public Node(Object data) {
this.data = data;
}
public Node() {
}
public Node(Object data, Node previous, Node next) {
this.previous = previous;
this.next = next;
this.data = data;
}
public Node getPrevious() {
return previous;
}
public void setPrevious(Node previous) {
this.previous = previous;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
and we are tasked with implementing a few methods. In the list class there is one Node created called 'base'
public class DList {
private Node base;
public DList() {
}
all of the methods require some form of traversing the list. From what I understand setting up a temp node to be equal to base.getNext() will give me the first node of the list and testing if temp != base will be my check for reaching the end of the list since the base node serves as an anchor for the rest of the nodes (if my understanding is correct).
However, when I try to do bits of code such as:
public int size() {
int count = 0;
if (base.getNext() == base)
return count;
else {
Node temp = base.getNext();
while (temp != base) {
temp = temp.getNext();
count++;
}
}
return count;
}
I get a null pointer exception at the line where I say Node temp = base.getNext(); and for the life of me I cannot understand why, because like I said earlier I thought that base.getNext() would be the first element of my list.
There is no need for a dummy base node. In that case base initially is null.
In that case:
public int size() {
int count = 0;
if (base != null) {
Node temp = base;
do {
temp = temp.getNext();
count++;
} while (temp != base);
}
return count;
}

How to display items in a linked list in java

Hi all im wondering how to display all nodes in a linked list. Heres the code I have so far. The Manager class is supposed to operate the list. The movieNode class creates new list nodes for the movie. I know I have to use other things as well but im just trying to get the first element of the list to display for starters.
public class Manager {
MovieNode head;
public Manager (){
head=null;
}
public void Add (MovieNode data) {
if (head==null){
head=data;
}
}
public void Display () {
int i=1;
MovieNode temp=head;
System.out.println("Displaying Movies");
while (head!=null) {
System.out.println(temp.getData().getName());
head=null;
}
}
}
also, the code for the MovieNode class
public class MovieNode {
private Movie data;
private MovieNode next;
public MovieNode (){
data=null;
next=null;
}
public MovieNode (Movie data){
setData(data);
}
public void setData (Movie data){
this.data=data;
}
public Movie getData (){
return data;
}
}
Hopefully this will help you get started. Here are some pointers:
Manager Class
You don’t need an explicit constructor for Manager, as you can initialize the head variable in line and you’re not passing any other information to the constructor
Method names in Java are conventionally camel case and start with lower-case letter
When you add a new item to the linked list, you can pass in just the data and create the node in the add method
Assuming you don’t need to maintain any special order, you can insert the new item to the head of the list. This saves the time to go through the whole list to find the tail or keeping a reference to the tail.
To display all the movies, you just need to start with the head and check if there is a node next in list. If you don’t need to implement this custom method, I would recommend implementing the class as Iterable. A SO discussion on this topic can be found here
MovieNode Class
You only need one constructor that takes the data and sets the private variable
You also need the getter and setter for the next variable in order to hold the list structure and iterate through the list
The toString() implementation will allow to print an instance of this class directly, as in displayAllMovies() method
Movie Class
This class just holds the title of the movie for now, but you can extend it according to your spec.
Here is the code:
public class Manager {
MovieNode head = null;
public void addMovie(Movie data) {
MovieNode newNode = new MovieNode(data);
if (head == null) {
head = newNode;
} else {
newNode.setNext(head);
head = newNode;
}
}
public void addMovieInOrder(Movie data) {
MovieNode newNode = new MovieNode(data);
if (head == null) {
head = newNode;
} else {
MovieNode higher = head;
MovieNode lower = null;
// find the right position for newNode
while(higher != null){
if(newNode.compareTo(higher) > 0){
lower = higher;
higher = higher.getNext();
}
else break;
}
newNode.setNext(higher);
if(higher == head) head = newNode; //inserting as head
else lower.setNext(newNode);
}
}
public void displayAllMovies() {
MovieNode node = head;
if (node == null) {
System.out.println("The list is empty!");
}
do {
System.out.println(node.getData());
node = node.getNext();
} while (node != null);
}
public static void main(String[] args) {
Manager manager = new Manager();
manager.addMovieInOrder(new Movie("ddd"));
manager.addMovieInOrder(new Movie("ccc"));
manager.addMovieInOrder(new Movie("aaa"));
manager.addMovieInOrder(new Movie("bbb"));
manager.displayAllMovies();
}
}
Movie Node class:
public class MovieNode implements Comparable<MovieNode> {
private Movie data;
private MovieNode next = null;
public MovieNode(Movie data) {
this.data = data;
}
public void setData(Movie data) {
this.data = data;
}
public Movie getData() {
return data;
}
public void setNext(MovieNode node) {
this.next = node;
}
public MovieNode getNext() {
return next;
}
#Override
public String toString() {
return data.toString();
}
#Override
public int compareTo(MovieNode otherMovieNode) {
return data.compareTo(otherMovieNode.getData());
}
}
Movie class:
public class Movie implements Comparable<Movie> {
private String title;
public Movie(String title) {
this.title = title;
}
#Override
public String toString() {
return title;
}
#Override
public int compareTo(Movie otherMovie) {
return title.compareTo(otherMovie.title);
}
}

Categories

Resources