How to insert a node arbitrary in a liked list? - java

I'm about to implement a function that is able to insert a node in a linked list arbitrary . The Code below works properly for inserting a node at the first of the list but for putting a node after another node it doesn't work . I honestly can't figure out that what's the matter with this code. Also when I'm tracing the code I can't find out my mistake.please don't ban me and help me solve this matter . Thanks in advance.
Class Node Comes :
public class Node {
Object Element;
Node Link;
public Node() {
this(null,null);
}
public Node(Object Element, Node Link) {
this.Element = Element;
this.Link = Link;
}
}
Class List :
public class List {
Node FirstNode;
Scanner UserInfo = new Scanner(System.in);
Scanner UserInput = new Scanner(System.in);
public List() {
FirstNode = null;
}
public void InsertArbitrary() {
int Location = UserInput.nextInt(); // Location of new node
if (Location == 1) {
Object Element = UserInfo.nextLine();
FirstNode = new Node(Element, FirstNode); // locates a New Node At First
} else {
Object Element = UserInfo.nextLine(); // Content of new node
Node CurrentNode ; // for searching in the list
CurrentNode = FirstNode;
for (int i = 1; i <= Location - 1; i++)
CurrentNode = CurrentNode.Link;
Node NewNode = new Node (Element , CurrentNode);
}
}
}

Once you've iterated to the location for insertion, you properly create a new node and assign it's link to the next element. But what you're not doing is updating the previous link to POINT TO your new node, so the tail of your list is not longer reachable from the head node.
You must do something like this (untested):
Node FirstNode;
int Length = 0;
public List() {
FirstNode = null;
}
public void InsertArbitrary(int Location, Object Element) {
if (Location == 1 || Length == 0) {
FirstNode = new Node(Element, FirstNode); // locates a New Node At First
Length++;
} else {
Node CurrentNode ; // for searching in the list
CurrentNode = FirstNode;
for (int i = 1; i <= Location - 2 && i < Length; i++)
CurrentNode = CurrentNode.Link;
Node NewNode = new Node (Element , CurrentNode.Link);
CurrentNode.Link = NewNode;
Length++;
}
}

The problem is you're not updating the reference to the next node.
Without giving you the code (because this is homework), given you want to insert a new node X after A, in pseudo code:
x.next = a.next
a.next = x
So the chain fragment changes from a -> b to a -> x -> b

Related

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
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;
}
If you want to insert after the data1 your error is here(insertAfter method):
insertNode.nextNode = temp;
temp = insertNode;
So this is the right code:
Node next = temp.nextNode;
temp.nextNode = insertNode;
insertNode.nextNode = next;

Object is getting updated without that object reference?

//I have a Node.java Class
public class Node{
int data;
Node next;
public Node(int d) {
data = d;
}
}
//And another java class
class LinkedList {
Node head;
public static void main(String[] args) {
LinkedList list = new LinkedList();
//Executing this loop
for (int i = 0; i < 5; i++) {
**list.add(i);**
}
}
void add(int value){
Node newNode = new Node(value);
if(head == null )//Very first time its create the head object when i = 0
{
head = newNode;
}else if(head.next == null){//This is for when i value is 1
head.next = newNode;
}else{ //else part execute i >= 2
//Created new node with head.next which mean value 1.And head is 0
Node temp = head.next;
// Just need this object initialization for reference
Node temp1 = newNode;
//Checking head.next is null or not if its null skip this loop execution
while(temp != null)
{
temp1 = temp;
temp = temp.next;
}
// Here we set newNode.next to null
newNode.next = temp1.next;
temp1.next = newNode;
}
}
}
My Question is here , when temp1.next = newNode; line execute head object have added
one next value.
**
//For example if head = 0,head.next = 1 when temp1.next = newNode; line execute head.next.next = 2 is getting added with head. How its happening when we do not have head object reference.
You are not updating the head object.
You are updating the head.next object.
So
head.next.next
can be written like this:
Node nextFromHead = head.next; // nextFromHead is 1
Node nextFromNextFromHead = nextFromHead.next; // nextFromNextFromHead is 2
head.next.next is the same object as nextFromNextFromHead but it ( the Node that is 2 ) doesn't have any direct connection to the head node.
I think this will help better understand how references work in java.
public class LinkedList {
static Node head;
public static void main(String[] args) {
LinkedList list = new LinkedList();
for(int i = 0; i < 5; i++)
list.add(i);
Node currentNode = head; // in java we don't need object initialization for reference. Node temp1; would work just fine
System.out.println("==head node== " + currentNode);
while(currentNode.next != null) {
// here we increment
currentNode = currentNode.next;
// System.out.println("Last time we in here, next is null so print only current");
System.out.println("==next node== " + currentNode);
}
}
void add(int value){
Node newNode = new Node(value);
if(head == null )//Very first time its create the head object when i = 0
{
head = newNode;
}else if(head.next == null){//This is for when i value is 1
head.next = newNode;
}else{ //else part execute i >= 2
//Created new node with head.next which mean value 1.And head is 0
Node temp = head.next;
// Just need this object initialization for reference
Node temp1 = newNode;
//Checking head.next is null or not if its null skip this loop execution
while(temp != null)
{
temp1 = temp;
temp = temp.next;
}
// Here we set newNode.next to null
System.out.println(" ==temp1== " + temp1);// before
newNode.next = temp1.next;
temp1.next = newNode;
System.out.println(" ==temp1== " + temp1);// and after
}
System.out.println("==current node== " + head);
System.out.println();
}
}
And the Node class with an additional toString() for properly viewing the objects.
public class Node {
int data;
Node next;
public Node(int d) {
data = d;
}
#Override
public String toString() {
return "Node{" +
"data=" + data +
", next=" + next +
'}';
}
}
"You" do have the head element.
Have a look at your code: your LinkedList class has a field head; and whenever you call the add() method of your list; that field is accessible by that method.
So, adding works like this:
If the head is not set, a new one is created
If the head is set, but has no "next", then that next node is created and linked to head
If the head is set, and his "next", then you keep retrieving the "next" next ... until you find one the last one; which doesn't have a next (yet) ...
That is all there is to understand. Or lets try some non IT-example.
Assume you some hook and short ropes; and you want to build a "list of ropes".
No list yet. You take the first rope and attach it to the hook.
The first rope, your head, is there. You add another rope, by connecting it to the end of the first one (probably making a knot)
Adding another rope ... you start at the hook, and you keep following the ropes/knots ... until you have a loose end.
Hope that helps.

How do I change a singly-linked list to a doubly-linked list?

I'm currently taking a Java class and the professor told us that a good practice to understand links would be to make a doubly linked list. I have made a singly linked list but I am having trouble converting it to a doubly linked list. So I was wondering if anybody could give me any suggestions on making sure my last number is connected to the previous one? And if the front number and last number connected to the null. Here is part of the code, if you wish for more of it just ask and I shall post.
The code for adding elements and such. This is my attempt of trying to make the tail which is the end connect to the last number.
public void add(int element){
Node n = new Node();
n.setItem(element);
n.setNext(head);
head = n;
>
//The tail connected to the new number added.
n.setItem(element);
n.setBefore(tail);
tail = n;
The code below is the insert function which I need to make sure the new inserted blocks connect but I'm having troubles thinking of a way to make it connect for both.
public void insert(int element, int position){
int currentposition = 0;
Node currentNode = head;
//Traverse to the right position
while(currentposition < position-1){
currentposition++;
}
Node n = new Node();
n.setItem(element);
n.setNext(currentNode.getNext());
currentNode.setNext(n);
//The previous number connecting to the new number
currentNode = tail;
}
You add an extra Node field to each Node that holds its previous Node
Insertion Pseudocode:
insert(Node n, index i) {
currentIndex = 0
currentNode = head
while (currentIndex < i) {
currentNode = currentNode.next
currentIndex++
}
n.prev = currentNode
n.next = currentNode.next
currentNode.next = n
}
For doubly linked list, you need to add both head and tail fields in the class so that it maintains a doubly linked data structure.
private Node<T> head = null;
private Node<T> tail = head;
private int size = 0;
To add a new node to the end of the linked list, you can do
public void add(T element) {
Node<T> node = new Node<T>(element);
Node<T> current = head;
if(current == null) {
current = node;
head = tail = current;
} else {
tail.next = node;
node.prev = tail;
tail = node;
}
size++;
}
Note that you also need to deal with the empty list case which is the first if clause. Also you can set next and prev references for tail when you add the node.
To insert a node to the list at a certain position, you need to consider that if the specified position is less than 0 or great than the existing list size, then error occurs because you can't insert element with out of bound index. So you can throw exception. Also you need to separate the case when the inserted position is at 0 (head) or at size (tail). Considering all these cases, the solution is:
public void insert(T a, int position) {
if (position < 0 || position > size)
throw new IndexOutOfBoundsException();
Node<T> node = new Node<T>(a);
Node<T> temp;
if(position == 0) {
if(head == null)
add(a);
else {
temp = head;
head = node;
node.next = temp;
temp.prev = node;
}
return;
} else if (position == size) {
temp = tail;
tail = node;
temp.next = tail;
tail.prev = temp;
return;
}
Node<T> current = head;
int i = 0;
while (current != null && i < position-1) {
current = current.next;
i++;
}
temp = current.next;
current.next = node;
node.prev = current;
node.next = temp;
temp.prev = node;
}

Delete a last node of linked list given pointer to that node

I'm trying to delete the last node of the linkedlist, given pointer only to that node.
I wrote the below implementation, but isn't working.
I already visited majority of SO questions regarding this subject, but none of them shows how to delete last node of linked list, if there's only one pointer to that node ?
Am I missing anything here ?
class Node {
Node next;
int value;
Node(int val) {
this.value = val;
this.next = null;
}
#Override
public String toString() {
Node cur = this;
String str = "";
while(cur != null) {
str += cur.value+"->";
cur = cur.next;
}
return str;
}
}
class DeleteNodeLL {
public static void deleteNode(Node current) {
Node temp;
if(current.next == null) {
current = null;
return;
} else {
current.value = current.next.value;
temp = current.next;
temp = null;
current.next = current.next.next;
}
}
public static void main(String [] args) {
Node n1 = new Node(25);
Node n2 = new Node(1);
Node n3 = new Node(36);
Node n4 = new Node(9);
Node n5 = new Node(14);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = null;
System.out.println("Original linkedlist :");
System.out.println(n1);
System.out.println();
System.out.println("After deleting a node :");
deleteNode(n5);
System.out.println(n1);
}
}
Output :-
Original linkedlist :
25->1->36->9->14->
After deleting a node :
25->1->36->9->14->
With the singly linked list it is not possible.
This is the interview questions which is typically asked in Big Shot companies which emphasizes on Data Structures.
The question is formulated as "Delete the node in single linked list given pointer to only that node"
Expected Solution:
public void deleteNode(Node n)
{
if(n==null || n.next==null)
{
System.out.println("Delete not possible");
return;
}
n.data = n.next.data;
Node tmp = n.next;
n.next = n.next.next;
tmp.next = null;
System.out.println("Node Deleted");
}
The idea is to copy the data from the next node to the current node and delete the next node. The solution does not work if the node is the last node (This is what candidate has to debate and point out in interview)
Hope it helps you! (Solution to your problem is a trick question, and it does not exists)
current = null; doesn't do what you expect - it only sets local variable (method argument) to null.
What you want is impossible with your current implementation of the Node class.
You need either a reference to the previous node inside the Node class (i.e. a doubly-linked list) or you have to provide a reference to some previous node to the deleteNode method.
I would say
You can delete the last node from the Linked List if reference of
it's previous node is given.
However it's based on how you implement the list.
For your implementation, you can't do that
The only solution to this question is to iterate over the complete list keeping the prev node pointer everytime, compare the current node with the present node. When the comparison passes, delete the last node, and point the prev node to null. Something like the code below(note: I did not compile it)
deleteNode(Node *node){
if(node){
currentNode = Head, prevNode = NULL;
while(currentNode != node){
prevNode = currentNode;
currentNode = currentNode -> next;
}
delete currentNode;
prevNode -> next = NULL;
}
}
#asifsid88 copied and pasted the solutions from "cracking the coding", you should refer to that book to find more interesting and challenging questions.

Single linked list in java

In the following code, I am trying to understand one thing in the insertFirst() method that
Why is the last statement first =newLink; and not first.next=new Link;
Will it be wrong? Isn't there a "next" in first?
I know this code is right and I know that a node needs to be inserted at the beginning and all, but I need help understanding just one statement.
Is first =newLink; and first.next=new Link; not the same thing?
public class LinkedList {
private Link first;
public LinkedList()
{
first = null;
}
public boolean isEmtpy()
{
return(first==null);
}
public void insertFirst(int id, int dd)
{
Link newLink=new Link(id,dd);
newLink.next=first;
first =newLink;
}
}
No, it's right: the list inserts new links at the beginning. The old "first" becomes the new link's "next", and the new link is the new "first".
Why is the last statement first =newLink; and not first.next=new Link;
Because you're inserting a new first element and the "next" element is the old first element, which was set on the previous line.
Is first =newLink; and first.next=new Link; not the same thing?
No. first is the first and first.next is the second.
This is because you want to put new element to the beginning, so you must set new element to the head of list and this element should point on "old-head", and then you have:
new_elemnt->old_head->...
LinkedList::first is not a guard element. It really points to the first element of the list. If LinkedList::first == null, then the list is empty. If Link::next == null, then it's the last element (the null is called a guard element in this case).
Simple example of SingleLinkedList in Java
package com.ds;
public class SingleLinkedList {
private Node head;
public static void main(String[] args) {
SingleLinkedList linkedList = new SingleLinkedList();
linkedList.insert(5);
linkedList.insert(15);
linkedList.insert(45);
linkedList.insert(55);
linkedList.insert(58);
linkedList.insert(25);
// Print value of Single Linked list.
linkedList.print();
// delete node from tail side.
linkedList.delete();
linkedList.delete();
linkedList.delete();
linkedList.delete();
linkedList.delete();
/*linkedList.delete();
linkedList.delete();
linkedList.delete();
linkedList.delete();*/
linkedList.print();
}
SingleLinkedList() {
head = null;
}
void insert(int val) {
Node temp = new Node();
temp.data = val;
temp.next = null;
if (head == null) {
head = temp;
} else {
Node k = head;
while (k.next != null) {
k = k.next;
}
k.next = temp;
}
}
// delete from tail.
void delete() {
// if it's first node
if (head == null || head.next == null) {
head = null;
} else {
Node n = head;
Node t = head;
while (n.next != null) {
t = n;
n = n.next;
}
t.next = null;
}
}
void print() {
Node k = head;
while (k != null) {
System.out.println(k.data);
k = k.next;
}
}
Node reverse() {
Node h = head;
Node p = null;
Node t = null;
while (h != null) {
t = h.next;
h.next = p;
p = h;
h = t;
}
return p;
}
class Node {
private int data;
private Node next;
}
}

Categories

Resources