javadata-structureslinked-listsingly-linked-list

Insert after specific element in LinkedList java


I was trying to write the function insertAfter to insert the element after specific element in the LinkedList . Below is the code. The insertAfter function is not producing the desired output. Can some one help me what mistake I have done in the below insertAfter function that I need to correct.

import java.util.Scanner;
import java.lang.Exception;
import java.lang.StringBuilder;
import java.util.ArrayList;
import java.util.*;
import java.util.regex.*;
import java.util.stream.Collectors;

class SingleLinkedList<T> 
{
    public class Node 
    {
        public T data;
        public Node nextNode;
    }
    
    public Node headNode;
    public int size;
    
    public SingleLinkedList()
    {
        headNode = null;
        size = 0;
    }
    
    public boolean isEmpty()
    {
        if (headNode == null)
        {
            return true;
        }
        return false;
    }
    
    public void insertAtHead(T data)
    {
        Node node = new Node();
        node.data = data;
        node.nextNode = headNode;
        headNode = node;
        size++;
    }
    
    public void insertAtEnd(T data)
    {
        if (isEmpty())
        {
            insertAtHead(data);
            return;
        }
        
        Node newNode = new Node();
        newNode.data = data;
        newNode.nextNode = null;
        
        Node last = headNode;
        while (last.nextNode != null)
        {
            last = last.nextNode;
        }
        
        last.nextNode = newNode;
        size++;
    }
    
    public void insertAfter(T data1, T data2)
    {
        if (isEmpty())
        {
            System.out.println("The list is empty");
            return;
        }
        
        Node insertNode = new Node();
        insertNode.data = data2;
        
        Node temp = headNode;
        while (temp.data != data1)
        {
            temp = temp.nextNode;
        }
        
        insertNode.nextNode = temp;
        temp = insertNode;
        size++;
        
        
    }
    
    public void printList()
    {
        if (isEmpty())
        {
            System.out.println("The list is empty.");
            return;
        }
        
        Node temp = headNode;
        System.out.println("List : ");
        while (temp.nextNode != null)
        {
            System.out.print(temp.data.toString() + "->");
            temp = temp.nextNode;
        }
        
        System.out.println(" null");
    }
}
  





public class Solution
{
  //static String originalString="AbcDef";
  
  
     
  
  
  // arguments are passed using the text field below this editor
  public static void main(String[] args)
  {
     SingleLinkedList<Integer> sll = new SingleLinkedList<>();
     sll.printList();
     for (int i = 0; i <= 10; i++)
     {
         sll.insertAtEnd(i);
         
         
     }

    sll.printList();    

     System.out.println("The size of the list is : " + sll.size);

     sll.insertAfter(3,72);
     
     sll.printList();

     System.out.println("The new size of the list is : " + sll.size); 
     
  
  }
}

In the insertAfter function I create a temp Node and assign the headNode address. Then I create a while loop and traverse the list until I reach the data element after which I need to insert and update the nextNode address in temp Node. Once the loop breaks I update the new Node next address to the temp Node and update the temp node address with the address of the new Node. It seems correct to me but code provides below output.

The list is empty.
List :
0->1->2->3->4->5->6->7->8->9-> null
The size of the list is : 11
List :
0->1->2->3->4->5->6->7->8->9-> null
The new size of the list is : 12


Solution

  • Your logic for insertAfter is not correct. Your while loop exits when it encounters a node with the same value as data1. Then, you need to point the new node to the next value of the node containing data1, and point the node containing data1 to the newly added node with the value of data2. Adding this would fix the bug.

    insertNode.nextNode = temp.nextNode;
    temp.nextNode = insertNode;
    

    The new output would be something like this:

    0->1->2->3->72->4->5->6->7->8->9-> null

    Just to answer your second query, yes you can implement insertBefore in a singly linked list using a pointer which points to the previous node in addition to the one pointing to the current node. Here's how it looks. Please note that error handling is omitted for simplicity's sake.

    public void insertBefore(T data1, T data2) {
            Node p = null;
            Node curr = headNode;
            while (curr.data != data1) {
                p = curr;
                curr = curr.nextNode;
            }
    
            Node insertNode = new Node();
            insertNode.data = data2;
            p.nextNode = insertNode;
            insertNode.nextNode = curr;
            size = size + 1;
        }