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
Related
This is the code I was given for the Singly Linked List, however I am struggling on completing the Reverse function. This was the code and my attempt at the reverse function. I keep getting 2 errors that say "Undeclared variable: node" and "imcompatible types: Node cannot be converted to Linkedlist".
class LinkedList
{
Node head;
Node current;
Node previous;
public Object Get()
{
return current != null ? current.GetData() : null;
}
public void Next()
{
if (current != null)
{
previous = current;
current = current.next;
}
}
public void Head()
{
previous = null;
current = head;
}
public void Insert(Object data)
{
Node node = new Node(data);
node.next = current;
if (current == head)
head = node;
else
previous.next = node;
current = node;
}
public void Remove()
{
if (current == null)
throw new RuntimeException("Invalid position to remove");
if (current == head)
head = current.next;
else
previous.next = current.next;
current = current.next;
}
public void Print()
{
for (Head(); Get() != null; Next())
System.out.println(Get());
}
public LinkedList Reverse()
{
Node previous = null;
Node current = node;
Node forward;
while (current != null)
{
forward = current.next;
current.next = previous;
previous = current;
current = forward;
}
return previous;
}
}
There is also class Node:
class Node
{
// Public reference to next node
public Node next;
// Private data field
Object data;
Node(Object data)
{
this.data = data;
}
public Object GetData()
{
return data;
}
}
And this is the main function:
class Test
{
public static void main(String args[])
{
// creating a singly linked list
LinkedList linked_list = new LinkedList();
// adding node into singly linked list
linked_list.Insert(Integer.valueOf(10));
linked_list.Next();
linked_list.Insert(Integer.valueOf(11));
linked_list.Next();
linked_list.Insert(Integer.valueOf(12));
// printing a singly linked
linked_list.Print();
// reversing the singly linked list
linked_list.Reverse();
// printing the singly linked list again
linked_list.Print();
}
}
Here is a simple solution:
public class ListReverser {
public static Node<Integer> reverse(Node head) {
Node current = head;
while(current.getNext() != null) {
Node next = current.getNext();
current.setNext(next.getNext());
next.setNext(head);
head = next;
}
return head;
}
}
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.
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);
}
}
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();
}
}
I thought I had this program working but unfortunately I've overlooked something. How do you delete the first Node and convert the second node into the front of the Linked List. I've tries a multitude of approaches but end up with the same result.(LinkedList remaining unchanged) Any guidance would be much appreciated.
Node Class
public class Node {
private String data;
private Node next;
Node(String data, Node next)
{
this.data = data;
this.next = next;
}
public void setData(String d)
{
data = d;
}
public void setNext(Node n)
{
next = n;
}
public String getData()
{
return data;
}
public Node getNext()
{
return next;
}
Main
public static void main(String[] args) {
Node list = new Node("NODE 1",new Node("NODE 2",new Node("NODE 3", null)));
list = insertSecond(list,"New Node");
list = addLast(list,"LAST NODE");
printList(list);
System.out.println();
deleteNode(list, "NODE 1");
printList(list);
}
public static Node deleteNode(Node list,String str)
{
Node temp = list;
Node prev = list;
while(temp != null)
{
if(temp.getData().equals(str))
{
if(temp.getData().equals(list.getData()))
{
list = list.getNext();
return deleteNode(list,str);
}
else
{
prev.setNext(prev.getNext().getNext());
}
}
prev = temp;
temp = temp.getNext();
}
return list;
Your deleteNode function should return the head of new list. This is required only in one edge case which you described - deleting head of that list.
list = deleteNode(list, str);
Also you don't need to recursively execute deleteNode method, iteration over node elements should be enough:
public static Node deleteNode(Node list, String str) {
// I'm assuming that you are deleting the first inscance of the string
Node temp = list;
Node prev = list;
while(temp != null) {
if(temp.getData().equals(str)) {
if(temp.getData().equals(list.getData())) {
return list.getNext();
}
else {
prev.setNext(temp.getNext());
return list;
}
}
prev = temp;
temp = temp.getNext();
}
return list;
}