Why is new Node is not added? - java

public class LinkedList {
static Node head;
static class Node{
int data;
Node next;
Node(int dat){
data = dat;
next = null;
}
}
public void add(int data){
Node node = new Node(data);
Node n = head;
while (n!= null){
n = n.next;
}
n = node;
}
public void print(){
Node n = head;
while(n!=null){
System.out.println(n.data);
n = n.next;
}
}
}
I realize that in the add() method I am assigning 'node' to an item that has the value null, however, the doubt is even is n.next becomes null its still a node right because 'next' is defined as a Node, so it should work right.

To add the new node at the end of the linked list, you need to take following steps:
Create the new node
Check if linked list is empty. If it is, point the head to the new node and return from the function
If linked list is not empty, traverse the linked list until the last node is reached
Point the next of the last node to the new node created in step 1.
Problem
There are couple of problems in your code:
You are not handling the special case of adding the new node in the empty linked list
while loop in the add() method doesn't stops when the last node is reached. It only stops when n itself becomes null which means you cannot add the new node in the linked list
Solution
You need to change the condition in the while loop from
n != null
to
n.next != null
to make sure that you are at the last node in the linked list after the loop ends and then to add the new node in the linked list, you need to point the next of the last node to the new node
n.next = node;
Your add() method should be written as:
public void add(int data) {
Node node = new Node(data);
if (head == null) {
head = node;
return;
}
Node n = head;
while (n.next != null){
n = n.next;
}
n.next = node;
}

Related

Recursive code for reversing a linked list is not working properly

Here tail is a pointer to the last element of linked list.
This code only works when there are odd numbers of nodes in a linked list and shows wrong output for even number of nodes. Please help what is the problem in the code and reason why it is happening?
public static class Node
{
int data;
Node next;
}
public static class LinkedList
{
Node head;
Node tail;
int size;
// many other member functions
private void reversePRHelper(Node node , Node prev)
{
if(node == null)
{
return;
}
Node Next = node.next;
node.next = prev;
prev = node;
reversePRHelper(Next , prev);
Node temp = this.head;
this.head = this.tail;
this.tail = temp;
}
public void reversePR()
{
reversePRHelper(head,null);
}
}
The bug in your code is that these three lines:
Node temp = this.head;
this.head = this.tail;
this.tail = temp;
should only be executed once, at the end, and not for each recursive call. So if you move those three statements out of your reversePrHelper method and into your reversePR method, your code will work.
private void reversePRHelper(Node node , Node prev)
{
if(node != null)
{
return;
}
Node Next = node.next;
node.next = prev;
prev = node;
reversePRHelper(Next , prev);
}
public void reversePR()
{
reversePRHelper(head,null);
Node temp = this.head;
this.head = this.tail;
this.tail = temp;
}
For me it is unclear however why you keep the tail as an attribute, since you can't navigate anywhere from the tail, as it has no next value. It would be different if your nodes would keep a reference to the previous element as well, but then it would be a double linked list.

Can an object like node update itself without any need of giving it an updated value?

(In the insert method): In the else statement, I don't understand how "front.next" is getting updated with the line: "prev.next = newNode". Theoretically, I understand it, but practically, although "prev" gets its value from "curr", which got its value from "front" itself, there is no way that front is getting updated because "prev". How are they talking to each other?
(Insert method)I have tried debugging and when it reaches the else statement that executes => prev.next = newNode; front.next gets updated as well which I just don't understand since front is nowhere being initialised again. Front is an object of itself.
public class SinglyLinkedList<T>
{
// inner class being created:
protected class Node<T extends Comparable<T>>
{
T val;
Node<T> next;
Node(T val)
{
this.val = val;
this.next = null;
}
Node(T val, Node n)
{
this.val = val;
this.next = n;
}
}
private Node front, tail;
public SinglyLinkedList()
{
this.front = this.tail = null;
}
// print method:
public void print()
{
// print the contents of the list
Node curr = front;
while (curr != null)
{
System.out.println(curr.val + " ");
curr = curr.next;
}
}
// insert method:
public void insert(T val)
{
Node newNode = new Node((Comparable) val);
// make a new node
if (front == null)
{
// empty list
front = tail = newNode;
}
else
{
// list is not empty
Node curr = front, prev = null;
// look for insert point.
while (curr != null && curr.val.compareTo(val) < 0)
{
prev = curr;
curr = curr.next;
}
// insert node before curr
newNode.next = curr;
if (curr == front)
{
// update front
front = newNode;
}
else
{
// update node before
prev.next = newNode;
}
if (tail.next != null)
{
// move tail to last node
tail = tail.next;
}
}
}
}
I expected curr to keep continuing to fill in the chain of nodes using curr.next and using "prev" as a temporary node used in the process of adding a node in between two nodes.
I also didn't expect print method to work since it begins with front node. Theoretically, it does make sense to start with front node, but looking at my code how "front" is not equalling to any value, but rather "curr" equalling "front", makes me feel that "front" shouldn't be having the access to the rest chain of nodes.
I expected "front.next" to be null, but it isn't.
Well, according to your code, the front works as the first node of the linked list, it actually equals to a certain value (a real node) because your code set it to be so a
if (front == null)
{
// empty list
front = tail = newNode;
}
and
if (curr == front)
{
// update front
front = newNode;
}
See! You indeed pointed it to a certain node with a given value.
For the update question. I think possibly you are always inserting a new node right next to the front node. Under that circumstance, the prev points to the same node as the front do. So if you update prev, you are updating front, too!

error in deleting a node from singly linked circular linked list in Java

I am having some trouble in deleting a node fro a circular linked list specifically deleting the head node.I tried to debug the code and problem that i found out was that the head node is not getting updated after deletion.that means if my list is 1->2->3->1(the 1 at the end here is actually the repetition of head node 1 to show circular link list ) and after trying to delete '1' the list becomes 1->2->3->2...So basically the the head node is not getting updated and hence when I try to print this linked list it enters infinite loop as the head node is encountered only once and the stopping condition is nover met again. below is the code which I have written for deletion
public class cirlinklist {
private int data;
private cirlinklist next;
private cirlinklist head;
public cirlinklist()
{
data = 0;
next = this;
}
public cirlinklist(int val)
{
data = val;
next = this;
}
public void cirlist(int val)
{
cirlinklist node = new cirlinklist(val);
if(this.next == this) //only one node present
{
node.next = this;
this.next = node;
}
else
{
cirlinklist temp = this.next;
//cirlinklist head = this;
/*while(node != head)
node = node.next;*/
node.next = temp.next; //adding after the last added node.For adding before last added node change to temp here and temp.next in next line
this.next.next = node;
}
}
public void printlist()
{
//cirlinklist head = this; //start node
cirlinklist node = this; //node for traversing and printing
System.out.println("Circular Link list data is:");
do
{
System.out.println(node.data);
node = node.next;
}
while(node != head);
System.out.println(node.data);
}
public void check()
{
}
public cirlinklist delete(int val)
{
head = this;
cirlinklist node = head;
cirlinklist node2 = node;
if(head.data == val) //if the node to be deleted is head node
{
//this = this.next;
while(node.next != head) //iterate till the last node i.e. the node which is pointing to head
{
node = node.next;
}
node.next = node.next.next; // update current node pointer to next node of head
//node = node.next;
head = head.next; //update head node
/*this.next = head.next.next;
this.data = head.next.data;*/
return this;
}
else // if node to be deleted is other than head node
{
while(node.data != val) // find the node
{
node = node.next;
node2.next = node;
}
node2.next = node.next; //updating next field of previous node to next of current node.current node deleted
node = null;
return this;
}
}
public static void main(String [] args)
{
cirlinklist obj = new cirlinklist(1);
cirlinklist obj2 = new cirlinklist();
//obj.cirlist(1);
obj.cirlist(2);
obj.cirlist(3);
obj.printlist();
obj2 = obj.delete(1);
System.out.println("Circular list after deletion is");
obj2.printlist();
}
}
Please tell me where I am going wrong
if(head.data == val) //if the node to be deleted is head node
{
//this = this.next;
while(node.next != head) //iterate till the last node i.e. the node which is pointing to head
{
node = node.next;
}
node.next = node.next.next; // update current node pointer to next node of head
//node = node.next;
head = head.next; //update head node
}
In this code, where is the head pointing to after
node.next = node.next.next ?
may be the problem lies there.
Since your code has changed quite a bit since this answer was posted, I am starting fresh. I can solve your problem as it exists currently, but you do have some issues with your list design that I will mention and suggest you redesign what you have.
First, your print function is breaking because you don't have anything that sets head, which you are using to determine when to keep printing.
Modify your constructors to:
public cirlinklist()
{
data = 0;
next = this;
head = this;
}
public cirlinklist(int val)
{
data = val;
next = this;
head = this;
}
Second, your delete function needs to return head since that's what you're modifying in that function.
I've posted the cleaner function here:
public cirlinklist delete(int val)
{
cirlinklist node = head;
if(head.data == val) //if the node to be deleted is head node
{
//this = this.next;
while(node.next != head) //iterate till the last node i.e. the node which is pointing to head
{
node = node.next;
}
node.next = node.next.next; // update current node pointer to next node of head
//node = node.next;
head = head.next; //update head node
/*this.next = head.next.next;
this.data = head.next.data;*/
return this;
}
else // if node to be deleted is other than head node
{
cirlinklist prev = node; // track previous node from current (node)
while(node.data != val) // find the node
{
prev = node;
node = node.next;
}
prev.next = node.next; //updating next field of previous node to next of current node.current node deleted
return head;
}
}
This should get you what you want.
However, there is a problem that you're not yet seeing, in that if you try to return head and then hope it's a copy of the list, it's not. You're actually modifying the head list and then distributing it to some other method when it returns, meaning that cirlist obj2 = obj.delete(1); is not going to give you a new copy of the deleted list, leaving obj untouched. You can see this if you add another delete operation after this one and print.
That being said, I modified the function to react properly when deleting a node in the middle.
One other thing you might also want to test for, is removing the tail node, as you might experience problems with that case too.
The last thing I would suggest is you redefine your data structures. You're using the identifier node in this case to represent a list node, when in fact, as you've got them defined, are actually lists themselves. A linked-list as is typically defined, is a bunch of nodes linked together, the entire collection being the list.
If you create a data structure to represent the node, that is, it's an object that has a data element, and a pointer to the next node, your list can be in a different class entirely and you can operate on the nodes while preserving only a single copy of the list, that you can control and copy with greater ease.
Something like this:
public class ListNode {
public int data;
public ListNode next = null;
public ListNode() {
data = 0;
}
public ListNode(int data) {
this.data = data;
}
public ListNode(ListNode node) {
if ( node != null) {
this.data = node.data;
this.next = node.next;
}
}
}
Then you can have another class that actually provides the operations
public class CircularLinkedList {
public ListNode head;
public CircularLinkedList(...) {}
public void addToList(int data) {}
public void deleteFromList(int data) {}
... // and so-on
}
The head in this case, is your list, and any time you make changes or need to manipulate it, you can define functions that will do so in terms of head and then act appropriately.
Good luck to you

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.

Categories

Resources