Inserting into a Priority queue - java

I've been given a task of making a priority queue from scratch without extension programs.
The underlying task in hand is to create a priority queue for an IT ticketing System that allows the IT workers to prioritize which tasks within the company must be completed first . (priority = 1 -> Highest priority and 4 being the lowest).
I'm attempting to do this via a singly linked list.
My issue in hand is once my insertInQueue(Ticket T) function takes the last value in it fails.
The failure return statement is
Exception in thread "main" java.lang.NullPointerException
at Queue.insertInQueue(Queue.java:36)
(the line of code at line 36):
`if( temp.getNextTicket().getPriority() > T.getPriority())
at Main.main(Main.java:21) (The last object to go into the system)
private Ticket head;
private Ticket tail;
public void insertInQueue(Ticket T){
Ticket temp = head;
if(head == null){ //When no values are in the queue
head = T; //head = Ticket
tail = T; //tail = Ticket
}else if(T.getNextTicket() == null){
tail.setNextTicket(T);
tail = T;
}
else{
while( temp != null ){
if( temp.getNextTicket().getPriority() > T.getPriority()){
T.setNextTicket(temp.getNextTicket());
temp.setNextTicket(T);
}
temp = temp.getNextTicket();
}
}
}
Example of input:
Ticket T8 = new Ticket(8, "Ben_DG", 4);
I've tried a few different things but havn't gotten anywhere. Would anybody be able to help me out?
If you need more of my code let me know and I'll post it up. (just a little concerned some class mates would steal it)
Thanks!

Since you haven't provided the rest of the code for what set and get next ticket, I can't tell for sure, but logically at some point you are trying to get a NULL value with your get method which is giving you the error. Check all your conditionals properly and see if you aren't trying to get a NULL value.
That should be the main issue and should fix it

Related

To delete an entire linked list in java which I have created

I want to delete an entire list which I have created in java(note: I am not using internal list in java.util). I have assigned head to null but my question is will the java garbage collector handle the list which has no head or should I delete every node(I mean setting every node to null) which will be handled by java garbage collector? Following is my code, please let me know which one is ok although both works but I would still like to know. Thanks in advance.
//first code
public void deleteList()
{
Node n = head;
Node n1;
head = null;
System.out.println("Deleting list");
while(n != null)
{
n1 = n;
n = n.next;
n1 = null;
}
n1 = n;
n1 = null;
System.out.println("List deleted");
}
//second code
public void deleteList()
{
head = null;
}
It depends on your implementation. If your Node class is internal only (so you don't ever return a Node where it might be saved) and you don't hold any in statics, then there should be no path to any node from a garbage collection root and GC will get rid of them.
So it's probably right, unless your implementation is doing something unusual. (I'm also assuming you don't have a tail variable or anything else that references an internal Node, because those would also need to be set to null).
The Garbage Collector will destroy an object only when the particular object doesn't have any linked internal dependency to other nodes. In other words, whenever the objects are not referenced anymore, they are destroyed and their memory is reclaimed.
your first code is right, when you have internal dependency with other nodes i.e, tail node, for example.
your second is right, when you doesn't have any dependency with other node.

delete node after specified node in doubly linked list. (recursively)

I have this recursive function that is supposed to delete the node that comes after the specified one in
a doubly linked list. However My method Isn't deleting anything. I am having trouble with rearranging the values in the list. Any ideas?
private void deleteAfterThis(T data, Node headAux) {
if(headAux == null) {
return;
}
Node deleteAfter = new Node(data);
Node target = deleteAfter.next;
if(target == null) {
return;
}
if(deleteAfter.prev == null){
if(target != tail && target==headAux) {
deleteAfter.next = target.next;
target.next.prev = deleteAfter;
size--;
deleteAfterThis(data, headAux.next);
}
else if(target == tail && target == headAux) {
deleteAfter.next = null;
deleteAfter = tail;
size--;
return;
}
}
else if(deleteAfter.prev != null) {
if(target != tail && target == headAux) {
deleteAfter.next = target.next;
target.next.prev = deleteAfter;
size--;
deleteAfterThis(data, headAux.next);
}
else if( target == tail && target == headAux) {
deleteAfter.next = null;
deleteAfter = tail;
size--;
return;
}
}
deleteAfterThis(data, headAux.next);
}
One mistake I see right off the bat is that you should not be creating a completely new node for deleteAfter. Intuitively, does it make sense to have to create a new node when attempting to delete one? I'll assume that, even knowing what the constructor for Node actually looks like, it sets the next and prev pointers to nodes to null. As a result, you'll keep recursively updating headAux until it's null without ever deleting anything. It seems what you want deleteAfter to be is headAux.next.
Another bug I see is that you've copy and pasted your checking logic twice - I recommend stepping through both cases and verifying if the logic should be identical within each block of the if and else-if blocks (it probably shouldn't).
Stepping into the logic, you should realize that the prev node of the current (headAux in your code) would be null only if headAux is the head of the list. Thus, it would be a bit more clear to rewrite the headAux.prev check as verifying if headAux is equal to the head of the linked list.
Looking at the actual deletion logic, it seems to make sense in the general case to me (assuming the fact that deleteAfter is the next node of headAux as stated above). You're making the prev of the node to be deleted to point to the deleted node's prev node and the next of the previous node (after having set the pointer, which I'm not too big of a fan of but it works) point to deleteAfter.
Lastly, when you do actually locate the node you'd like to delete, you probably shouldn't be calling the recursive function again. You already handle the setting of pointers correctly, so there shouldn't be a need to do so.
I would highly recommend you (re-)draw a sample use-case of your circular linked list and perform deletion on a sheet of paper before jumping to coding the edgecases (which aren't all handled here). The edge cases you should probably be aware of are the following: empty list, deleting head, deleting tail, single-node list. In your code, it seems that you did try to handle the deletion of the head (you'd have to remember to set the head afterwards). After getting that to work, making deletion work on other cases should be a breeze.

Getting an infinite loop while trying to remove from a queue

I'm modeling a fastfood drive-through using a priority queue of Event objects (yep, homework). There are three stations, an order, payment and collection station, each with their own queues. I'm having an issue removing an item from the collection station (the last station visited by a Customer). When the collection queue fills up, the simulation begins to loop indefinitely and the timer no longer increments. I assume it's because of this line:
public void processFoodCollection(Customer c, Event e) {
collection.remove(c);//this is the issue I believe
collection.setServerStatus(false);
However, if I attempt to use my standard remove() method (which just calls queue.poll() in the station class), it returns null. I have no idea why this would happen after having just added to the queue, it's given me zero problems any other time I've used it at the other stations (and I just copy-pasted the methods for each station class, they're all identical). I'd really appreciate any help on identifying what is causing this loop, or, if it is the remove(c), how I can fix this.
Here's my Restaurant class (contains the simulation, lazy I know), but hopefully it's not necessary to look at since my documentation isn't complete yet: http://pastebin.com/cHj3xqJN[1]
Here's the method in particular I'm having issue with (collection is a CollectionStation var composed of a queue field, the remove(Customer c) and remove() methods are just for access to the queue methods):
public void processFoodCollection(Customer c, Event e) {
collection.remove(c);//Customer c should be head of queue
collection.setServerStatus(false);//cashier not helping anyone
if (collection.getQueueSize() < 2) {
//process event if room available in collection queue
collection.add(payment.remove());//remove customer from payment queue, add to collection queue
payment.setServerStatus(false);
if (!collection.getServerStatus())
createFinishCollection(collection.peek());//creates event to be processed in the future
//generate new finish payment event for new head of payment queue
if (payment.getQueueSize()>0) {
double b = this.exponentialPay.next();//minutes until finished paying
while (b == 0.0) {
b = this.exponentialPay.next();//ensure return > 0.0
}
createFinishPayment(b, payment.peek());
}
//check if head of order queue can move up
if (order.getQueueSize() > 0) {
if (order.peek().getTimeFinished() == this.clockTime && order.getServerStatus()) {
processFinishOrder(order.peek(), eventList.peek());
} else if (!order.getServerStatus()) {
double timeToOrder = (order.peek().getOrderSize() * this.timeToOrderItem);
createFinishOrder(timeToOrder, order.peek());
}
}
}
}//end method processFoodCollection
If I try to use the remove() method, I get a null pointer exception at:
Event newE = new Event(Events.FINISHFOODCOLLECTION, this.clockTime + (c.getOrderSize() * this.timeToProcessItem), c);
from the null customer object (c). This traces back to the createFinishCollection() method call in the above code. So this is how I know I get a null from calling remove, but I don't understand why my queue would say it's empty when I just added to it. Is there some trick to look out for when indirectly removing data structure elements?
Here's the remove method I'm calling (in the CollectionStation class):
/**
* Removes and returns object at front of queue.
* #return
*/
public Customer remove() {
return customerQueue.poll();
}//end method remove
I'm honestly pretty stumped why this wouldn't work. Any guidance would be appreciated (not looking for answers, just help).

Loop Turning into an Infinite Loop

A segment of my code is triggering an infinite while loop, and I'm not sure why. I've used the loop itself before to add friends to a Linked List in this same program and it worked fine, so I do not understand why it is turning into an infinite loop now.
while (!a.equals("*")){
curr = friendlist.getUsers().getFront();
while (curr!=null){
if (curr.getData().getName().equals(a)){ //why is it not removing friends?
d.removeFriend(curr.getData());
}
curr = curr.getNext();
}
System.out.println("Add a friend by typing in their name. Enter * to end. ");
a = in.nextLine();
}
The above code accesses the following segment from another class:
public void removeFriend(User u){
if (friendsList.isEmpty()){
System.out.println("Empty list, cannot remove.");
}
else{
Node c = friendsList.getFront();
while (c.getNext()!=null){
if (c.getNext().getData().equals(u)){ //condition: if the data is the same
c.setNext(c.getNext().getNext()); //change the link
c.getNext().setData(null); //set the next data to null (cut the link)
friendsList.setSize(friendsList.size()-1);
c = c.getNext();
}
}
}
}
Why is the code not running properly?
As another poster has mentioned, you are invoking the getNext() method twice in one code block.
Here's what I presume is what will work for you
while (c!=null){
if (c.getNext().getData().oldestFriend().getBirthYear()>c.getData().oldestFriend().getBirthYear()){
a = c.getNext().getData();
continue; //then skip the current iteration, so that your line below after the if statement, wont get called.
}
c = c.getNext();
}
Why dont you do this, because now it looks like you're calling that same method three times!
Instead, store whatever is returned from the getNext() into one variable, and then access that local variable and do whatever you want with it, analyse is however you like etc.
Do you know where the infinite loop is exactly? Maybe put a System.out.println("loop") before curr.getNext() and c.getNext() so see which one is failing?
Would add this as a comment, but I'm not yet allowed to :(
How is the semantic of
allUsers.getFront()
Does it just fetch the head or is it more like a pop-operation?
In case of a fetch, there might be an issue with the recursive call of
oldestFriend()
in the method oldestFriend().
Though in that case I would expect a StackOverflowException.
change your while by:
while (c.hasNext() {
Node oldC = c;
c = c.getNext();
if(c.getData().oldestFriend().getBirthYear() > oldC.getData().oldestFriend().getBirthYear()) {
a = c.getData();
}
}
Call only getNext() if there is next, and only once.

How to push Nodes of a Binary Search Tree with same Content in a stack

I have a BinarySearchTree that contains people. Each person has a property of birthday month.
I have the following code trying to push Nodes to a stack if the people has the same birthday month. But when i run the program it throws a java.lang.OutOfMemoryError: Java heap space.
How can i get all elements that has the same birthday month and push them to the stack?
EDIT: Working code based ok KarlP's answer
//Part of the code
//Declared in Instance Variables
private Stack<BinaryNode> st = new Stack<BinaryNode>();
//Methods
public void getSame(BinaryNode node, String mo){
if(node != null){
if (mo.equalsIgnoreCase(node.people.getBmonth())){
st.push(node);
}
getSame(node.left, mo);
getSame(node.right, mo);
}
}
public void getSt(String mo){
getSame(root, mo);
}
You are not updating the node so it will loop for ever inside the while loop.
I think it probably should be replaced with an if statement, as a stop-condition for the recursive calls.
A recursive algorithm always needs an if of some sort. Otherwise it just keeps going down.
if (we are done) {
return(1);
} else {
return recurse() + recurse();
}
In your case, you want to test for the lack of children nodes to end the recursion.
Use this to end the recursion:
if (node != null){

Categories

Resources