Issue with removing a node - java

I'm working on a link list and not currently able to remove a speficic node by a key value. I ask a helper at my school and he is not sure why it isn't working.(There is also a lot of try-catches for another issue I apologize for how gross it looks)
Here is my remove method:
public void remove(int key) throws Exception {
Node tmp = first;
Node pred = first;
while (tmp != null) {
if (tmp.keyValue == key) {
pred = tmp;
tmp = tmp.next;
} else {
tmp = tmp.next;
}
}
Here is my main method creaing the list and trying to remove it and print it:
OrderedLinkedList oLL3 = new OrderedLinkedList();
try {
oLL3.insert("Should be removed", 5);
oLL3.insert("Shouldn't be removed 2nd", 15);
oLL3.insert("Shouldn't be removed", 10);
} catch (Exception e) {
System.out.println("Error: Two nodes with the same key value and the newest one won't be stored.");
}
try {
oLL3.remove(5);
} catch (Exception r) {
System.out.println("Error:No nod with the key value to be removed");
}
System.out.print("toString test removing node: \n" + oLL3.toString());
System.out.println("Number of nodes in the List:" + oLL3.listCount());
}

In this code shown you are deleting the first node of the linked list, and to delete the first node you need to point the "head" (or whatever the name of your head node is) to the second node, i.e.
head = head.next;

Your remove method is only assigning to local variables. That is not going to affect the state in your linked list. Assuming that the head of your list is the node held by the field first, you need to assign to either first or to the .next field in another node.
To remove the first node, you can do:
first = first.next;
To remove the node after node prev, you can do:
prev.next = prev.next.next;
(null-checking where appropriate)

Related

Implementing my own LinkedList, insertion of a new element to the Tail doesn't work correctly

I`m trying to implement my own linkedlist and I tackled with this question.
This is add method implementation for linkedlist, supposed to add specified elements to the end of the list.
Below you see a code I found and that works, and you see my code which only shows last 2 elements added no matter how many you add to the list.
The only difference 2 codes have is that he stores rootNode (head) inside currentNode and does his traversing using currentNode. I directly used rootNode to do the same. Can someone explain my what is wrong with my code ?
This is his code that works:
public void add (E val) {
Node newNode = new Node(val, null);
Node currentNode = rootNode;
if (rootNode == null) {
rootNode = newNode;
} else {
while (currentNode.nextNode != null) {
currentNode = currentNode.nextNode;
}
currentNode.setNextNode(newNode);
}
}
And this is my code that only shows last 2 elements added :
public void add (E val) {
Node newNode = new Node(val, null);
if (rootNode == null) {
rootNode = newNode;
} else {
while (rootNode.nextNode != null) {
rootNode = rootNode.nextNode;
}
rootNode.setNextNode(newNode);
}
}
That happens because you're resigning the rootNode while iterating.
By making this, you are erasing all previous state of the list, which you can access only via root. That's way the only node that remain in the list are root and its next node.
In order to iterate over the list, you should introduce the local variable like in the first version. There's no other way around.
And I suggest to simplify the method a bit by returning after checking whether the root is null, there will be no in nesting the loop into the additional block of curly braces:
public void add (E val) {
Node newNode = new Node(val,null);
if(rootNode == null) {
rootNode = newNode;
return;
}
Node currentNode = rootNode;
while (rootNode.nextNode != null) {
rootNode = rootNode.nextNode;
}
rootNode.setNextNode(newNode);
}
Because you are changing root node, after add method ends, you have only the root node and the next node of it, do not change root node if it is not null.
For instance, you call add Method for nodes A, B, and C.
For the first time root is A, then when you call add(B), as the root node is not null already, loop will not work in the else statement and the next of A will be B, then when you call add(C), while loop will work one iteration and B will become root node(you lost A) and the next of B will be C node.

Implementing an AddAtIndex method in a LinkedList

currently, I am working on implementing an AddAtIndex method and for the most part it seems to be working fine. However, my method is not passing my JUnit test and I can't seem to understand why. Thus, I have chosen to show the code I have done thus far:
**
* Add an element to the list at the specified index
* #param The index where the element should be added
* #param element The element to add
*/
public void add(int index, E element ) //Method should be O(1) time.
{
// TODO: Implement this method
if (index < 0) {
System.out.println("Can't add an element at a negative index.");
}
int i = 0;
LLNode<E> currentNode = head.next;
while ( i < size ) {
if ( i == index ) {
LLNode<E> newNode = new LLNode<E>(element);
LLNode<E> tempNode = new LLNode<E>(currentNode.data);
currentNode.next = tempNode;
currentNode.data = newNode.data;
newNode.prev = currentNode.prev;
newNode.next = tempNode;
tempNode.prev = newNode;
size++;
}
currentNode = currentNode.next;
i++;
}
}
My thought process behind the code is that the method creates a new Node, then it replaces the data at the specified index of the linked list. However, the data at the node it is replacing is stored in a temporary node which is incremented in position to the next node after the new node. I am about 80% confident in my implementation though the code looks a bit sloppy. I have created a driver to demonstrate the implementation. The drivers code is as follows:
public class LinkedListDriver {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyLinkedList<String> nameList = new MyLinkedList<String>();
nameList.add("Hamadi");
nameList.add("Ballo");
nameList.add(1, "Salisu");
nameList.add(2, "Galo");
System.out.println(nameList.toString());
System.out.println(nameList.size());
nameList.set(2, "Abdullahi");
System.out.println(nameList.toString());
nameList.remove(1);
System.out.println(nameList.toString());
MyLinkedList<Integer> list1 = new MyLinkedList<Integer>();
list1.add(65);
list1.add(21);
list1.add(42);
System.out.println(list1.toString());
list1.remove(0);
System.out.println(list1.toString());
}
}
The Output from the driver is as follows:
List: Hamadi, Salisu, Galo, Ballo,
4
Replacing Galo with Abdullahi
List: Hamadi, Salisu, Abdullahi, Ballo,
Removing Salisu from the list
List: Hamadi, Abdullahi, Ballo,
List: 65, 21, 42,
Removing 65 from the list
List: 21, 42,
The unit test fails however with the following error:
It fails at the AssertEquals method:
shortList.add(2, "E");
shortList.add(3, "F");
**assertEquals("AddAtIndex: at position 2 ", "E", shortList.get(2)); //fails here**
assertEquals("AddAtIndex: at position 3 ", "F", shortList.get(3));
assertEquals("AddAtIndex: List size is ", 6, shortList.size());
I would like to know what I'm doing wrong. I have this literally completely figured out, though I know that there is something a bit off about my AddAtindex method. Thanks!
You don't need that tempNode. Just create the newNode and insert it properly between currentNode and its previous node.
You should also consider the possibility of adding an element at the beginning (no previous) or end (no next) of the list.
I used head and tail as sentinel nodes. Created a new node to be added in the list.
public boolean add(E element) {
// create new element
LLNode<E> variable = new LLNode(element);
variable.next = null;
variable.prev = null;
// if element is null, throw exception
if (element == null) {
// return false;
throw new NullPointerException("Element is null");
} else {
// get the value stored in tail.prev in variable temp.
variable.prev = tail.prev;
variable.next = tail;
// now modify the tail node prev and new node next
tail.prev = variable;
// get prev node next link changed
variable.prev.next = variable;
// update size
if (head.next.next != tail) {
size++;
}
return true;
}
}

JAVA Linked List :method to insertLast

I have my code as following:
Node current=head;
if(current==null)//check
else{
while(current.getNext()!=null)
current=current.getNext(); //loop through to find the last node in the list
}
//if I find it then connect it with my newNode(add)
Node add=new Node("A");
current.setLink(add);
add.setLink(null);
But it does not work, I drawn a diagram but still have no idea what`s wrong with it.
the line
if(current==null) //why do you check if you don't have any statements afterwards?
this solution is for singly linked list:
public static Node addLast(Node head, Object x) {
// save the reference to the header so we can return it.
Node ret = head;
// check base case, head is null.
if (header == null) {
return new Node(x, null);
}
// loop until we find the end of the list
while ((head.next != null)) {
head = head.next;
}
// set the new node to the Object x, next will be null.
head.next = new Node(x, null);
return ret;
}

Delete last node, or only node from a Linked List in Java.

I am unable to get my program to delete the last node or only node in my linked list. It will delete any other node. This program allows the user to enter integers and delete them. Thanks in advance for your help.
// This method finds the value requested in the Linked List.
public Node find(Node head, Comparable value2){
if (head == null )
{
System.out.println("The list is empty");
return null;
}
Node pointer = head;
while (pointer != null)
{
if (pointer.data.compareTo(value2)>=0)
{
Node delNode = pointer;
System.out.print("Found it. Deleting " + delNode.data + "\n");
return delNode;
}
pointer = pointer.next;
}
return null;
}
// This method deletes a given value from the linked list.
public void delete(Node head, Comparable value2){
Node delNode;
delNode = find(head, value2);
if (delNode== null)
{
System.out.println("The value: " + value2 + " does not exist");
print(head);
}
else
{
if (delNode.next == null)
{
System.out.println("Trying to delete last");
delNode = null;
print(head);
}
else{
delNode.data = delNode.next.data;
Node temp = delNode.next.next;
delNode.next = null;
delNode.next = temp;
print(head);
}
}
return;
}
I thought that if (delNode.next== null) {delNode = null} would do it?
If you want to delete a node, you should have a reference to the node before the one you want to delete, say beforeNode, and set
beforeNode.next = beforeNode.next.next;
(Think about special cases like deleting the last element.)
See Java Linked List search and delete method
Please note that in the sequence
delNode.next = null;
delNode.next = temp;
The first line is useless.
You current delete operation effectively works by copying the next node into the current node and then deletes the next node, making it look like you deleted the current node. This is fine until there is no next node, as you have discovered.
The reason the following doesn't work
if (delNode.next == null)
{
System.out.println("Trying to delete last");
delNode = null;
print(head);
}
is that delNode is just a local variable, setting delNode to null doesn't affect anything outside of delete().
If you want to delete the last node from the list, you need to set the next pointer in the second last element to null. Therefor it is insufficient for find() to simply return the element you wish to delete -- you need the previous element.
Pseudocode for delete(data) should be (untested):
if head == null
return
if head.data == data
head = head.next
return
previous = find_previous(data)
if previous == null
return
previous.next = previous.next.next

How do you remove nodes from a linked list?

I have a linked linked of student objects. It's basically a database that stores data about students as student objects. The only problem I am having is creating the removeStudent method. Posted below is what I have tried so far, altering different parts of it to see if a different result occurs. Right now with this code, I can delete a student in my driver, but it will also delete every student before the one that I want to delete as well, leaving behind only the students that are in the database after the student that I am trying to delete.
public void RemoveElements(Object Student) {
LinearNode<Object> current = element;
LinearNode<Object> temp = current;
while (current.getNext() != null) {
temp = current;
current = current.getNext();
if(current.getElement() == Student) {
temp.setNext(current.getNext());
length--;
}
}
}
public void RemoveElements(Object Student) {
LinearNode<Object> current = element;
LinearNode<Object> previous = null;
//LinearNode<Object>(student);
while (current.getNext() != null) {
current = current.getNext();
if(current.getElement() == Student) {
length--;
element = element.getNext();
if (previous != null) {
previous.setNext(element.getNext();
} else {
//if you have a pointer to the head element place it element.getNext();
}
}
previous = current;
}
}
If the current contains the object to be removed, you need get a reference to the previous node, and point it at the next node. So you have
A -> B -> C
and B contains the item to be removed, you want your linked list to look like
A -> C
A few things are wrong with your code
1) You are not doing the above
2) You are not setting previous within your while loop. You can do that right before
current = current.getNext();
3) For the code
LinearNode<Object> current = element;
at the top, what is element?
It looks like element is the head of the list. Look at the code that changes element and change it so that when you delete the second item, element still points to the first element and the first element points to the third instead of the second.

Categories