I'd like to add new nodes into the list without removing/substituting the dummy node head, i.e. head is always null and the list would start from head.next (head -> node -> node -> node). I'm having trouble with the syntax of the dummy node and Im not sure if Im doing it right at all. Could smb please take a look? Thanks in advance!
Im getting a nullPointer in this line of the constructor:
this.head.next = null;
CODE
package SinglyLinkedList;
import java.util.*;
public class Tester {
public static void main(String[] args){
LinkedList<Integer> myList = new LinkedList<Integer>();
myList.insert(1);
myList.insert(2);
myList.insert(3);
myList.displayList();
}
}
Class Link
package SinglyLinkedList;
import java.util.Iterator;
public class Node<T> {
public T data;
public Node<T> next;
public Node(T data){
this.data = data;
}
public void display(){
System.out.print(this.data + " ");
}
}
class LinkedList<T> implements Iterable<T>{
private Node<T> head;
private int size;
public LinkedList(){
this.head = null;
this.head.next = null;
this.size = 0;
}
public boolean isEmpty(){
return head == null;
}
public void displayList(){
if(head.next == null){
System.out.println("The list is empty");
}
else{
Node<T> current = head.next;
while(current != null){
current.display();
current = current.next;
}
}
}
public void insert(T data){
Node<T> newNode = new Node<T>(data);
if(head.next == null){
head.next = newNode;
}
else{
newNode.next = head.next;
head.next = newNode;
}
size++;
}
#Override
public Iterator<T> iterator() {
// TODO Auto-generated method stub
return null;
}
}
I guess you have misunderstood the concept of linked lists. The member variable head points to the start address of the linked list. It cannot be null. head.next should point to the second element while head itself points to the first element. Moreover, you don't have to change the value of head while adding new nodes to the list unless the node you insert is supposed to be placed at the beginning of the linked list. In that case, you need to update head to point to the new node. For inserting nodes in the middle or at the end of the linked list, this is not required.
Further reading:
http://crunchify.com/how-to-implement-a-linkedlist-class-from-scratch-in-java/
http://www.tutorialspoint.com/java/java_linkedlist_class.htm
Related
I was working on a program to add nodes to a list, but I seem to be doing something wrong...
My java program has three Classes; Demo, Lista and Node
Class Node:
public class Node {
private int num;
private Node tail;
private Node head;
public Node (int num, Node head, Node tail) {
this.num = num;
this.head = head;
this.tail = tail;
}
}
Class Lista:
public class Lista {
private Node nil;
public Lista () {
nil = null;
}
public void add (int num) {
Node newNode = new Node(num, head, tail);
if (head == null) {
head = newNode;
tail = newNode;
}
}
public void display () {
Node current = head;
while(current != null) {
System.out.print(current.num);
}
}
}
Class Demo:
public class Demo {
public static void main ( String [] args) {
Lista lista = new Lista();
lista.add(3);
lista.add(9);
lista.add(7);
lista.display();
}
}
Demo class is to add the different nodes to the list "lista". Class Node has num, head which is the next one and tail which is the previous one. How can I go about getting Class Lista to be able to use head and tail from Class Node? And if it is possible would this code work when running Demo? What should I change/modify to get this to work?
You may want to modify your code something like this:
EDIT - This is a doubly-linked list implementation.
class Node {
int num;
Node prev;
Node next;
Node(int num) {
this.num = num;
}
Node(int num, Node prev, Node next) {
this.num = num;
this.prev = prev;
this.next = next;
}
void setPrev(Node prev) {
this.prev = prev;
}
void setNext(Node next) {
this.next = next;
}
}
class Lista {
Node root;
Node endNode;
public void add(int num) {
Node n = new Node(num);
if (root == null) {
root = n;
} else {
n.setPrev(endNode);
endNode.setNext(n);
}
endNode = n;
}
public void display() {
Node iterateeNode = root;
while (iterateeNode != null) {
System.out.print(iterateeNode.num + " ");
iterateeNode = iterateeNode.next;
}
}
}
The selected answer is technically not correct. For a (single) Linked List, all your Lista need is a single (head) node. Additionally, the Node class needs a single (next) Node field.
The following is a potential implementation of Node:
public class Node {
private Node next;
private int value;
public Node(int value) {
this.value = value;
}
public boolean hasNext() {
return next != null;
}
public Node next() {
return next;
}
public void add(Node node) {
if (next == null) {
next = node;
} else {
Node temp = next;
while (temp != null) {
temp = temp.next;
}
temp = node;
}
}
#Override
public String toString() {
return String.valueOf(value);
}
}
The add() method will insert the new node in next if it is null. Otherwise, it will traverse the nodes until it finds the tail node (the one where next is null).
The Lista has only the first element in the list (head node).
public class Lista {
private Node head;
public void add(Node node) {
if (head == null) {
head = node;
} else {
Node temp = head;
while (temp.hasNext()) {
temp = temp.next();
}
temp.add(node);
}
}
// Other methods
}
When the add() function in the list is called, it will either add the new node as the head (if the list doesn't have one already) or rely on the already added nodes to figure out where the end of the list is in order to insert the new node.
Lastly, to display the list, just override the toString() method in node and add the "toString" value to a string buffer and send the concatenated string value to the console similar to the the code below.
public void display() {
StringBuilder buff = new StringBuilder("[");
buff.append(head);
if (head != null) {
Node next = head.next();
buff.append(",");
while (next != null) {
buff.append(next);
next = next.next();
buff.append(",");
}
}
buff.append("]");
int idx = buff.lastIndexOf(",");
buff.replace(idx, idx+1, "");
System.out.println(buff.toString());
}
Executing the following displays [3,9,7] as expected.
public class Demo {
public static void main ( String [] args) {
Lista lista = new Lista();
lista.add(new Node(3));
lista.add(new Node(9));
lista.add(new Node(7));
lista.display();
}
}
My Node class:
public class Node<T>
{
protected T data;
protected Node<T> next;
protected Node<T> previous;
public Node()
{
this.data = null;
this.next = null;
this.previous = null;
}
public Node(T data)
{
this.data = data;
this.next = null;
this.previous = null;
}
public Node(T data, Node<T> next, Node<T> previous)
{
this.data = data;
this.next = next;
this.previous = previous;
}
public T getData()
{
return data;
}
public void setData(T data)
{
this.data = data;
}
public Node<T> getNext()
{
return next;
}
public void setNext(Node<T> next)
{
this.next = next;
}
public Node<T> getPrevious()
{
return previous;
}
public void setPrevious(Node<T> previous)
{
this.previous = previous;
}
}
My LinkedList class:
public class LinkedList<T extends Node<T>>
{
private Node<T> head;
private Node<T> tail;
private Node<T> currNode;
public LinkedList()
{
head = null;
tail = null;
currNode = null;
}
public LinkedList(Node<T> head)
{
this.head = head;
tail = head;
currNode = head;
}
public void resetHead()
{
currNode = head;
}
public void add(T data)
{
Node<T> newNode = new Node<T>(data);
newNode.next = null;
if(head == null)
{
head = newNode;
}
else
{
tail.next = newNode;
newNode.previous = tail;
tail = newNode;
}
}
public void addHead(T data)
{
Node<T> newNode = new Node<T>(data);
newNode.next = head;
head.previous = newNode;
head = newNode;
}
public void addAfter(T data, Node<T> previousNode)
{
Node<T> newNode = new Node<T>(data);
newNode.next = previousNode.next;
previousNode.next = newNode;
}
public void addBefore(T data, Node<T> nextNode)
{
Node<T> newNode = new Node<T>(data);
newNode.next = nextNode;
nextNode.previous = newNode;
}
public void delete(Node<T> nodeToDelete)
{
(nodeToDelete.getNext()).setPrevious(nodeToDelete.getPrevious());
(nodeToDelete.getPrevious()).setNext(nodeToDelete.getNext());
nodeToDelete.setNext(null);
nodeToDelete.setPrevious(null);
}
public boolean hasNext()
{
if(head == null)
{
return false;
}
else if(currNode.next != null)
{
currNode = currNode.getNext();
return true;
}
else
{
return false;
}
}
public boolean hasPrevious()
{
if(tail == null)
{
return false;
}
else if(currNode.previous != null)
{
currNode = currNode.getPrevious();
return true;
}
else
{
return false;
}
}
public Node<T> getHead()
{
return head;
}
public void setHead(Node<T> head)
{
this.head = head;
}
public Node<T> getTail()
{
return tail;
}
public void setTail(Node<T> tail)
{
this.tail = tail;
}
public Node<T> getCurrNode()
{
return currNode;
}
public void setCurrNode(Node<T> currNode)
{
this.currNode = currNode;
}
}
The error crops up when attempting to use any of the add/insert methods in LinkedList. For example, if I try to use the add(T data) method, like so: listOfChars.add('B');, I get the following error: The method add(Node) in the type LinkedList is not applicable for the arguments (char). What I expect it to do is to accept the data (in this case, the char 'B'), create a new node with 'B' as the data, and then put it in the linked list after the last node in the list. From my understanding, the method is expecting a Node instead of any generic data type, such as a char.
After doing some researching, I think somewhere in my TestLinkedList class, I have declared the LinkedList object incorrectly:
public class TestLinkedList
{
public static void main(String[]args)
{
Node<Character> n1 = new Node<Character>('A');
LinkedList listOfChars = new LinkedList(n1);
listOfChars.add('B');
}
}
but I can't figure out how to declare it correctly. I've tried LinkedList<Character>, LinkedList<Node>, LinkedList<Node<T>>, and LinkedList<Node<Character>>, but none of them are correct. Any help would be appreciated as this is my first time using generics and I am just trying to learn how to apply it to a Linked List I've made.
You need to fix two things. First, the class declaration of LinkedList says:
public class LinkedList<T extends Node<T>> {
which means that T has to be both a Node and the element of a Node. This doesn't work with Character since a Character is not an instance of Node. If you remove the constraint so that T can be any value, it works with Character.
public class LinkedList<T> {
Next you should add the generic part to the main file for the listOfChars as well:
LinkedList<Character> listOfChars = new LinkedList<Character>(n1);
Also make sure that you have imported the right LinkedList and not the java standard class.
You simply have to rewrite LinkedList from
LinkedList<T extends Node<T>>
to
LinkedList<T>
since in the code of LinkedList you already state that you are using Node objects.
You can use it like this:
public static void main(String[]args)
{
Node<Character> n1 = new Node<>('A');
LinkedList<Character> listOfChars = new LinkedList<>(n1);
listOfChars.add('B');
}
I think its a combination of both Todd's and Adams answer
public class LinkedList<T extends Node<T>>
to
public class LinkedList<T>
and
LinkedList<Character> listOfChars = new LinkedList<>(n1);
As you can infer from the error The method add(Node) in the type LinkedList is not applicable for the arguments (char)
This is a type error, your add method expects a Node but in the main you call add with type character.
Your LinkedList class is expecting an object of type T extends Node. Which would imply a custom class that extends your Node object, however that is not what you are looking to use to add objects to the linkedlist.
Ok, so your class declaration
public class LinkedList<T extends Node<T>>
is saying 'This is a class LinkedList parameterised by T where T is a subtype of Node<T>
This means if you wanted T = Character for example, you would need Character to be a subtype of Node<Character>, which doesn't really make sense.
You probably want to just parameterise your class by T eg public class LinkedList<T>
Then you can go LinkedList<Character> listOfChars = new LinkedList<Character>(n1)
or more succinctly LinkedList<Character> listOfChars = new LinkedList<>(n1) as the second generic parameter can be inferred
Create your LinkedList like this:
LinkedList<Character> listOfChars = new LinkedList<>(n1);
EDIT:
M4ver1k is right that this alone won't fix it. I missed the part that Adam Arold pointed out. Adam's answer fixes the problem and should be accepted. My answer just prevents the LinkedList from being implicitly defined as a LinkedList<Object>.
.
The question is this:
Define a constructor that takes a TreeSet as a parameter and initializes a linked list with the elements in the set. The new list must be sorted in increasing lexicographic order.
This method is to be implemented using the class below:
public class LinkedList<T extends Comparable<T>> {
private class Node{
private T data;
private Node next;
private Node(T data){
this.data = data;
next = null;
}
}
private Node head;
public LinkedList(){
head = null;
}
Now I know a TreeSet is inherently sorted so all I'd really have to do here is take the element from the TreeSet and put it to the front of this linked list. But I'm having trouble retrieving the element from the set and adding it to the LinkedList. I wrote a private helper add(T data) method and am using it but I don't know if this is how I should approach it. I'm new to data structures so have little idea about sets and their implementations.
public class LinkedList<T extends Comparable<T>> {
private class Node{
private T data;
private Node next;
private Node(T data){
this.data = data;
next = null;
}
}
private Node head;
public LinkedList(){
head = null;
}
public void add(T data){
Node n = new Node(data);
if(head == null){
head = n;
}
else{
n.next = head;
head = n;
}
}
public LinkedList(TreeSet<T> test){
Iterator<T> itr = test.iterator();
while(itr.hasNext()){
this.add(itr.next());
}
}
The main problem you have to solve is that you need to add each item to the end of the list not the start.
Adding a node to the start of the list is easy:
public void addToHead(T data) {
Node node = new Node(data);
node.next = head;
head = node;
}
Adding to the end is harder because you don't have a reference to the tail. But the solution is fairly simple: in the constructor you are developing, keep a reference to the tail of the list so that you can add each value at the end of the links rather than the start.
The question includes "increasing lexicographic order."
My solution is without helper method:
public LinkedList(TreeSet<T> test){
Node currNode = null;
for(T data : test) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
currNode = head;
}
else {
currNode.next = newNode;
currNode = currNode.next;
}
}
}
Hey ya'll I am having a little trouble with my singly linked list. I decided to create a simple one because we do not get enough practice during my data structures class and cannot seem to find why I am not getting the right output.
The code is:
package linked_list;
public class LinkedList {
private Node head;
private Node tail; // After figuring out head, come back to this FIXME
private int listSize;
public LinkedList() {
head = new Node(null);
tail = new Node(null);
}
public void addLast(String s) {
Node newNode = new Node(s);
if (head == null) {
addFirst(s);
} else {
while (head.next != null) {
head = head.next;
}
head.next = newNode;
tail = newNode;
}
listSize++;
}
public void addFirst(String s) {
Node newNode = new Node(s);
if (head == null) {
head = newNode;
tail = newNode;
}
else {
newNode.next = head;
head = newNode;
}
listSize++;
}
public Object getFirst() {
return head.data;
}
public Object getLast() {
return tail.data;
}
public void clear() {
head = null;
tail = null;
listSize = 0;
}
public Object peek() {
try {
if (head == null) {
throw new Exception ("The value is null");
}
else {
return head;
}
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
public int size() {
return listSize;
}
// This class has the ability to create the nodes that are used
// in the Linked List.
private class Node {
Node next;
Object data;
public Node(String value) {
next = null;
data = value;
}
public Node(Object value, Node nextValue) {
next = nextValue;
data = value;
}
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
}
Now here is my driver that I created to run a simple little operation:
package linked_list;
public class LinkedListDriver {
public static void main(String[] args) {
LinkedList list1 = new LinkedList();
list1.clear();
list1.addLast("This goes last");
list1.addFirst("This goes first");
list1.addLast("Now this one goes last");
System.out.println(list1.getFirst());
System.out.println(list1.getLast());
}
}
My output is this:
This goes last
Now this one goes last
I guess my question is why am I not getting the answer This goes first from my getFirst() method. It seems to be something wrong with the order or structure of that method but I cannot pinpoint it.
When you are in the else in the addLast, you are changing the reference to head. You should use another reference pointer to traverse the list when adding in the else.
Also, your list size should only be incremented in the else in addLast because you are incrementing twice otherwise (once in addFirst and again after the if-else in addLast).
I am creating a singly linked circular list and I don't seem to understand why it is not working. Here is my code. Would someone help me and point out what am I doing wrong? I am able to add the first node but I don't understand how to add the second node. Could someone show me how to change it. I think my list is traversing endlessly that's why.
public class CircularList <E> {
private Node<E> head;
private class Node <E>
{
E data;
Node <E> next;
public Node(E data, Node<E> next)
{
this.data = data;
this.next = next;
}
public Node(E data)
{
this.data = data;
this.next = null;
}
}//node
public CircularList()
{
head = null;
}
public void add(E data)
{
Node <E> temp = new Node <E> (data);
if(head==null)
{
head=temp;
temp.next=temp;
System.out.println(head.next.data);
}
else
{
Node<E> temp2 = head.next;
while(temp2!=head)
{
if(temp2.next==head)
{
temp2.next=temp;
temp.next=head;
}
temp2=temp2.next;
}
}
}
Update your else part with this;
Node<E> temp2 = head;
while(temp2.next != head)
{
temp2=temp2.next;
}
temp2.next=temp;
temp.next=head;
If you would like to make your singly linked list circular, it would be a good idea to have a tail, then your code can be something along the lines of (pseudo code)
function addElement(data){
Node n = new Node(data)
if(list.isEmpty() ){
head = n
tail = n
n.setNext(n)
} else {
n.setNext(head)
tail.setNext(n)
head = n
}
}