Linked List sorted insertion - java

I'm trying to insert a request and sort it via priority, so highest(1) is first in the list.
public Node addByPriority(Object request, int priority) {
size++;
//creates a new node with a priority, owner and creator and sets its next node to the root
Node newNode = new Node(request, priority);
//node to store prev
Node prevNode = null;
//node to store current
Node currNode = first;
//cycle thru the nodes til either the priority is higher or current is null
while (currNode != null && priority >= currNode.getPriority()) {
prevNode = currNode;
currNode = currNode.getNext();
}
if (prevNode == null) {
newNode.setNext(first);
first = newNode;
}
else {
prevNode.setNext(newNode);
newNode.setNext(currNode);
}
// what would be the return statement??
}
It says I need a return statement but not sure what has to be put, or if there's another way.

You didn't state what Node you're supposed to return, but it stands to reason that you'd return the newly created one:
return newNode;

You can return the head of the linked list as:
return first;
This can be helpful to access the updated list again.

Related

Recusively merge AND sort two linked lists into a third in reverse order

I'm trying to write a single function in Java (Node sortedmerge(Node node1, Node node2)) where the data in node1 and node2 are already sorted in descending order ({5, 3, 1, 0}). I figured out an implementation for the function but I can't figure out how to make it recursive:
//Defined elsewhere as a global variable
static Node<Integer> head = new Node();
//Used to store the final sorted linked list
Node sortedmerge(Node node1, Node node2) {
// if both the nodes are null
if (node1 == null && node2 == null) {
return null;
}
// if both of them have nodes present traverse them
while (node1 != null && node2 != null) {
// Now compare both nodes current data
if (node1.data <= node2.data) {
Node temp = node1.next;
node1.next = head;
head = node1;
node1 = temp;
} else {
Node temp = node2.next;
node2.next = head;
head = node2;
node2 = temp;
}
}
// If second list reached end, but first list has
// nodes. Add remaining nodes of first list at the
// front of result list
while (node1 != null) {
Node temp = node1.next;
node1.next = head;
head = node1;
node1 = temp;
}
// If first list reached end, but second list has
// node. Add remaining nodes of first list at the
// front of result list
while (node2 != null) {
Node temp = node2.next;
node2.next = head;
head = node2;
node2 = temp;
}
return head;
}
supposedly there's a way to do it without a temporary node (Node temp) or any outside functions... but at this point I'd just be happy to make it function recursively (I'm struggling to understand how to implement recursive calls).
Your function merges two sorted lists, you can implement this with a loop as posted or recursively as will be shown below. Note however that:
there is no reason to make head a global variable. You should instead define it as a local and return as the return value of the function.
the head in your code does not point to the head of the list, but to the last element, aka the tail node.
once one of the lists is exhausted, you can just append the other to the last element of the merged list.
a recursive implementation of sortedmerge will require stack space proportional to the length of the merged list, which can easily exceed available stack space, causing a stack overflow exception.
Here is a simple recursive implementation:
Node sortedmerge(Node node1, Node node2) {
// if either node is null, return the other node
if (node1 == null) {
return node2;
}
if (node2 == null) {
return node1;
}
// select the node with the largest data
if (node1.data <= node2.data) {
// select node2 and append the rest of the merged list to it
node2.next = sortedmerge(node1, node2.next);
return node2;
} else {
// select node1 and append the rest of the merged list to it
node1.next = sortedmerge(node1.next, node2);
return node1;
}
}

Java - Removing an element from LinkedList except first

I'm new to Java.
I have created a method where it will remove elements from LinkedList except the first one. The idea is a boolean will be set to true if a LinkedList's element data (Which is in Integer) matched with parameter. Once the boolean sets to true, it will remove any element that also matched with initial one.
Now for the problem. For example, if I were to remove 5 except the first one from this LinkedList:
5 5 5 6 5 7 8 9
I will get result like this:
5 5 6 7 8 9
As you can see, it didn't remove the 5 on the second position. Is there anything wrong with my code?
Here's the code by the way
public void append(int data) {
Node newNode = new Node(data);
if (head == null) {
head = new Node(data);
return;
}
Node lastNode = head;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
lastNode.next = newNode;
return;
}
public void insert(int data) {
Node newData = new Node(data);
newData.next = head;
head = newData;
}
public void removeExceptFirst(int dataValue) { //The mentioned method
boolean duplicate = false;
Node currentNode = head;
while (currentNode.next != null) {
int value = currentNode.next.data;
if (value == dataValue) {
if (!duplicate) {
duplicate = true;
currentNode = currentNode.next;
} else {
currentNode.next = currentNode.next.next;
}
} else {
currentNode = currentNode.next;
}
}
return;
}
The problem here is with
if (!duplicate) {
duplicate = true;
currentNode = currentNode.next;
}
you are marking duplicate = true and immediately assigning the "currentNode = currentNode.next;"
due to this reference is getting preserve of the next node
So
1. Put the condition outside of the loop to check whether the head element itself is
that node, if->yes mark isDuplicate = true and proceed in the loop.
2. Inside the loop check afterward and then assign the next node.
Hope this should work
You skipped head node. Try replace
Node currentNode = head;
with
Node currentNode = new Node();
currentNode.next = head;
You should update the current node reference as well as head->next should point to the current node after removing the node.
try the below code:
if (!duplicate) {
duplicate = true;
currentNode = currentNode.next;
head.next= currentNode.next;
}else {
currentNode.next = currentNode.next.next;
currentNode = currentNode.next;
head.next = currentNode; }
`

Trouble with a sortedInsert into a singly LinkedList.of Objects with attributes Java

This method will create a new Node object and insert it in order by the 3rd value in the CSV(i.e. KYZ98765, ABC12345, etc.) it works except for the last node insert...
Here is my code:
void sortedInsert(Node new_node)
{
Node current;
/* Locate the correct node before inserting. */
//System.out.println(current.data);
if(head.next == null)
{
new_node.next = head;
head = new_node;
System.out.println("Inserted head: \n" + head.data.toString());
}else
{
current = head;
while (current.data.getbLnum().compareTo(new_node.data.getbLnum())>=0)
{
System.out.println("here again");
current = current.next;
}
new_node.next = current.next;
current.next = new_node;
System.out.println("Inserted: \n" + current.next.data.toString());
}
}
Here is the output:
FundManagerLicense FundManagerLastname FundManagerFirstname
ABC12345 Wonch Bob
FundManagerLicense FundManagerLastname FundManagerFirstname
ZYK98765 Ferguson Jesus
FundManagerLicense FundManagerLastname FundManagerFirstname
GYZ98765 Ferguson Jose
FundManagerLicense FundManagerLastname FundManagerFirstname
KYZ98765 Ferguson Jimmi
This is my input in the order each element is fed to the sortedInsert:
BROKER,ADD,KYZ98765,Jimmi,Ferguson,321-131,0.02
BROKER,ADD,ABC12345,Bob,Wonch,321-112,0.1
BROKER,ADD,GYZ98765,Jose,Ferguson,321-111,0.02
BROKER,ADD,ZYK98765,Jesus,Ferguson,321-141,0.02
Can anyone see what is going wrong?
Try it this way.
private int compare(Node n1, Node n2) {
return n1.data.getbLnum().compareTo(n2.data.getbLnum());
}
void sortedInsert(Node newNode) {
Node prev = null;
Node next = head;
while (next != null &&
compare(newNode, next) >= 0) {
prev = next;
next = next.next;
}
if (prev == null) head = newNode;
else prev.next = newNode;
newNode.next = next;
}
It should be fairly self-explanatory, go through the list, keeping track of the nodes that will come before (prev) and after (next) the inserted node, until next is null, or until newNode cannot come after next. Then insert the new node and, if necessary, make it the head.
You have a big risk of a null pointer exception.
while (current.data.getbLnum().compareTo(new_node.data.getbLnum())>=0)
{
System.out.println("here again");
current = current.next;
}
When you reach the end of your list current will become null and the next call to current.data will throw and exception.
Do you know why is not being thrown? Because you made your list a circular list!
new_node.next = head;
head = new_node;
The new node is the head and point to itself as next. So your last insertion goes all the way to the end f the list, fails to find an insertion place (because your last input should be placed at the end of the list) and then became the next after the head.
To solve the problem you need two changes:
void sortedInsert(Node new_node){
Node current;
/* Locate the correct node before inserting. */
//System.out.println(current.data);
if(head.next == null)
{
new_node.next = **null**;
head = new_node;
System.out.println("Inserted head: \n" + head.data.toString());
}else
{
current = head;
while (current.data.getbLnum().compareTo(new_node.data.getbLnum())>=0 **&& current.next != null**)
{
System.out.println("here again");
current = current.next;
}
new_node.next = current.next;
current.next = new_node;
System.out.println("Inserted: \n" + current.next.data.toString());
}
}
Test them and let me know.

How to set next value in a Circularly Linked List in Java?

This is what I have so far:
public void insert(int position, ValueNode value) {
if (position == 1) {
this.nextInRow = value;
}
ValueNode current = this.getFirst();
if (position > 1) {
current.setNext(current.next);
}
value.setNextInRow(current.getNext());
}
The headnode is being set properly with the first if statement. In this list we already know the position, so I'm thinking we don't need a while loop since we know where to put the new node.
I create a temp node called current to hold the next node pointer, but right now it sets the pointer to null. My problem is I don't know where to point the next node pointer to. Any help would be very much appreciated.
Distinguish making a node with value and setting next node operations.
Your data structure can be like this:
class Node {
int val;
Node next;
Node previous;
//setters and getters and constructors
}
1) For all new values should have a node
Node createNode(int val) {
Node newNode = new Node(val);
newNode.next = null;
newNode.previous = null;
return newNode;
}
2) Locate newNode starting from root or hold a current node set it next
currentNode.setNext(Node newNode);
//iterate the currenNode with newNode
currentNode = newNode;
...
// implement the setNext and mark current as previous for newNode
void setNextNode(Node newNode) {
this.next = newNode;
newNode.setPrevious(this);
}

Doubly Linked List of Menu Items

I have a program which processes menu items (and submenu items) using a linkedList data structure. My program works except for the delete function which works if deleting an element inserted before an existing element but doesn't if the element is inserted after an existing element. Any advise is much appreciated! Here's the insert function
public Item insert(String newElem, String existingElem, int key) {
// search for given existing element starting at head
currentNode = new Item("");
currentNode = head;
while (!currentNode.element.equals(existingElem)) {
currentNode = currentNode.next;
if (currentNode == null)
break; // cannot find the given key
}
// create a new node
newNode = new Item(newElem);
if (key == 1) // if key = 1 insert after the existing element
{
newNode.next = currentNode.next;
newNode.prev = currentNode;
currentNode.next = newNode;
tail = newNode;
tail.next = null;
counter++;
}
if (key == 2) // if key = 2 insert before the existing element
{
newNode.next = currentNode;
newNode.prev = currentNode.prev;
currentNode.prev = newNode;
head = newNode;
head.prev = null;
counter++;
}
return newNode;
}
I also realize that I am assuming only one existing element, however, if I could make the delete function more generic then it would be best and I don't want to split the function into multiple functions! Here's the delete function:-
public Item delete(String elem) {
// search for given existing element starting at head
currentNode = new Item("");
currentNode = head;
while (!currentNode.element.equals(elem)) {
currentNode = currentNode.next;
if (currentNode == null)
break; // cannot find the given key
}
// check if element is the first element
if (currentNode == head) {
head = currentNode.next;
} else {
currentNode.prev = currentNode.next;
}
// check if element is the last element
if (currentNode == tail) {
tail = currentNode.prev;
} else {
currentNode = currentNode.prev;
}
return currentNode;
}
Problems
You should not be updating tail and head every time you insert a new node. You should only do so if inserting at the beginning or end of the list, if you are not at the begining of the list, you need to also update the prev/next of the element that used to be before/after the one you are inserting next to:
if (key == 1) // if key = 1 insert after the existing element
{
newNode.next = currentNode.next;
newNode.prev = currentNode;
currentNode.next = newNode;
if (newNode.next == null)
tail = newNode;
else
newNode.next.prev = newNode;
}
else if (key == 2) // if key = 2 insert before the existing element
{
newNode.next = currentNode;
newNode.prev = currentNode.prev;
currentNode.prev = newNode;
if (newNode.prev == null)
head = newNode;
else
newNode.prev.next = newNode;
}
Note: I am also using an else if statement, instead of two ifs
Your delete function need to be updated also. You are not updating the surrounding nodes, just the one you are removing:
if (currentNode.prev == null) { // is head
head = currentNode.next;
} else {
currentNode.prev.next = currentNode.next;
}
if (currentNode.next == null) { // is tail
tail = currentNode.prev;
} else {
currentNode.next.prev = currentNode.prev;
}
Other comments
It seems unusual that you would be searching for the node to insert before/after by value, what if I had a list like this: [1,2,2,2,3]? It would be impossible to insert a value in several places in that list. Surely your API should be based on Items:
public Item insert(String newValue, Item existingItem, int key);
public Item delete(Item item);
Or indicies:
public Item insert(String newValue, int index, int key);
public Item delete(int index);
You can then have another method to find the Item or index for a particular value:
public Item find(String value);
Or:
public int indexOf(String value);
And use them like this to get the equivalent of your methods:
list.insert("value", list.find("other value"), 1);
You might want to consider changing the insert method to an insertBefore and insertAfter method, or at least changing the key parameter to an enumerated type:
public enum Position {
BEFORE,
AFTER,
}
After all, what happens when key is 0, or 23?
You currently have currentItem as a class member, it should really be a local variable of the function (after all, what use does it have outside of those functions), and you also don't need to initialise it to a new element, just set it straight to head:
public Item insert(String newElem, String existingElem, int key) {
Item currentNode = head;
...
}
Finally, your search code doesn't work if there are no items in the list. The following line will fail with a NullPointerException if head is null:
while (!currentNode.element.equals(existingElem))
Because you can't call .equals(...) on a null reference.

Categories