LinkedList without tail field gets stuck in infinite loop - java

What's wrong with my LinkedList add method if I want to implement it without a tail field?
public class LinkedList<E> {
private Node<E> head= new Node<E>();
private int size=0;
public void linkedList(){
head=null;
size=0;
}
public void add(E data){
Node<E> currNode=head;
while (currNode.hasNext()){
currNode.setNext(currNode.getNext());
}
Node<E> lastNode= new Node<E>();
lastNode.setItem(data);
lastNode.setNext(null);
currNode.setNext(lastNode);
size++;
}
public void remove(int i){
Node<E> currNode = head;
int index=0;
while (index<i){
currNode.setNext(currNode.getNext());
i++;
}
currNode.setNext(currNode.getNext().getNext());
}
public void print(){
Node<E> currNode = new Node<E>();
do{
System.out.println(currNode.getItem());
} while (!currNode.hasNext());
}
public static void main(String arc[]){
LinkedList<String> ll = new LinkedList<String>();
ll.add("9");
ll.add("b");
ll.add("987");
ll.print();
return;
}
}
Here's the Node class:
public class Node<E> {
private E item;
private Node<E> next;
public Node<E> getNext(){
return this.next;
}
public void setNext(Node<E> n){
this.next=n;
}
public E getItem(){
return this.item;
}
public void setItem(E item){
this.item=item;
}
public boolean hasNext(){
return (this.next != null);
}
}
Edit: Changed the print method to:
public void print(){
Node currNode = head;
while (currNode.hasNext()){
System.out.println(currNode.getItem());
currNode=currNode.getNext();
}
}
and I get this result:
null
9
b

In your add method, don't you mean :
currNode = currNode.getNext();
instead of :
currNode.setNext(currNode.getNext());
? Because the last one has no effect and you are making an infinite loop...

This block will never end
while (currNode.hasNext()) {
currNode.setNext(currNode.getNext());
}
So infinite loop.
Make sure you move the currNode to forward, to reach the loop end by adding crrNode.next() inside the while loop.

Related

Java Linked List add Method

I am attempting to implement a linked list that uses a node class containing head, tail, and current nodes. Part of the linked list is an add method that should add a value to the end of the current node in the list just like an actual linked list would. My issue is that it only works for the first node and then just stops there. For example, in my main I tried testing the code by calling add(1); and add(2);. The console shows me 1 but that's all. I'm unsure if the error is in my add method, toString method, or node class.
I'll also add that I tested whether the correct values were being assigned to "current" in either case, and they were. This has led me to wonder if it's the toString that is the root of the issues, however no matter how much I try I can't change it to make any improvements.
I've hoping fresh eyes may be able to find any blaring issues that may exist.
Add method:
public void add(int val){
if(current != null){
Node nextNode = new Node(val, current);
current = nextNode;
tail = nextNode;
}
else{
head = tail = new Node(val, null);
current = head;
}
}
Node class:
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = next;
}
}
toString:
public String toString(){
for(Node x = head; x != null; x = x.next){
System.out.println(x.data);
}
All:
public class IntLList extends IntList{
public IntLList(){
}
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = next;
}
}
Node head = null;
Node tail = null;
Node current = null;
public void add(int val){
if(current != null){
Node nextNode = new Node(val, current);
current = nextNode;
tail = nextNode;
}
else{
head = tail = new Node(val, null);
current = head;
}
}
public int get(int index){
return 0;
}
public void set(int index, int val){
}
public void remove(int index) throws ArrayIndexOutOfBoundsException{
}
public int size(){
return 0;
}
public String toString(){
for(Node x = head; x != null; x = x.next){
System.out.println(x.data);
}
return "temp";
}
public void removeLast(){
}
public boolean isEmpty(){
boolean isEmpty = false;
if(head == null){
isEmpty = true;
}
return isEmpty;
}
public void clear(){
}
public static void main(String[] args) {
IntLList i = new IntLList();
i.add(1);
i.add(2);
i.toString();
}
}
Make the following changes:
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = NULL; // this is to set the next node of current node to null
if(next!=NULL)
next.next=this; // this is to set the previous node to point to current node
}
}

NullPointerException in getlast() for linked list [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I'm having this problem with my linked list that when i try to access the last node data section it throws me a null exception
the code section: getlast() method with an object in the main class
package lab1_ds;
public class LAB1_DS {
public static void main(String[] args) {
singlylinkedlist mylist=new singlylinkedlist();
singlylinkedlist<person> plist=new singlylinkedlist();
plist.addfirst(new person("Hesssa","SA"));
plist.addfirst(new person("Nora","SA"));
plist.display();
plist.addnode(new person("Farah","SA"),2);
plist.display();
System.out.println(plist.first().getName());
plist.removeNode(plist.getlast());
plist.display();
}
}
and the linked list code is:
package lab1_ds;
public class singlylinkedlist <E>{
private static class Node<E>{
private E element;
private Node<E> next;
public Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
public E getElement() {
return element;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> next) {
this.next = next;
}
}
private Node<E> head=null;
private Node<E> tail=null;
private int size=0;
public singlylinkedlist() {
}
public void display(){
Node<E> current;
current=head;
int count=0;
System.out.println("\n-----------Display method-----------");
while(current!=null){
count++;
System.out.println("Linked list ("+count+"):"+current.getElement());
current=current.getNext();
}
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public E getlast(){
if (isEmpty())
return null;
return tail.getElement();
}
public void setTail(Node<E> tail) {
this.tail = tail;
}
public E first(){
if (isEmpty())
return null;
return head.getElement();
}
public void addfirst(E value){
Node<E> newNode= new Node(value,null);
newNode.next=head;
head=newNode;
size=size+1;
if(size==1)
head=tail;
}
public void addlast(E value){
Node<E> newNode= new Node(value,null);
if(size==0)
head=tail=newNode;
else{ tail.next=newNode;
tail=newNode;
}
size=size+1;
}
public void addnode(E value,int pos){
Node<E> current;
if(pos==1)
addfirst(value);
if(pos==size+1)
addlast(value);
Node<E> newNode= new Node(value,null);
current=head;
int count=1;
while(count<pos-1 && current.next!=null){
current=current.next;
count=count+1;
}
newNode.next=current.next;
current.next=newNode;
size++;//or size=size+1;
}
public void removeFirst(){
if (isEmpty()){
System.out.println("linked list is empty");
return;
}
head=head.getNext();
size--;//or size=size-1;
if(size==0)
tail=null;//only node
}
public void findNode(E place){
if (isEmpty()){
System.out.println("linked list is empty");
return;
}
Node<E> current=head;
int count=1;
while (current!=null ){
if(current.getElement()==place || current.getElement().equals(place)){
System.out.println("found in posittin #"+count);
return;}
count++;
current=current.getNext();
}//end while loop
System.out.println("\n.......Node is not found!......");
}
public void removeNode(E place){
Node<E> current=head;
Node<E> prev=head;
if (isEmpty()){
System.out.println("linked list is empty");
return;
}
while(current.getElement()!=place && !current.getElement().equals(place)){
if(current.next==null){
System.out.println("\n not found...");
return;
}
prev=current;
current=current.next;
}//end loop
if(current==head){
removeFirst();
}
else {
prev.next=current.next;
size--;
}
if(current==tail){//node i'm trying to remove is the last node
tail=prev;
}
}
}
and the error shows:
Exception in thread "main" java.lang.NullPointerException
at lab1_ds.singlylinkedlist.getlast(singlylinkedlist.java:52)
at lab1_ds.LAB1_DS.main(LAB1_DS.java:34)
line 52:
return tail.getElement();
line 34:
plist.removeNode(plist.getlast());
Please help me I can't seem to figure it out and the lab assisstant says it should work (the getlast())
The problem is in your addfirst method. You are reassigning head to null, rather than tail to head. Correct version:
public void addfirst(E value) {
Node<E> newNode = new Node(value, null);
newNode.next = head;
head = newNode;
size = size + 1;
if (size == 1)
tail = head;
}
After this change, the output is:
-----------Display method-----------
Linked list (1):person{name='Hesssa', state='SA'}
-----------Display method-----------
Linked list (1):person{name='Nora', state='SA'}
Linked list (2):person{name='Hesssa', state='SA'}
-----------Display method-----------
Linked list (1):person{name='Nora', state='SA'}
Linked list (2):person{name='Farah', state='SA'}
Linked list (3):person{name='Hesssa', state='SA'}
Nora
-----------Display method-----------
Linked list (1):person{name='Nora', state='SA'}
Linked list (2):person{name='Farah', state='SA'}
Sidenote:
Please see the naming convention of classes and methods. They should be in snake case. For example, method name from addfirst -> addFirst. Class name from singlylinkedlist -> SinglyLinkedList

Need guidance on creating Node class (java)?

I need to implement a Node class, where the basic methods are: getItem(), getNext(), setItem() and setNext(). I want the nodes to be able to store at least the default integer range in Java as the “item”; the “next” should be a reference or pointer to the next Node in a linked list, or the special Node NIL if this is the last node in the list.I also want to implement a two-argument constructor which initializes instances with the given item (first argument) and next node (second argument) , I've kind of hit a brick wall and need some guidance about implementing this , any ideas ?
I have this so far:
class Node {
public Node(Object o, Node n) {
}
public static final Node NIL = new Node(Node.NIL, Node.NIL);
public Object getItem() {
return null;
}
public Node getNext() {
return null;
}
public void setItem(Object o) {
}
public void setNext(Node n) {
}
}
While implementing the custom LinkedList/Tree, we need Node. Here is demo of creating Node and LinkedList. I have not put in all the logic. Just basic skeleton is here and you can then add more on yourself.
I can give you a quick hint on how to do that:
Class Node{
//these are private class attributes, you need getter and setter to alter them.
private int item;
private Node nextNode;
//this is a constructor with a parameter
public Node(int item)
{
this.item = item;
this.nextNode = null;
}
// a setter for your item
public void setItem(int newItem)
{
this.item = newItem;
}
// this is a getter for your item
public int getItem()
{
return this.item;
}
}
You can create a Node object by calling:
Node newNode = Node(2);
This is not a complete solution for your problem, the two parameter constructor and the last node link are missing, but this should lead you in the correct direction.
Below is a simple example of the Node implementation, (i renamed Item to Value for readability purpose). It has to be implemented somehow like this, because methods signatures seems to be imposed to you. But keep in mind that this is definely not the best way to implement a LinkedList.
public class Node {
public static final Node NIL = null;
private Integer value;
private Integer next;
public Node(Integer value, Node next) {
this.value = value;
this.next = next;
}
public Integer getValue() {
return this.value;
}
public Node getNext() {
return this.next;
}
public void setValue(Integer value) {
this.value = value;
}
public void setNext(Node next) {
this.next = next;
}
public boolean isLastNode() {
return this.next == Node.NIL || Node;
}
}
public class App {
public static void main(String[] args) {
Node lastNode = new Node(92, Node.NIL);
Node secondNode = new Node(64, lastNode);
Node firstNode = new Node(42, secondNode);
Node iterator = firstNode;
do () {
System.out.println("node value : " + iterator.getValue());
iterator = iterator.getNext();
} while (iterator == null || !iterator.isLastNode());
}
}
The node class that will be implemented changes according to the linked list you want to implement. If the linked list you are going to implement is circular, then you could just do the following:
public class Node {
int data;
Node next = null;
public Node(int data){
this.data = data;
}
}
Then how are you going to implement the next node?
You are going to do it in the add method of the circularLinkedList class. You can do it as follows:
import java.util.*;
public class CircularLinkedList {
public CircularLinkedList() {}
public Node head = null;
public Node tail = null;
public void add(int data) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
}
else {
tail.next = newNode;
}
tail = newNode;
tail.next = head;
}
public void displayList() {
System.out.println("Nodes of the circular linked list: ");
Node current = head;
if(head == null) {
System.out.println("Empty list...");
}
else {
do {
System.out.print(" " + current.data);
current = current.next;
}while(current != head);
System.out.println();
}
}
}

Confused about choosing a loop to iterate a linked list

My problem is in the add method. I think I know what I want it to do but I can't figure out what type of loop I should use to look through the list. As you can see I started to make a if else loop but I couldn't figure out what I should use as the counter. I'm pretty sure I have the right logic in dealing with the add but I feel like I'm not quite there yet. I was thinking of using compareTo in some fashion.
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node topNode;
private class Node
{
private E data;
private Node nextNode;
public Node(E data)
{
this.data = data;
nextNode = null;
}
}
public OrderedLinkedList()
{
topNode = null;
}
public boolean empty()
{
if(topNode == null)
return true;
return false;
}
public String toString()
{
String myString = "";
Node nextNode = topNode;
while(nextNode != null)
{
myString = topNode + " -> " + nextNode;
nextNode = topNode.nextNode;
}
return myString;
}
public void add(E data)
{
Node myNode = new Node(data);
Node priorNode = topNode;
Node currentNode = topNode;
if(___)
{
priorNode = currentNode;
currentNode = currentNode.nextNode;
}
else
{
priorNode.nextNode = myNode;
myNode.nextNode = currentNode;
}
}
}
Since you don't typically know the length of a linked list until you've walked down it, the usual thing would be to use a while loop (as you've done in your toString() method)
Perhaps using a doubly linked list would be more beneficial. Consider the following alterations to your class:
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node head;
private Node tail;
private class Node
{
private E data;
private Node nextNode;
private Node prevNode;
public Node(E data)
{
this.data = data;
nextNode = null;
prevNode = null;
}
public void setNext(Node node)
{
this.nextNode = node;
}
public Node getNext()
{
return this.nextNode;
}
public void setPrev(Node node)
{
this.prevNode = node;
}
public Node getPrev()
{
return this.prevNode;
}
public E getData()
{
return this.data;
}
public int compareTo(Node that) {
if(this.getData() < that.getData())
{
return -1;
}
else if(this.getData() == that.getData()
{
return 0;
}
else
{
return 1;
}
}
}
public OrderedLinkedList()
{
head = new Node(null);
tail = new Node(null);
head.setNext(tail);
tail.setPrev(head);
}
public boolean empty()
{
if(head.getNext() == tail)
{
return true;
}
return false;
}
public void add(E data) {
Node tmp = new Node(data);
if(this.empty()) {
this.addNodeAfterNode(tmp, head);
} else {
Node that = head.getNext();
// this while loop iterates over the list until finding the correct
// spot to add the new node. The correct spot is considered to be
// when tmp's data is >= that's data, or the next node after 'that'
// is tail. In which case the node is added to the end of the list
while((tmp.compareTo(that) == -1) && (that.getNext() != tail)) {
that = that.getNext();
}
this.addNodeAfterNode(tmp, that);
}
}
private void addNodeAfterNode(Node addNode, Node afterNode)
{
addNode.setNext(afterNode.getNext());
afterNode.getNext().setPrev(addNode);
afterNode.setNext(addNode);
addNode.setPrev(afterNode);
}
}

return a linked list of first n elements

Ok guys I need to write a method; MyLinkedList getFirst(int n) – Returns a linked list of the first n elements. If the list is empty or n > size return null.
and I'm lost, I've done the mothods add, remove, add to middle, print a string of elements, and so on but this one has me stuck..
all I have so far is:
public MyLinkedList<E> getFirst(int n) {
if(n > size ) {
return null;
}
Node<E> current = head;
for (int i = 0; i == n; i++) {
current.next = new Node<E>(e);
}
}
I know this code is pretty wrong but its all I can think of been working on this assignment for a while and I'm just running out of steam I guess lol
Thanks for any and all help.
Create an empty list
Add the head to the list
Continuing adding the next node to the list until you have the first n nodes.
public MyLinkedList getFirstN(int n) {
MyLinkedList firstNList=new MyLinkedList();//create an empty list
if(n>size)
firstNList= null;
else {
Node tmp=head; //initialise tmp Node to the head(beginning) of list
for(int i=0;i<n;i++) {
firstNList.add(tmp);//add current node to the end of list
tmp=tmp.getNext();
}
}
return firstNList;
}
Implement the add(Node node) method to append a Node to the end of list.
You can use this as prototype and proceed with any operation
public class Node {
private int data;
private Node next;
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
}
public class LinkedList {
private Node start;
public LinkedList() {
start = null;
}
public void insert(int x) {
if(start == null) {
start = new Node(x, start);
} else {
Node temp = start;
while(temp.getNext() != null) {
temp = temp.getNext();
}
Node newNode = new Node(x,null);
temp.setNext(newNode);
}
}
public void getFirst() {
if(start == null) {
System.out.println("\n List is empty !!");
}
else {
Node temp = start;
System.out.println("\n First Element is --->" + temp.getData());
}
}
}
public class MainClass {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
System.out.println("\n--- Inserting 100 ---\n");
ll.insert(100);
ll.insert(101);
ll.insert(102);
ll.insert(103);
System.out.println("\n--- First Element ---\n");
ll.getFirst();
}
}

Categories