I am practicing working with Linked List Nodes and have come upon a problem I don't know how to answer. How do you go about deleting the last node in a linked list. The code below works for all entry's bar the last node. The last does not get deleted.
Node Class
public class Node {
private String data;
private Node next;
Node(String data, Node next)
{
this.data = data;
this.next = next;
}
public void setData(String d)
{
data = d;
}
public void setNext(Node n)
{
next = n;
}
public String getData()
{
return data;
}
public Node getNext()
{
return next;
}
Main
Node list = new Node("NODE 1",new Node("NODE 2",new Node("NODE 3", null)));
list = insertSecond(list,"New Node");
list = addLast(list,"LAST NODE");
printList(list);
System.out.println();
deleteNode(list,"LAST NODE");
printList(list);
}
public static Node deleteNode(Node list,String str)
{
Node temp = list;
Node prev = list;
while(temp.getNext() != null)
{
if(temp.getData().equals(str))
{
if(prev.getNext() == null)
prev.setNext(null);
else{
prev.setNext(prev.getNext().getNext());
}
}
prev = temp;
temp = temp.getNext();
}
I would guess while(temp.getNext() != null) fails for your last element. The last element won't have a next element. So the last element is not compared against the passed string. You should trace this with the debugger.
while(temp != null){
prev = temp;
temp = temp.getNext();
}
prev.next = null;
Try this:
It's easiest if you use a doubly-linked List, where your list knows both start and end.
Then you can just do something like this:
public void removeLastItem(){
this.lastNode = this.lastNode.prev;
}
This is very simple technique that I used to delete the last Node.
public void deleteLast() {
Node curr = null;
for (curr = this.first; curr.next.next != null;curr = curr.next) {
}
curr.next = null;
}
You need something like this:
public static Node deleteNode(Node list, String str) {
Node temp = list;
Node prev = list;
do {
if (temp.getData().equals(str)) {
if (prev.getNext() == null) {
prev.setNext(null);
} else {
prev.setNext(prev.getNext().getNext());
}
}
prev = temp;
temp = temp.getNext();
} while (temp != null);
return list;
}
You were stopping your loop too early.
BTW: if (prev.getNext() == null) { prev.setNext(null); ... doesn't make sense but I'll leave that bug to you.
Deleting a node in a singly linked list
Assumptions
- Each node in the list has a
nextNodepointer. - The
headOfListpointer points to the first node in the list. - The next pointer of each node, that is already in the list, is correct.
- The next pointer of the last node in the list is some meaningful value (for instance, null).
Steps to implement
- If the list is empty, done. Desired node not found.
- If the first node is the desired node, set the
headOfListpointer to theheadOfList->nextNodevalue. Done. Desired node found. - Set the
currentNodepointer equal to theheadOfListpointer value. - If the
currentNodenode is the last node. Done. Desired node not found. - If the
currentNode->nextNodenode is the desired node, set thecurrentNode->nextNodeto thecurrentNode->nextNode->nextNodevalue. Done. Desired node found. - goto step 4.
Notes
Since this is a singly linked list, you can not back up. Because of this, you need to point to the node parent and check to see if the the node child is the node that you wish to delete. There will be boundry conditions.
Some code
This is a member function of a LinkedList class. startOfList is a class member and points to the start of the linked list.
public boolean delete(final String target)
{
if (startOfList != null)
{
if (StringUtils.equals(startOfList.getData(), target))
{
startOfList = startOfList.getNext();
return true;
}
Node current = startOfList;
for (Node next = current.getNext(); next != null; next = current.getNext())
{
if (StringUtils.equals(next.getData(), target))
{
current.setNext(next.getNext());
return true;
}
else // advance one node.
{
current = next;
}
}
}
return false;
}
This is my attempt at it with assumption that last node's next variable will always be null:
public class LastNodeRemoval {
private static class Node {
String item;
Node next;
}
public static void main(String[] args) {
Node third = new Node();
third.item = "Third";
Node second = new Node();
second.item = "Second";
second.next = third;
Node first = new Node();
first.item = "First";
first.next = second;
removalLastNode(first);
}
private static void removalLastNode(Node first) {
Node temp = first;
while(temp.next.next != null) {
temp = temp.next;
}
temp.next = null;
System.out.println("Last node: "+temp.item);
}
}
This can be done in a much simpler way by using the Java container class "LinkedList". The class LinkedList in Java implements the Deque (Double ended queue) interface which supports get/add/remove First/Last methods. An elementary code snippet follows:
LinkedList<Integer> list = new LinkedList<Integer>();
list.addFirst(1);
list.addLast(2);
System.out.println(list.removeLast());
This one worked for me..
public void removeLastNode(){
System.out.println("\n Inside removeLastNode");
next=firstLink;
prev=firstLink;
if(next == null) System.out.println("\n The link List is Empty");
while(next.getNext()!=null) {
prev=next;
next=next.getNext();
}
prev.setNext(null);
}
The logic is simple here and it is the same as getting the last node. The tricky thing here is to when you reach the last node, you will have to remember the node before the last and set it to null so that it will be the new last node. In the code below when you reach the last element which will be n2 get n1 and set it to null.
public void removeLast(){
if(head==null) System.out.println("List is empty");
else {
Node n1 = null;
Node n2 = head;
while(n2.next != null)
{
n1 = n2;
n2 = n2.next;
}
n1.next = null;
}
public Node deleteEnd(Node node)
{
if(node==null)
{
throw new IllegalStateException();
}
if(node.getNext()==null)
return null;
Node headF=node;
while (node.getNext().getNext()!=null)
{
node=node.getNext();
}
node.setNext(null);
return headF;
}
Given the following singly linked list implementation the last node can be removed using removeLast() or removeLastRecursive() methods that are traversing the list starting form the first node:
public class LinkedList<T> {
Node<T> first;
Node<T> last;
int length;
public LinkedList() {
}
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList();
linkedList.add("A");
linkedList.add("B");
linkedList.add("C");
linkedList.add("D");
linkedList.printListParams();
linkedList.removeLast();
linkedList.printListParams();
linkedList.removeLast();
linkedList.printListParams();
linkedList.removeLast();
linkedList.printListParams();
linkedList.removeLast();
linkedList.printListParams();
linkedList.removeLast();
linkedList.printListParams();
}
public void add(T data) {
if (isEmpty()) {
first = new Node(data);
last = first;
} else {
last.next = new Node(data);
last = last.next;
}
length++;
}
public void removeLast() {
Node current = first;
if (isEmpty()) return;
if (current.next != null) {
while (current.next != null) {
if (current.next.next == null) {
current.next = null;
last = current;
length--;
return;
}
current = current.next;
}
} else {
first = null;
last = null;
length--;
}
}
public void removeLastRecursive() {
if (isEmpty()) return;
if (first.next != null) {
removeLast(first);
} else {
first = null;
last = null;
length--;
}
}
private void removeLast(Node node) {
if (node.next.next != null) {
removeLast(node.next);
} else {
node.next = null;
last = node;
length--;
return;
}
}
public boolean isEmpty() {
return first == null;
}
public void printList() {
Node current = first;
while (current != null) {
System.out.print(current.data);
current = current.next;
}
System.out.println();
}
public void printListParams() {
printList();
System.out.println("Length: " + length);
System.out.println("Last node data: " + ((last != null) ? last.data : last));
System.out.println("***********************");
}
private class Node<T> {
T data;
Node next;
public Node(T data) {
this.data = data;
}
}
}
/**
* Deletion From End
*/
public static LinkedList DeletionFromEnd(LinkedList list){
Node currNode = list.head;
Node prevNode = null;
while( currNode.getNext() != null) {
prevNode = currNode;
currNode = currNode.getNext();
}
prevNode.setNext(null);
return list;
}
来源:https://stackoverflow.com/questions/15792682/delete-last-node-of-a-linked-list