I have just seen this wonderful code from this question "Generic Linked List in java" here on Stackoverflow. I was wandering on how do you implement a method remove (to remove a single node from the linkedlist), size (to get the size of list) and get (to get the a node). Could someone please show me how to do it?
public class LinkedList<E> {
private Node head = null;
private class Node {
E value;
Node next;
// Node constructor links the node as a new head
Node(E value) {
this.value = value;
this.next = head;//Getting error here
head = this;//Getting error here
}
}
public void add(E e) {
new Node(e);
}
public void dump() {
for (Node n = head; n != null; n = n.next)
System.out.print(n.value + " ");
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.add("world");
list.add("Hello");
list.dump();
}
}
Your implementation of LinkedList for operation remove(), size() and contains()
looks like this:
static class LinkedList<Value extends Comparable> {
private Node head = null;
private int size;
private class Node {
Value val;
Node next;
Node(Value val) {
this.val = val;
}
}
public void add(Value val) {
Node oldHead = head;
head = new Node(val);
head.next = oldHead;
size++;
}
public void dump() {
for (Node n = head; n != null; n = n.next)
System.out.print(n.val + " ");
System.out.println();
}
public int size() {
return size;
}
public boolean contains(Value val) {
for (Node n = head; n != null; n = n.next)
if (n.val.compareTo(val) == 0)
return true;
return false;
}
public void remove(Value val) {
if (head == null) return;
if (head.val.compareTo(val) == 0) {
head = head.next;
size--;
return;
}
Node current = head;
Node prev = head;
while (current != null) {
if (current.val.compareTo(val) == 0) {
prev.next = current.next;
size--;
break;
}
prev = current;
current = current.next;
}
}
}
Related
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 1 year ago.
I am trying to print out the elements in my ArrayList that looks like
static ArrayList<LinkedList> listy = new ArrayList<>();
I tried to create a function called PrintTest()
public static void pTest() {
String [] top;
for (LinkedList i: listy) {
//i.show();
System.out.println(i.toString());
However, I am still getting when I call printTest()
LinkedList#15975490
LinkedList#6b143ee9
LinkedList#1936f0f5
LinkedList#6615435c
LinkedList#4909b8da
LinkedList#3a03464
LinkedList#2d3fcdbd
LinkedList#617c74e5
Do I need to iterator over this once more? I am confused on how to go about this. Can I override toString()? I can't seem to get it to work
Here is my linkedlist implementation code
public class LinkedList {
Node head;
Node tail;
public String getFirst() {
Node node = head;
if (node.next == null) {
throw new NoSuchElementException();
}
else {
return node.data;
}
}
public void insert(String data) {
Node node = new Node();
node.data = data;
node.next = null;
if (head == null) {
head = node;
}
else {
Node n = head;
while(n.next !=null) {
n = n.next;
}
n.next = node;
}
}
public void insertAtStart(String data) {
Node node = new Node();
node.data = data;
node.next = null;
node.next = head;
head = node;
}
public void insertAt(int index, String data) {
Node node = new Node();
node.data = data;
node.next = null;
if(index == 0) {
insertAtStart(data);
}
else {
Node n = head;
for (int i = 0; i < index-1; i++) {
n = n.next;
}
node.next = n.next;
n.next = node;
}
}
public void deleteAt(int index) {
if (index == 0) {
head = head.next;
}
else {
Node n = head;
Node n1 = null;
for (int i = 0; i < index-1; i++) {
n = n.next;
}
n1 = n.next;
n.next = n1.next;
//System.out.println("n1 " + n1.data);
n1 = null;
}
}
public int size() {
int count =0;
Node pos = head;
while (pos != null) {
count++;
pos = pos.next;
}
return count;
}
public void remove(String s) {
Node node = head;
while (!node.data.equals(s)) {
node = node.next;
}
if (node.next == null) {
node.data = null;
}
else {
node.data = node.next.data;
node.next = node.next.next;
}
//System.out.println("n1 " + n1.data);
}
public void show() {
Node node = head;
while(node.next != null) {
System.out.println(node.data);
node = node.next;
}
System.out.println(node.data);
In java, every class inherits the Object class. In the Object class default definition for the toString method is hashcode. When you are calling toString method, you need to define by yourself.
class LinkedList{
int value;
#Override
public String toString(){
return String.valueOf(value);
}
}
I think you can go through this article to get more understanding.Explanation For toString
I'm trying to add "hello" at the index 0 but it it's added at index one, and also prints USA after that when it shouldn't. What's wrong with my add method? Is there something else that's wrong in the code that's causing this problem or is it just the add method? Any help is appreciated... The code of singlylinkedlist with the implementation is below...
class SinglyLinkedList<E> { //---------------- nested Node class
private static class Node<E> { private E element;
private Node<E> next;
public Node(E e, Node<E> n) {
element = e;
next = n; }
public E getElement() {
return element;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> n) {
next = n;
} }
private Node<E> head = null;
private Node<E> tail = null;
private int size = 0;
public SinglyLinkedList() { }
public int size() { return size; }
public boolean isEmpty() { return size == 0; }
public E first() {
if (isEmpty()) return null; return head.getElement();
}
public E last() {
if (isEmpty()) return null;
return tail.getElement(); }
// update methods
public void addFirst(E e) {
head = new Node<>(e, head);
if (size == 0)
tail = head;
size++;
}
public void addLast(E e) {
Node<E> newest = new Node<>(e, null);
if (isEmpty( ))
head = newest;
else
tail.setNext(newest);
tail = newest;
size++;
}
public E removeFirst() {
if (isEmpty())
return null;
E answer = head.getElement();
head = head.getNext();
size--;
if (size == 0)
tail = null;
return answer;
}
public void printLinkedList() {
Node<E> temp = head;
for(int i = 0; i< size; i++) {
System.out.println(temp.getElement());
temp = temp.next;
}
}
public void removeLast() {
tail = null;
size--;
}
public void remove(int index) {
//Node<E> newest = new Node(e, null);
Node<E> current = head;
if (index == 0) {
removeFirst();
}
else {
for (int i = 0; i<index -1; i++) {
//current = current.next;
current = current.getNext();
}
current.next = current.next.next;
}
size--;
}
public void add(int index, E e) {
Node<E> current = head;
Node newNode = new Node(e, null);
for(int i = 0; i< index; i++) {
current = current.next;
}
current.next = newNode;
newNode.next = current;
size++;
}
}
public class SinglyLinkedListTest {
public static void main(String args[]) {
SinglyLinkedList<String> list = new SinglyLinkedList();
list.addLast("USA");
list.addLast("America");
list.addLast("portugal");
System.out.println(" ");
list.printLinkedList();
//list.remove(2);
System.out.println(" ");
list.printLinkedList();
list.removeLast();
System.out.println(" ");
list.printLinkedList();
list.add(0, "hello");
System.out.println(" ");
list.printLinkedList();
}
}
There a two mistakes:
at index 0 you need to replace head
current points to newNode and newNode points to current
Fixed code:
public void add(int index, E e) {
Node<E> newNode = new Node<>(e, null);
if(index == 0) {
newNode.next = head;
head = newNode;
} else {
Node<E> current = head;
for(int i = 1; i< index; i++) {
current = current.next;
}
Node<E> tmp = current.next;
current.next = newNode;
newNode.next = tmp;
}
size++;
}
My code for linked list reversal doesn't compile. Everything seems to be logically correct.
Here is the snippet of my LinkedList class:
public class LinkedList {
Node head;
public static class Node {
int data;
Node next;
Node(int d) {
this.data = d;
this.next = null;
}
}
public void display(Node n) {
n = head;
int ctr;
while (n != null) {
System.out.print(n.data +" ");
n = n.next;
}
ctr = countNodes(head);
System.out.println("The list length is "+ctr);
}
public Node recreverse(Node n){
Node prev = null;
Node temp = null;
if (n.next == null) {
head = n;
head.next = prev;
return head;
} else {
temp = n;
n = n.next;
prev = n;
prev.next = temp;
return n;
}
}
}
countNodes(Node) is not defined anywhere:
ctr = countNodes(head);
Define it and the code will compile.
import java.util.Scanner;
public class reverse {
private Node head;
private int listCount;
public reverse() {
head = new Node(null);
listCount = 0;
}
public static void main(String args[]) {
reverse obj = new reverse();
Scanner sc = new Scanner(System.in);
int n, i, x;
System.out.println("How many no.s?");
n = sc.nextInt();
for (i = 1; i <= n; i++) {
System.out.println("enter the no.");
x = sc.nextInt();
obj.add(x);
}
Node newhead = obj.method1(obj.head);
obj.display(newhead);
}
public void add(Object data) {
Node temp = new Node(data);
Node current = head;
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(temp);
listCount++;
}
public void display(Node newhead) {
Node current = newhead;
//System.out.println(current.getNext().getNext().getNext().getNext().getNext().getData());
while (current != null) {
System.out.print(current.getData() + " " +);
current = current.getNext();
}
}
public Node method1(Node head) {
if (head == null) {
return head;
}
Node first = head.getNext();
Node second = first.getNext();
first.setNext(head);
head = null;
if (second == null)
return head;
Node current = second;
Node prev = first;
while (current != null) {
Node upcoming = current.getNext();
current.setNext(prev);
prev = current;
current = upcoming;
//System.out.println(prev.getData());
//System.out.println(current.getData());
}
head = prev;
return head;
}
private class Node {
Node next;
Object data;
public Node(Object _data) {
next = null;
data = _data;
}
public Node(Object _data, Node _next) {
next = _next;
data = _data;
}
public Object getData() {
return data;
}
public void setData(Object _data) {
data = _data;
}
public Node getNext() {
return next;
}
public void setNext(Node _next) {
next = _next;
}
}
}
My while statement is not working properly.
Initial value of newhead.getData() is 5. The comment part in my code is also giving value as null which is correct, but after that there is some error in my while loop.
I have written code for reversing a linked list.
display() method is to print all the list elements.
Input from user of linked list is:
1 2 3 4 5
Output should be:
5 4 3 2 1
But my output is:
null 1 null 1 null 1............occurring infinite times.
you have a problem when you a filling your data .
all nods have the same reference
try to print your list
for(int i=;i;list.size();i++)
System.out.print(list.getObjectAtIndex(i).getData);
I am trying to learn data structure, but I ran into the dreaded NullPointerException and I am not sure how to fix it.
My SinglyLinkedList<E> class implements an interface, LinkedList, where I redefined some methods like, add(), get(), contains(), and more.
The NullPointerException happens when I use the clear() method. It points at the method removeLast() under nodeBefore.setNext(null). It also points to the clear() method under remove(head.getElement()).
Also, if there is anything I can improve upon in my code please let me know.
public class SinglyLinkedList<E> implements LinkedList<E> {
private class Node<E> {
public Node<E> next;
public E element;
public Node(E element) {
this.element = element;
}
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 setElement(E element) {
this.element = element;
}
public void setNext(Node<E> next) {
this.next = next;
}
public String toString() {
return ("[" + element + "] ");
}
}
public Node<E> head;
public Node<E> tail;
public int total;
public SinglyLinkedList() {
this.head = null;
this.tail = null;
this.total = 0;
}
public E get(int index) {
if (index < 0 || index > size()) {
return null;
}
if (index == 0) {
return head.getElement();
}
Node<E> singly = head.getNext();
for (int i = 1; i < index; i ++) {
if (singly.getNext() == null) {
return null;
}
singly = singly.getNext();
}
System.out.println("\n" + singly.getElement());
return singly.getElement();
}
public void add(E element) {
Node<E> singlyAdd = new Node<E>(element);
if (tail == null) {
head = singlyAdd;
tail = singlyAdd;
} else {
tail.setNext(singlyAdd);
tail = singlyAdd;
}
total++;
}
public void display() {
if (head == null) {
System.out.println("empty list");
} else {
Node<E> current = head;
while (current != null) {
System.out.print(current.toString());
current = current.getNext();
}
}
}
public boolean contains(E data) {
if (head == null) {
return false;
}
if (head.getElement() == data) {
System.out.println(head);
return true;
}
while (head.getNext() != null) {
head = head.getNext();
if (head.getElement() == data) {
System.out.println(head);
return true;
}
}
return false;
}
private Node<E> removeFirst() {
if (head == null) {
System.out.println("We cant delete an empty list");
}
Node<E> singly = head;
head = head.getNext();
singly.setNext(null);
total--;
return singly;
}
private Node<E> removeLast() {
Node<E> nodeBefore;
Node<E> nodeToRemove;
if (size() == 0) {
System.out.println("Empty list");
}
nodeBefore = head;
for (int i = 0; i < size() - 2; i++) {
nodeBefore = nodeBefore.getNext();
}
nodeToRemove = tail;
nodeBefore.setNext(null);
tail = nodeBefore;
total--;
return nodeToRemove;
}
public E remove(int index) {
E hold = get(index);
if (index < 0 || index >= size()) {
return null;
} else if (index == 0) {
removeFirst();
return hold;
} else {
Node<E> current = head;
for (int i = 1; i < index; i++) {
current = current.getNext();
}
current.setNext(current.getNext().getNext());
total--;
return hold;
}
}
public int size() {
return getTotal();
}
public boolean remove(E data) {
Node<E> nodeBefore, currentNode;
if (size() == 0) {
System.out.println("Empty list");
}
currentNode = head;
if (currentNode.getElement() == data) {
removeFirst();
}
currentNode = tail;
if (currentNode.getElement() == data) {
removeLast();
}
if (size() - 2 > 0) {
nodeBefore = head;
currentNode = head.getNext();
for (int i = 0; i < size() - 2; i++) {
if (currentNode.getElement() == data) {
nodeBefore.setNext(currentNode.getNext());
total--;
break;
}
nodeBefore = currentNode;
currentNode = currentNode.getNext();
}
}
return true;
}
public void clear() {
while (head.getNext() != null) {
remove(head.getElement());
}
remove(head.getElement());
}
private int getTotal() {
return total;
}
}
For your clear method, I don't see that you do any per element cleanup, and the return type is void, so all you want is an empty list. The easiest way is to simply clear everything, like in the constructor:
public void clear() {
this.head = null;
this.tail = null;
this.total = 0;
}
Another comment:
in contains, you do
while (head.getNext() != null) {
head = head.getNext();
if (head.getElement() == data) {
System.out.println(head);
return true;
}
}
which may have two problems (where the first applies to the entire class),
you compare with == data which compares references, where you probably want to compare values with .equals(data)
Edit: I.e. n.getElement().equals(data) instead of n.getElement() == data.
(Or, if n and data may be null, something like (data != null ? data.equals(n.getElement()) : data == n.getElement())
you use the attribute head as the scan variable which modifies the state of the list. Do you really want that?
The problem arises when you delete the last element within clear: remove(head.getElement());. For some reason, you first remove the head and then the tail. But when calling removeLast, you use the head (which is already null). Within removeLast this is the line, which causes the NullPointerException: nodeBefore.setNext(null);.
My advice would be to write the clear() method as #bali182 has suggested:
public void clear() {
this.head = null;
this.tail = head;
this.total = 0;
}
One advice: if you are writing methods to search or delete entries, you should never use == when dealing with objects (or even better: don't use == at all when dealing with objects). You may want to read this thread.
From within clear method, you are calling remove(head.getElement()); meaning you are trying to call LinkedList's remove method. And since you are overriding each functionality and so is add, you don't maintain internal state of LinkedList and hence you get exception. Code in remove is:
public boolean remove(Object o) {
if (o==null) {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (e.element==null) {
So here since you are not using functionality of LinkedList, header would be null and doing header.next would return NullPointerException.