Delete last element in singleLinked List - java

I am making a simple linked list and I'm trying to implement a method that allows me to delete the last node of the linked list. At some point, my method is wrong and I'm not sure where the error is and how to fix it. Here is the code!
public Nodo deleteEnd() {
Nodo aux;
if (head == null) {
throw new NoSuchElementException("Element cant be deleted");
} else {
aux = head;
while (aux.next.next != null) {
aux = aux.next;
}
size--;
}
return aux;
}

You need to assign the next of the last but not least node to null:
if(head.next == null) {
// head is last!
head = null;
size = 0;
} else {
previous = head;
current = head.next;
// while current is not last, keep going
while(current.next != null) {
previous = current;
current = current.next;
}
// current is now on last!
previous.next = null;
size--;
}

public Nodo deleteEnd() {
if (head == null) {
throw new NoSuchElementException("Element can't be deleted");
}
Nodo current = head;
Nodo next = current.next;
// Check if there is only the head element.
if ( next == null )
{
size--;
head = null;
return current;
}
// Skip to the end.
while (next.next != null) {
current = next;
next = next.next;
}
// Break the link to the next element.
current.next = null;
size--;
return next;
}

Add
aux.next = null;
after the while loop - then there will be no reference to the last element.

try reducing one .next:
while (aux.next != null) {
aux = aux.next;
}

Related

How to delete the first node of doubly linked list

I have an implementation of doubly linked list , and I'm trying to delete a particular node at a given position. I managed to delete the second node to the last node but when I try to delete the first node it fails, I wonder what's wrong with my code.
I've already tried this but still doesn't work
head.next.previous = null;
head = head.next;
This is my code
public class Proses {
private class Node{
String Matkul;
int NilaiUts;
int NilaiUAS;
Node previous;
Node next;
public Node(String Matkul, int Nilai, int NilaiUAS) {
this.Matkul = Matkul;
this.NilaiUts = Nilai;
this.NilaiUAS = NilaiUAS;
}
}
Node head, tail = null;
public void addNode(String matkul, int Nilai, int NilaiUAS) {
Node newNode = new Node(matkul, Nilai, NilaiUAS);
if(head == null) {
head = tail = newNode;
head.previous = null;
tail.next = null;
} else {
tail.next = newNode;
newNode.previous = tail;
tail = newNode;
tail.next = null;
}
}
public void delete(int position){
if (head == null || n <= 0)
return;
Node current = head;
int i;
for (i = 1; current != null && i < position; i++)
{
current = current.next;
}
if (current == null)
return;
deleteNode(head, current);
}
//delete function
public Node deleteNode(Node head, Node del){
if (head == null || del == null){
return null;
}
if (head == del){
head = del.next;
del.next.previous = null;
}
if (del.next != null){
del.next.previous = del.previous;
}
if (del.previous != null){
del.previous.next = del.next;
}
del = null;
return head;
}
}
Using your code, if the scenario is such that it ends up with 1 node (head will be pointing to this node) and you want to delete this node (i.e. head), code will fail with NullPointerException at
del.next.previous = null;
as del.next is NULL;
Use can take a look at below code to delete a Node from doubly linked list
// Function to delete a node in a Doubly Linked List.
// head_ref --> pointer to head node pointer.
// del --> data of node to be deleted.
void deleteNode(Node head_ref, Node del)
{
// Base case
if (head == null || del == null) {
return;
}
// If node to be deleted is head node
if (head == del) {
head = del.next;
}
// Change next only if node to be deleted
// is NOT the last node
if (del.next != null) {
del.next.prev = del.prev;
}
// Change prev only if node to be deleted
// is NOT the first node
if (del.prev != null) {
del.prev.next = del.next;
}
// Finally, free the memory occupied by del
return;
}
code ref: https://www.geeksforgeeks.org/delete-a-node-in-a-doubly-linked-list/
The problem with your code is that, head is not getting changed in deleteNode function because it's pass by value. Consider the following scenario:
You are deleting the position 1. Head is pointing to the node1, so
it store the address of node1. assume it's 1001.
Now you call deleteNode function with head reference and currentNode, so head reference is get passed to the function argument as pass by value. so in function argument head contains the address 1001.
Now you perform the delete operation, so the function's head is changing it's position to the next node. But, your class member's head is still pointing to the first position.
To overcome this, you can set the head again, because you are returning it from the deleteNode function. Like:
Change the code as follow
public void delete(int position){
if (head == null || n <= 0)
return;
Node current = head;
int i;
for (i = 1; current != null && i < position; i++)
{
current = current.next;
}
if (current == null)
return;
head = deleteNode(head, current);
}

Remove method in double linked list isn't working?

would anybody be able to help me with this problem I've been having? I'm trying to implement a doubly linked list for the first time and have been frustrated trying to get my code to work for my remove class:
public void remove(int data) {
if(length == 0) {
return;
}
if (head.data == data){
head = head.next;
length--;
}
Node current = head;
while (current != null) {
if(current.data != data) {
current = current.next;
length--;
}
current = current.next;
}
}
I know this question may have been asked before, but I was unable to understand the differences in other people's code as it was much more complex. It's been a really difficult day trying to get this one method working without getting a NullPointerException and help would be appreciated! Thanks.
You want to remove a single node or part of the front list?
If you are trying to remove a single node, your current node is used as a pointer to find the node to be removed, when you find such node, you can change the node's value, if this is the last element, you can set the previous node's next node to null, else set the previous nodes' next node to the node's next node, and change the node's next node's previous node to the node's previous node.
public void remove(int data) {
if(length == 0) {
return;
}
if (head.data == data){
head = head.next;
length--;
}
Node current = head;
while (current != null) {
if (current.data != data) {
current = current.next;
} else {
if (current.next == null) {
current.pre.next = null;
} else {
current.pre.next = current.next;
current.next.pre = current.pre;
}
length--;
}
}
}
Try this:
public void remove(int data) {
if (isEmpty()) {
throw new NoSuchElementException();
}
if (this.size == 1 && this.head.getData() == data) {
this.head = this.tail = null;
this.size--;
return;
}
if (this.head.getData() == data) {
this.head = this.head.getNext();
this.head.setPrevious(null);
this.size--;
return;
}
if (this.tail.getData() == data) {
this.tail = this.tail.getPrevious();
this.tail.setNext(null);
this.size--;
return;
}
for (Node<T> current = this.head; current != null; current = current.getNext()) {
if (current.getData() == data) {
Node<T> previous = current.getPrevious();
Node<T> next = current.getNext();
previous.setNext(next);
next.setPrevious(previous);
this.size--;
return;
}
}
throw new NoSuchElementException();
}

Delete specific element from LinkedList....?

I am trying to delete an specific element from the linkedlist, however i am getting null pointer exception. Could any one pls fix my below mentioned code...
public void deleteElement(T num)
{
Node<T> ele = new Node<T>(num);
if(head == null){
System.out.println("Underflow");
return;
}
Node<T> temp = head;
while(temp != null)
{
if(temp.data == num){
temp.previous.next = temp.next;
return;
}
else
temp = temp.next;
}
size--;
}
You should modify inside your while loop like this:
while(temp != null)
{
if(temp.data == num) {
if(temp.previous != null) {
temp.previous.next = temp.next;
}
// you have to link-up the next's previous with temp's previous too
if(temp.next != null) {
temp.next.previous = temp.previous;
}
temp = null; // to deference the node and let garbage collector to delete/clear this node
break; // don't return here otherwise size-- won't execute
}
temp = temp.next;
}
Before referencing temp.next and temp.previous as lvalue you should check whether they are null otherwise it will throw NullPointerException.
Hope it helps!
You have to find Node object whose data is equal to T num. Use such loop:
for (Node<T> x = first; x != null; x = x.next) {
if (num.equals(x.data)) {
unlink(x);
return true;
}
}
Where first is pointer to first node. In method remove you have to unlink found Node x from linked list:
T remove(Node<T> x) {
// assert x != null;
final T element = x.data;
final Node<T> next = x.next;
final Node<T> prev = x.prev;
if (prev == null) {
//if x is first node(head)
first = next;
} else {
// link x.next to x.prev.next
prev.next = next;
//unlink x
x.prev = null;
}
if (next == null) {
//if x is last node(tail)
last = prev;
} else {
// link x.prev to x.next.prev
next.prev = prev;
//unlink x
x.next = null;
}
// reset data
x.data = null;
size--;
return element;
}

Method to remove nodes

I have a *, and I'm trying to get my remove method to removes and returns a specific targeted items. I tried a lot of different way trying to make it work, but it keeps giving me the NPE.
Here is my first remove():
Here is my second remove() that was able to make the code compile:
Here is my LinearNode:
Student class:
To remove should be fairly straightforward and you already have the general idea:
public Student remove(Student items) {
LinearNode previous = null,
current = head;
// iterate over all the nodes starting at the head, maintaining a reference to the previous node as you go
while (current != null && current.items.compareTo(items) != 0) {
previous = current;
current = current.next;
}
// At this point you have either a) found the Node with matching items or b) not found it
if (current == null) {
// not found in the list
return null;
}
// At this point you know where the Node is, and you have a reference previous node as well
// so it's easy to reattach the linked list to remove the node
if (previous == null) {
// The head node was the match if previous is not set, so make sure to update the head Node accordingly
head = current.next;
}
else {
previous.next = current.next
}
return current.items;
}
Use try catch on the suspicious code, till you find which line causing the problem.
This will tell you if you are looking at the right place.
For Example:
while (current != null) {
try{//1st level try
if(current.items.compareTo(items) == 0) {
try{ //2nd level try
if(previous == null) {
head = head.next;
return items;
}
else {
previous.next = current.next;
return items;
}
}catch(NullPointerException e ){
StackTraceElement t = e.getStackTrace()[0];
System.out.println("catch lvl 2 at line: " + t.getLineNumber());
}
}
else {
previous = current;
current = current.next;
}
}catch(NullPointerException e){
StackTraceElement t = e.getStackTrace()[0];
System.out.println("catch lvl 1 at line: " + t.getLineNumber());
}
}
EDIT:
You can try to put this "try catch" and wrap all your main function:
try{
...
}catch(NullPointerException e ){
int i=0
for( StackTraceElement t : e.getStackTrace()){
System.out.println("stack[" + i + "]: " + t.getLineNumber());
i++;
}
}
EDIT2
public Student remove(Integer studentId)
{
LinearNode previous = null;
LinearNode current = head;
while (current != null) {
//if everything is OK you can remove the 2 ifs
if(current.items == null){
//something is really wrong on insert
}
else if(current.items.getId() == null){
//something is really wrong on insert
}
else if( studentId.compareTo(curent.items.getId()) == 0) {
//return value is curent.items;
if(previous == null) {
head = head.next;
return curent.items;
}
else {
previous.next = current.next;
return curent.items;
}
}
else {
previous = current;
current = current.next;
}
}
//not found!
return null;
}

How could I re-write this java method with a while loop?

It's supposed to take the last element out of a pseudo-LinkedList. The instructions suggested using a while loop to find the next-to-last element.
public String removeFromEnd() {
String removed = null;
if (head == null) {
return removed;
} else if (head.getNext() == null) {
removed = head.getName();
head = null;
} else if (head.getNext().getNext() == null) {
removed = head.getNext().getName();
head.setNext(null);
}
return removed;
}
Past attempts usually look similar to this:
public String removeFromEnd() {
String removed = null;
while (head.getNext().getNext() == null){
removed = head.getNext().getName();
head.setNext(null);
}
if (head.getNext() == null){
removed = head.getName();
head = null;
}
return removed;
}
Node node = head;
Node prev = null;
while (node != null && node.getNext() != null) {
prev = node;
node = node.getNext();
}
In your attempt code...
while (head.getNext().getNext() == null){
removed = head.getNext().getName();
head.setNext(null);
}
You'll only enter this loop when head is already the second-to-last element. You want to loop until head is the second-to-last element. Does that help at all?
// Java Code
public String removeFromEnd() {
String removed = null;
Node prev = null;
Node node = head;
while(node != null && node.getNext() != null)
{
prev = node;
node = node.getNext();
}
//the while loop should move the node to the end of the list
if(node != null)
{
removed = node.getName();
node = prev;
node.getNext().removeNode();
node.setNext(null);
}
return removed;
}

Categories

Resources