Adding nodes to end of linked list - java

Having trouble adding nodes to the end of a linked
The code is pretty self explanatory, the addToEnd method adds a single node to the end of a linkedlist.
public class ll5 {
// Private inner class Node
private class Node{
int data;
Node link;
public Node(int x, Node p){
data = x;
link = p;
}
}
// End of Node class
public Node head;
public ll5(){
head = null;
}
public void addToEnd(int data) {
Node p = head;
while (p.link != null)
p=p.link;
p.link=new Node(data, null);
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ll5 list = new ll5();
list.printList();
System.out.println("How many values do you want to add to the list");
int toAdd = input.nextInt();
for(int i = 0; i < toAdd; i++) {
System.out.println("Enter value " + (i + 1));
list.addToEnd(input.nextInt());
}
System.out.println("The list is:");
list.printList();
input.close();
}
}
Why is it giving me an NullPointerException error?? The error is somewhere in the while loop in the addToEnd method.

You haven't handled the initial condition when list has nothing and head is null. Because of that you're getting NPE.
Following method should work.
public void addToEnd(int data) {
Node p = head;
if( p == null) {
head = new Node(data, null);
} else {
while (p.link != null)
p=p.link;
p.link=new Node(data, null);
}
}

That's because the head is null at the beginning
public ll5(){
head = null; // <-- head is null
}
public void addToEnd(int data) {
Node p = head; //<-- you assigned head, which is null, to p
while (p.link != null) //<-- p is null, p.link causes NullException
p=p.link;
p.link=new Node(data, null);
}

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;

I have a problem in the reference of my 'head' node in my own LinkedList Class

I had written my own Linked Class Codes with Node first and last, since there exists a Node last, I encountered problems regarding reference and pointer manipulations when I tried to manually created the LinkedList in the main method and test it.
I am quite familiar with the recursion implemented in the "addFirst" "addLast" and "remove" methods, but now somehow the reference to the Node first becomes null after addFirst Method.
public class LinkedList<T> {
Node first,last,temp;
public class Node{
T value;
Node next;
public Node(T value, Node next) {
this.value = value;
this.next = next;
}
public String toString(){
if(next == null){
return value.toString();
}
else{
return value.toString() + " " + next.toString();
}
}
public T getLL(int index){
if(index == 0){
return value;
}
if(next == null){
throw new
IndexOutOfBoundsException("have reached the end of the list, none found");
}
return next.getLL(index-1);
}
public T removeLL(int x){
if(x == 1){
T value = next.value;
next = next.next;
return value;
}
else if(next == null){
throw new
IndexOutOfBoundsException("have reached the end of the list, none found");
}
else{
return next.removeLL(x-1);
}
}
}
public LinkedList(T value) {
temp = new Node(value,null);
first = new Node(value,null);
last = temp;
}
public static void main(String[] args) {
/**
* [120,110,100,90,80];
*/
LinkedList L = new LinkedList(100);
L.addFirst(110);
L.addFirst(120);
L.addLast(90);
L.addLast(80);
System.out.println(L.size());
System.out.println(L.remove(0));
System.out.println(L.last.toString());
//return null which causes the remove method not to work.
System.out.println(L.first);
}
public void addFirst(T value){
first = new Node(value,first);
}
public void addLast(T value){
Node p = first;
if( p == null){
first = last = new Node(value,null);
}
while(p.next!= null){
p = p.next;
}
last.next = new Node(value,null);
last = new Node(value,null);
}
public T get(int index){
if(first == null){
throw new IndexOutOfBoundsException("empty list");
}
return first.getLL(index);
}
public int size(){
int c = 0;
while(first != null){
first = first.next;
c++;
}
return c;
}
public T remove(int x){
if(first == null){
throw new IndexOutOfBoundsException("Tried to remove from empty list");
}
if (x == 0) {
T value = first.value;
first = first.next;
return value;
}
return first.removeLL(x);
}
}
I expected that the Node first pointed to the first element of the LinkedList instead of pointing to null. Meanwhile, this won't affect the pointer of Node last.
Looks like the problem inside the AddLast function. You braking the list.
Shouldn't it be like this?
public void addLast(T value){
Node p = first;
if( p == null){
first = last = new Node(value,null);
}
while(p.next!= null){
p = p.next;
}
p.next = new Node(value,null);
last = p.next;
//last = new Node(value,null);
}
Update Regarding your comment and updated answer.
Your size function is wrong:
public int size(){
int c = 0;
while(first != null){
first = first.next; // <-- now first point to the last and length is 1
c++;
}
return c;
}
When you remove the first element first is null. You have to create temporary variable to traverse your list. To check this comment the line where you calculate size.
Your are actually not quite right last.next = new Node(value,null); point to the new node. But instead of connecting again last = last.next your new node is gone because you create your new node for the last but last.next pointed to new node and hence last is not last anymore. (I think your understood what I meant)

Linked list is only displaying the head node, not sure why

I am doing a linked list project for my class at school. Essentially we are supposed to make a linked list from scratch, and have add, delete, and find commands. No matter how hard I've been trying I cannot seem to get the list to display anything other than the head node. here are my classes starting from node
public class main {
public static void main(String args[]) {
for (int i = 0; i < 3; i++) {
LinkedList list = new LinkedList();
Node focus = new Node();
String start;
start = JOptionPane.showInputDialog("Enter 'A' to add an item"
+ "\n" + "Enter 'D' to delete an item\nEnter 'F' to find an item.");
if (start.equals("a") || start.equals("A")) {
focus.data = JOptionPane.showInputDialog("enter an item to ADD");
list.Add(focus);
while (focus != null) {
focus = list.head;
focus = focus.next;
JOptionPane.showMessageDialog(null, "your list is\n" + focus.getData());
}
}
}
}
}
public class Node {
String data;
Node next;
Node prev;
public Node(String data, Node next) {
this.data = data;
this.next = next;
}
Node() {
}
public void setData(String data) {
this.data = data;
}
public String getData() {
return this.data;
}
public void setNext(Node next) {//setnext
this.next = next;
}
public Node getNext() {
return next;
}
}
public class LinkedList extends Node {
Node head;
int listcount = 0;
public LinkedList() {
this.prev = null;
this.next = null;
this.listcount = 0;
}
LinkedList(Node Set) {
}
public void Add(Node n) {
Node current = this.prev;
if (current != null) {
current = this.prev;
this.prev = new Node();
} else {
head = this.prev = new Node();
current = head;
}
listcount++;
}
}
I think my biggest problem is the "your list is" part. I can't seem to get it to display anything other than the head node. I would really appreciate the help, as this has been giving me a huge headache. :)
First of all, why does your LinkedList extends the Node class? It's a linked list not a node. There's nothing coming before and after the linked list. So the linked list has no prev and next. All the elements are added in the list and the elements are inserted after the head node. The head of the node has a prev and a next. In the Add method, if the head of the list is null (i.e, the list is empty), the new element becomes the head of the list. Otherwise, the new node is inserted after the head.
public class LinkedList {
Node head;
int listcount = 0;
public LinkedList() {
this.head = null;
this.listcount = 0;
}
public void Add(Node n) {
Node current = this.head;
if (current == null) {
head = n;
} else {
Node prev = null;
while (current != null) {
prev = current;
current = current.next;
}
prev.next = n;
}
listcount++;
}
public String toString() {
StringBuilder builder = new StringBuilder();
Node current = this.head;
while (current != null) {
builder.append(current.data).append(", ");
current = current.next;
}
return builder.toString();
}
}
I added a toString method which loops over the list and builds a string with the content from each node.
In the main method there are a few problems. The linked list is initialised only once not every time you select a choice. If you initialise the linked list every time you select something, then the linked list will always be reinitialised and the only node that will contain will be the head node after you add the new element.
public class main {
public static void main(String args[]) {
String start;
boolean finished=false;
LinkedList list = new LinkedList();
while(!finished) {
start = JOptionPane.showInputDialog("Enter 'A' to add an item"
+ "\n" + "Enter 'D' to delete an item\nEnter 'F' to find an item.");
if (start.equals("a") || start.equals("A")) {
Node focus = new Node();
focus.data = JOptionPane.showInputDialog("enter an item to ADD");
list.Add(focus);
JOptionPane.showMessageDialog(null, "your list is\n" + list.toString());
}
else {
finished = true;
}
}
}
}
Try to go over the code and understand what is happening and why. Also use pencil and paper to understand the logic.

Method utilising linked list not working

The display method is my program is not displaying anything at all.
The program has to have someone entire names into a circular linked list, then backup the linked list into another circular linked list.
Then it user must delete names until 1 is left, and the display the winner along with the list of original names, using the backup in the order that they were entered
import java.io.*;
import java.util.*;
import java.text.*;
public class Linkedlist
{
static public class Node
{
Node prev, next;
String data;
}
public static void delete (Node tail) throws IOException
{
BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));
System.out.println ("Please input a name to be deleted");
String tobedeleted = stdin.readLine ();
Node delete = tail;
while (delete.prev != null)
{
if (delete.data.equals (tobedeleted))
{
String temp = delete.data;
delete.data = tail.data;
tail.data = temp;
tail = tail.prev;
}
delete = delete.prev;
}
}
public static String findvictor (Node tail) throws IOException
{
int size = 0;
for (Node n = tail ; n.prev != null ; n = n.prev)
{
size++;
}
if (size == 1)
{
return tail.data;
}
else
{
delete (tail);
return findvictor (tail.prev);
}
}
public static void backup (Node tail, Node backuptail)
{
Node tobebackuped = tail;
Node backuphead = null;
Node backup = new Node ();
backuptail = backup;
while (tobebackuped.prev != null)
{
backup.data = tobebackuped.data;
backuphead = backup;
backup = new Node ();
backup.next = backuphead;
backuphead.prev = backup;
tobebackuped = tobebackuped.prev;
}
}
public static void display (Node tail, Node backuptail) throws IOException
{
System.out.println ("CONGRATULATIONS, " + findvictor (tail) + ", YOU ARE THE WINNER!");
System.out.println ("");
System.out.println ("This is a list of all the contestants:");
Node current = backuptail;
while (current.prev != null)
{
System.out.println (current.data);
current = current.prev;
}
}
public static void main (String[] args) throws IOException
{
BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));
Node head = null;
Node node = new Node ();
Node tail = node;
while (true)
{
String str = stdin.readLine ();
if (!str.equals ("fin"))
{
node.data = str;
head = node;
node = new Node ();
node.next = head;
head.prev = node;
}
else
{
break;
}
}
Node backuptail = null;
backup (tail, backuptail);
display (tail, backuptail);
}
}
You've fallen into a simple trap in Java. You've passed a value that you want to update into a function, and expected the value to be updated in the calling method. Right here:
Node backuptail = null;
backup (tail, backuptail);
display (tail, backuptail);
Here's what's happening: Java is passing your pointer by value. That means it's creating a copy of your pointer (backuptail) for use within the method backup(). That means your local variable in main() never gets updated.
The fix is simple. Change your backup method to return the value instead:
public static Node backup (Node tail)
{
Node tobebackuped = tail;
Node backuphead = null;
Node backup = new Node ();
Node backuptail = backup;
while (tobebackuped.prev != null)
{
backup.data = tobebackuped.data;
backuphead = backup;
backup = new Node ();
backup.next = backuphead;
backuphead.prev = backup;
tobebackuped = tobebackuped.prev;
}
return backuptail;
}
Then change your method calls apropriately:
Node backuptail = backup (tail);
display (tail, backuptail);
Now the resulting backup pointer is stored locally within your main, and can be passed to display().

null pointer exception in my bubblesort, and other sort methods

I have a project where I have to write a bunch of sort methods and measure the time complexity for each, and output the results to an output text file. the program runs but i get some null pointer exceptions in bubblesort method. here is my code and error, if you can tell me how to fix my sort methods, that would be awesome!
linked list class:
public class LinkedList {
protected static class Node {
Comparable item;
Node prev, next;
public Node(Comparable newItem, Node prev, Node next) {
this.item = newItem;
this.prev = prev;
this.next = next;
}
public Node (Comparable newItem) {
this(newItem, null, null);
}
public Node() {
this(null, null, null);
}
public String toString() {
return String.valueOf(item);
}
}
private Node head;
private int size;
public int dataCompares, dataAssigns;
public int loopCompares, loopAssigns;
public int other;
public LinkedList() {
head = new Node(null, null, null);
head.prev = head;
head.next = head;
size = 0;
}
public boolean add(Comparable newItem) {
Node newNode = new Node(newItem);
Node curr;
if(isEmpty()) {
head.next = newNode;
head.prev = newNode;
newNode.next = head;
newNode.prev = head;
} else {
newNode.next = head;
newNode.prev = head.prev;
head.prev.next = newNode;
head.prev = newNode;
}
size++;
return false;
}
public boolean remove(Comparable item) {
if(!isEmpty()) {
Node prev = null;
Node curr = head;
while(curr!=null) {
if(curr.item.compareTo(item)==0) {
if(prev==null) {
head=curr.next;
} else {
prev.next = curr.next;
curr=curr.next;
}
size--;
return true;
}else{
prev=curr;
curr = curr.next;
}
}
}
return false;
}
public void removeAll() {
this.head.prev = null;
this.head.next = null;
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public boolean remove(Object item) {
return true;
}
public void insertSortNode() {
Node back = head;
if (size < 2)
return;
back = back.next; // SECOND entry in the list
while ( back != null ) { // I.e., end-of-list
Comparable value = back.item;
Node curr = head; // Start at the front
// Find insertion point for value;
while (curr != back && value.compareTo(curr.item) >= 0)
curr = curr.next;
// Propogate values upward, inserting the value from back
while (curr != back){
Comparable hold = curr.item;
curr.item = value;
value = hold;
curr = curr.next;
}
back.item = value; // Drop final value into place!
back = back.next; // Move sorted boundary up
}
} // end insertSort()
public void selSort() {
Node front = head;
// Nothing to do on an empty list
if ( front == null )
return;
while ( front.next != null ) { // skips a one-entry list
Node tiny = front;
Node curr = front.next;
Comparable temp = front.item; // start the swap
for ( ; curr != null ; curr = curr.next ) {
if ( tiny.item.compareTo(curr.item) > 0 )
tiny = curr;
}
front.item = tiny.item; // Finish the swap
tiny.item = temp;
front = front.next; // Advance to the next node
}
// The structure is unchanged, so the validity of tail is unchanged.
}
public void bubbleSort() {
Node Trav=head.next;
Node Trail=head.next;
Comparable temp;
if (Trav != null)
Trav = Trav.next;
while(Trav!=null) {
if (Trav.item.compareTo(Trail.item)<0) {
temp = Trail.item;
Trail.item=Trav.item;
Trav.item = temp;
}
Trail=Trav;
Trav=Trav.next;
}
}
public void insertSortArray() {
Node insert1, cur, tmp1;
Comparable temp;
for(insert1 = this.head.next.next; insert1!=this.head; insert1 = insert1.next) {
//++loopcompares; ++loopassigns;
for (cur = head.next; cur!=insert1; cur=cur.next) {
//++loopCompares; ++loopassigns;
//++datacompares;
if(insert1.item.compareTo(cur.item)<0) {
temp=insert1.item;
//++dataassign
tmp1=insert1;
//++other
while(tmp1!=cur.prev) {
//++loopcomares
tmp1.item=tmp1.prev.item;
tmp1=tmp1.prev;
//++dataassign+=2
}
//++loopcompares
cur.item = temp;
//++dataassign;
break;
}
}
//++loopcompares; ++loopassigns;
}
//++loopcompares; ++loopassigns
}
public void disp6sortsFile(boolean disp, String fileName, String header, String data) {
FileWriter fw = null;
PrintWriter pw = null;
try {
File file = new File(fileName);
fw = new FileWriter(file, true);
pw = new PrintWriter(fw, true);
} catch (IOException e) {
System.err.println("File open failed for " +fileName+ "\n" + e);
System.exit(-1);
}
if (disp) {
pw.print(header + "\n");
}
pw.print(data + "\n");
pw.close();
}
}
here is my error:
Exception in thread "main" java.lang.NullPointerException
at LinkedList.bubbleSort(LinkedList.java:149)
at LinkListTester.main(LinkListTester.java:51)
the linkedlisttester error is simply list1.bubbleSort(); so bubble sort is the problem.
Change:
public String toString() {
return this.item.toString();
}
to:
public String toString() {
return String.valueOf(item); // Handle null too.
}
For add return true. Might check that item is not null if so desired.
remove is written for a single linked list.
In remove the head has a null item, which might have caused the error. Also as we have a circular list with a dummy node for head, the termination should not test for null but head. Otherwise a not present item will loop infinitely.
public boolean remove(Comparable item) {
if(!isEmpty()) {
Node prev = null;
Node curr = head.next; // !
while(curr!=head) { // !
if(curr.item.compareTo(item)==0) {
if(prev==null) { // ! WRONG, but I will not correct home work ;)
head=curr.next;
} else {
prev.next = curr.next;
curr=curr.next;
}
size--;
return true;
}else{
prev=curr;
curr = curr.next;
}
}
}
return false;
}
swap is written for a single linked list.
And here I stopped reading, as I've come to the usages.
Second Edit:
All algorithmic functions, i.e. bubbleSort, have the following control flow:
while(Trav!=null) { ... Trav = Trav.next; }
But the data structure is defined cyclic, so eventually you arrive back at head and there the item is null.
The solution is to have for the first Node a prev null, and for the last Node a next null.
To make this clear, readable, you could substitute the Node head with:
Node first;
Node last;

Categories

Resources