Don't understand why my addFirst() method doesn't work. When I ask for the size of list, it returns 1 but I added 3 words. It looks like the program takes only one element and forgets about the previous. I removed all the other irrelevant code and left only the one connected to my question with the addFirst() method. Here's the code:
Node object:
public class Node<Type> {
private Type data;
private Node<Type> next;
public Node(Type data) {
this.data = data;
next = null;
}
public Type getData() {
return data;
}
public void setData(Type data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
Main Method:
public class MyMain<Type> {
public static void main(String[] args) {
MyList<String> list = new MyList<String>();
System.out.println("The size is: " + list.size());
String s1 = "Summer";
String s2 = "Spring";
String s3 = "Winter";
list.addFirst(s2);
list.addFirst(s3);
list.addFirst(s1);
System.out.println("The size is: " + list.size());
}
}
Linked List:
public class MyList<Type> {
private Node<Type> head;
public MyList() {
head = null;
}
public int size() {
int length = 0;
Node<Type> current = head;
while (current != null) {
current = current.getNext();
length++;
}
return length;
}
public void addFirst(Type data) {
Node<Type> newFirst = new Node<Type>(data);
if (head == null) {
head = newFirst;
} else {
newFirst = newFirst.getNext();
newFirst = head;
head = newFirst.getNext();
}
}
}
Very confused and would appreciate any help, thank you!
I added comments to your original code, to explain what it actually does.
If you want addFirst to put the new element at the head of the list, you should change:
public void addFirst(Type data) {
Node<Type> newFirst = new Node<Type>(data);
if (head == null) {
head = newFirst;
} else {
newFirst = newFirst.getNext(); // here you assign null to newFirst
newFirst = head; // head you assign the old head to newFirst
head = newFirst.getNext(); // here you assign null to head, making the list empty
}
}
to:
public void addFirst(Type data) {
Node<Type> newFirst = new Node<Type>(data);
if (head == null) {
head = newFirst;
} else {
newFirst.setNext(head); // the old head of the list should be the
// next element of the new Node
head = newFirst; // make the new Node the head of the list
}
}
Your logic inside the else block of the addFirst method is not correct.
Your code in the addFirst method creates a new node, saves its reference in newFirst variable but then immediately discards the new node as a result of the following statement:
newFirst = newFirst.getNext();
Following statement then points newFirst to the node referenced by the head which is the first node inserted in the list.
newFirst = head;
Finally, you assign null to head:
head = newFirst.getNext();
Solution:
What you need to do is:
Set next of the newFirst to the node referenced by the head
newFirst.setNext(head);
Point head to the newFirst node
head = newFirst;
Full method code:
public void addFirst(Type data) {
Node<Type> newFirst = new Node<Type>(data);
if (head == null) {
head = newFirst;
} else {
newFirst.setNext(head);
head = newFirst;
}
}
Related
I implemented a solution to reverse a linked list in java that I found online. But it is not working in my code for some reason.
When I print the list it only prints the first node. I know the print method works because it prints the whole thing when I don't try to reverse.
Where did I go wrong in this code?
public class LinkedLists {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addLast(10);
list.addLast(20);
list.addLast(30);
list.reverseList();
list.print();
}
public static class LinkedList{
private class Node{
private int value;
private Node next;
}
public Node first;
public Node last;
public void addLast(int item){
Node node = new Node();
node.value = item;
if(first == null) {
first = node;
last = node;
} else {
last.next = node;
last = node;
}
}
private Node reverse(Node head, Node newHead) {
//base case: when first = last you return
if(head == null) {
return newHead;
}
Node temp = head.next;
head.next = newHead; //this will initially be null
newHead = head;
head = temp;
return reverse(head, newHead);
}
public Node reverseList() {
return reverse(first, null);
}
public void print(){
Node current = first;
while (current != null){
System.out.print(current.value + " ");
current = current.next;
}
}
} //class ends
}
Although reverse returns the correct reference for the new head, the initial call of reverseList -- in the main program -- ignores this returned reference.
Your reverseList method should better not return anything, but instead update the first and last members:
public void reverseList() {
last = first;
first = reverse(first, null);
}
I am trying to rearrange a Singly linked list. The initial list will be 1,2,3,4,5
and they have to be sorted in 1,5,2,4,3. I have the code and I am trying to understand how it works. Basically I am stuck at the concept of pass by value in java.
The complete code
public class Test {
public static void main(String[] args) {
LinkedLists linkedList = new LinkedLists();
linkedList.append(1);
linkedList.append(2);
linkedList.append(3);
linkedList.append(4);
linkedList.append(5);
linkedList.reorderList();
}}
class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
}}
class LinkedLists {
Node head;
public void reorderList() {
if (head == null) {
System.out.println(head);
return;
}
Node slowPointer = head;
Node fastPointer = head.next;
System.out.println(slowPointer.hashCode());
System.out.println(head.hashCode());
while (fastPointer != null && fastPointer.next != null) {
fastPointer = fastPointer.next.next;
slowPointer = slowPointer.next;// why head value did not change
}
Node head2 = slowPointer.next;
slowPointer.next = null;// why did the head value change here
LinkedList<Node> queue = new LinkedList<Node>();
while (head2 != null) {
Node temp = head2;
head2 = head2.next;
temp.next = null;
queue.push(temp);
}
while (!queue.isEmpty()) {
Node temp = queue.pop();
temp.next = head.next;
head.next = temp;
head = temp.next;
}
}
public void append(int data) {
if (head == null) {
head = new Node(data);
return;
}
Node current = head;
while (current.next != null) {
current = current.next;
}
current.next = new Node(data);
}}
The value of head does not get changed at line
slowPointer = slowPointer.next;// why head value did not change
But at line
slowPointer.next = null;// why did the head value change here
Why does it change here. Thanks.
Because in the first case you are assigning the object pointed by next to the slowPointer.
But in second case you are modifying the value of 'next' of the object being pointed by the reference slowPointer. So the head object is directly modified.
I am trying to insert element at the end of a linked list insertAtEnd(). When I debug the code I see a node(0,null) is being inserted as default in the beginning of the insertion. I think this is causing the problem while iterating through the list. Any suggestions on how fix this?
package com.ds.azim;
public class Node {
//Node has 1. Data Element 2. Next pointer
public int data;
public Node next;
//empty constructor
public Node(){
//
}
public Node(int data){
this.data= data;
this.next = null;
}
public Node(int data, Node next){
this.data = data;
this.next = next;
}
}
//*************************************//
package com.ds.azim;
public class SingleLinkedList {
//Single Linked list has a head tail and has a length
public Node head;
public Node tail;
public int length;
//constructor
public SingleLinkedList(){
head = new Node();
length = 0;
}
public void insertAtFirst(int data){
head = new Node(data,head);
}
public void insertAtEnd(int data){
Node curr = head;
if(curr==null){
insertAtFirst(data);
}else{
while(curr.next!=null){
curr = curr.next;
}
curr.next = new Node(data,null);
}
}
public void show(){
Node curr = head;
while(curr.next!=null){
//do something
System.out.print(curr.data+",");
curr = curr.next;
}
}
public static void main(String[] args){
SingleLinkedList sll = new SingleLinkedList();
sll.insertAtFirst(12);
sll.insertAtFirst(123);
sll.insertAtFirst(890);
sll.insertAtEnd(234);
sll.show();
}
}
Along with removing this part of the code
public SingleLinkedList() {
head = new Node();
length = 0;
}
change your show function as well, because this will not print the last element
while(curr.next!=null){
//do something
System.out.print(curr.data+",");
curr = curr.next;
}
after this while, put one more print statement to print the last element.
System.out.print(curr.data);
this will fix the errors.
Your code initializes the list with a Node containing (0, null) and head pointing to it. To fix this, don't do that.
public SingleLinkedList() {
head = new Node();
length = 0;
}
Also in that code you set length = 0;, but actually the length is 1. Remove both the assignments from the constructor. Then you will have a structure with zero members and the length will be correct.
You have a tail variable which should point to the last node in your list. You should be keeping it up to date:
class SingleLinkedList {
private Node head = null;
private Node tail = null;
public void addAtHead(int data) {
if (head == null) {
addFirst(data);
} else {
head.next = new Node(data, head.next);
if (tail == head)
tail = head.next;
}
}
public void addAtTail(int data) {
if (head == null) {
addFirst(data);
} else {
assert tail != null;
assert tail.next == null;
tail.next = new Node(data);
tail = tail.next;
}
}
private void addFirst(int data) {
assert head == null;
assert tail == null;
head = new Node(data);
tail = head;
}
}
If you want to remove the tail variable, then:
class SingleLinkedList {
private Node head = null;
public void addAtHead(int data) {
if (head == null) {
head = new Node(data);
} else {
head.next = new Node(data, head.next);
}
}
public void addAtTail(int data) {
if (head == null) {
head = new Node(data);
} else {
Node curr = head;
while (curr.next != null)
curr = curr.next;
curr.next = new Node(data);
}
}
}
I made a singly linked list from scratch in java. The code is as follows:
public class SingleLinkedList<Item>
{
private Node head;
private int size;
private class Node
{
Item data;
Node next;
public Node(Item data)
{
this.data = data;
this.next = null;
}
public Node(Item data, Node next)
{
this.data = data;
this.next = next;
}
//Getters and setters
public Item getData()
{
return data;
}
public void setData(Item data)
{
this.data = data;
}
public Node getNext()
{
return next;
}
public void setNext(Node next)
{
this.next = next;
}
}
public SingleLinkedList()
{
head = new Node(null);
size = 0;
}
public void add(Item data)
{
Node temp = new Node(data);
Node current = head;
while(current.getNext() != null)
{
current = current.getNext();
}
current.setNext(temp);
size++;
}
public void add(Item data, int index)
{
Node temp = new Node(data);
Node current = head;
for(int i=0; i<index && current.getNext() != null; i++)
{
current = current.getNext();
}
temp.setNext(current.getNext());
current.setNext(temp);
size++;
}
public Item get(int index)
{
if(index <= 0)
{
return null;
}
Node current = head;
for(int i=1; i<index; i++)
{
if(current.getNext() == null)
{
return null;
}
current = current.getNext();
}
return current.getData();
}
public boolean remove(int index)
{
if(index < 1 || index > size())
{
return false;
}
Node current = head;
for(int i=1; i<index; i++)
{
if(current.getNext() == null)
{
return false;
}
current = current.getNext();
}
current.setNext(current.getNext().getNext());
size--;
return true;
}
public String toString()
{
Node current = head.getNext();
String output = "";
while(current != null)
{
output+=current.getData().toString()+" ";
current = current.getNext();
}
return output;
}
public int size()
{
return size;
}
public void reverse()
{
Node current = head;
Node prevNode = null;
Node nextNode;
while(current!=null)
{
nextNode = current.getNext();
current.setNext(prevNode);
prevNode = current;
current = nextNode;
System.out.println(prevNode.getData());
}
head = prevNode;
}
}
As you can see, I added the reverse function in the class only.
But when I tried actually using the class it gave NullPointerException after I tried to reverse it.
To check the functionality I used another class called TEST. The code is as follows:
public class TEST
{
public static void main(String[] args)
{
SingleLinkedList<Integer> list = new SingleLinkedList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list.toString());
list.reverse();
System.out.println(list.toString());
}
}
The output is as follows:
1 2 3 4 5
null
1
2
3
4
5
Exception in thread "main" java.lang.NullPointerException
at SingleLinkedList.toString(SingleLinkedList.java:129)
at TEST.main(TEST.java:20)
I tried to print the value of prevNode to check whether its not taking values...but it is.
What to do?
Actually, your reverse method looks fine.
The problem is your toString() method.
When you create a new list, you create an initial element whose data is null.
Your toString method skips that first element, so it works fine as long as you don't reverse the list.
But when you reverse the list, that null element becomes the last element, and when you call output+=current.getData().toString()+" "; for that last element when current.getData() is null, you get NullPointerException.
You have several options :
Your reverse method can keep the initial null element first (i.e. reverse the rest of the list, but keep the head the same). This way toString can remain unchanged.
Eliminate the initial null element. Then your toString method doesn't have to skip anything.
Keeping the null element first :
public void reverse()
{
Node current = head.getNext();
Node prevNode = null;
Node nextNode;
while(current!=null)
{
nextNode = current.getNext();
current.setNext(prevNode);
prevNode = current;
current = nextNode;
System.out.println(prevNode.getData());
}
head.setNext(prevNode);
}
The problem is in your SingleLinkedList.java toString() method
Try below it is working fine
public String toString() {
Node current = head;
String output = "";
while (current != null) {
// output += current.getData().toString() + " ";
output += String.valueOf(current.getData()) + " ";
current = current.getNext();
}
return output;
}
while(current!=null)
This is your problem. When you hit the last node the 'next' node you get is actually null.
Try changing it to
while(current!=null&¤t.getNext()!=null)
EDIT: Actually not sure that solution will work. Try putting a conditional at the end of your loop that says:
if(current.getNext()==null)
break;
EDIT (again :/):
ok sorry I wasn't thinking straight.
change that final if statement to:
if(current.getNext()==null){
current.setNext(prevNode);
break;
}
The actual nullpointer is in the toString. Here's what you do:
Change the while conditional to
while(current != null&¤t.getData()!=null)
Because otherwise if current points to null then you get an exception.
That was exhausting.
This is my first post here, but I'm not new to the site (call me a lurker).
Unfortunately this time I cannot seem to find an answer to my question without asking.
Anyway, to the point.
I am writing a small snakes and ladders (aka chutes and ladders) program in java for a data structures course. I had to write my own Linked List (LL) class, (I know that there is a java util that does it better, but I have to learn about the workings of the data structure) and that is not a problem. My LL is 'semi-Double linked' as I like to call it, since it links forward, but has another pointer field for other links, which is not necessarily used in every node.
What I want to know is if it is possible to link a node from a list to another list, which is of a different type.
Poor example:
(eg.) How would one link a node of type to a node of type ? Let us say we have a LL of 7 int values [1,2,3,4,5,6,7], and a LL of 7 Strings [Monday, Tuesday, Wednesday,Thursday, Friday, Saturday, Sunday]. We want to link the node containing 1 to the node containing Monday.
To be exact the problem I am having is as follows:
I have 100 nodes forward-linked, forming the game board, and a circularly linked list of 4 . I want to link the player nodes to their respective positions on the board, so that as they traverse the board, they can also follow the "snakes" and "ladders" links.
Thanks in advance!
My LLNode.java and LL.java are attached.
// LLNode.java
// node in a generic linked list class, with a link
public class LLNode<T>
{
public T info;
public LLNode<T> next, link;
public LLNode()
{
next = null;
link= null;
}
public LLNode(T element)
{
info = element;
next = null;
link = null;
}
public LLNode(T element, LLNode<T> n)
{
info = element;
next = n;
link = null;
}
public T getInfo()
{
return info;
}
public void setInfo(T element)
{
info = element;
}
public LLNode<T> getNext()
{
return next;
}
public void setNext(LLNode<T> newNext)
{
next = newNext;
}
public LLNode<T> getLink()
{
return link;
}
public void setLink(LLNode<T> newLink)
{
link = newLink;
}
}
// SLL.java
// a generic linked list class
public class LL<T>
{
private LLNode<T> head, tail;
public LLNode<T> current = head;
public LL()
{
head = tail = null;
}
public boolean isEmpty()
{
return head == tail;
}
public void setToNull()
{
head = tail = null;
}
public boolean isNull()
{
if(head == tail)
if(head == null || tail == null)
return true;
else
return false;
else
return false;
}
public void addToHead(T element)
{
head = new LLNode<T>(element, head);
if (tail == null)
tail = head;
}
public void addNodeToHead(LLNode<T> newNode)
{
head = newNode;
if (tail == null)
tail = head;
}
public void addToTail(T element)
{
if (!isNull())
{
tail.next= new LLNode<T>(element);
tail = tail.next;
}
else head = tail = new LLNode<T>(element);
}
public void addNodeToTail(LLNode<T> newNode)
{
if (!isNull())
{
tail.next= newNode;
tail = tail.next;
}
else head = tail = newNode;
}
public void addBefore(T element, T X)
{
if (!isEmpty()) // Case 1
{
LLNode<T> temp, n;
temp = head;
while( temp.next != null )
{
if( temp.next.info == X )
{
n = new LLNode<T>(element, temp.next);
temp.next = n;
return;
}
else
temp = temp.next;
}
}
else // Case 2
head = new LLNode<T>(element, head);
}
public void addBefore(T element, LLNode<T> X)
{
if (!isEmpty()) // Case 1
{
LLNode<T> temp, n;
temp = head;
while( temp.next != null )
{
if( temp.next == X )
{
n = new LLNode<T>(element, X);
temp.next = n;
return;
}
else
temp = temp.next;
}
}
else // Case 2
head = new LLNode<T>(element, head);
}
public T deleteFromHead()
{
if (isEmpty())
return null;
T element = head.info;
if (head == tail)
head = tail = null;
else head = head.next;
return element;
}
public T deleteFromTail()
{
if (isEmpty())
return null;
T element = tail.info;
if (head == tail)
head = tail = null;
else
{
LLNode<T> temp;
for (temp = head; temp.next != tail; temp = temp.next);
tail = temp;
tail.next = null;
}
return element;
}
public void delete(T element)
{
if (!isEmpty())
if (head == tail && (element.toString()).equals(head.info.toString()))
head = tail = null;
else if ((element.toString()).equals(head.info.toString()))
head = head.next;
else
{
LLNode<T> pred, temp;
for (pred = head, temp = head.next; temp != null && !((temp.info.toString()).equals(element.toString())); pred = pred.next, temp = temp.next);
if (temp != null)
pred.next = temp.next;
if (temp == tail)
tail = pred;
}
}
public void listAll()
{
if(isNull())
System.out.println("\tEmpty");
else
{
for ( LLNode<T> temp = head; temp!= tail.next; temp = temp.next)
System.out.println(temp.info);
}
}
public LLNode<T> isInList(T element)
{
LLNode<T> temp;
for ( temp = head; temp != null && !((temp.info.toString()).equals(element.toString())); temp = temp.next);
return temp ;
}
public LLNode<T> getHead()
{
return head;
}
public LLNode<T> getTail()
{
return tail;
}
public LLNode<T> getCurrent()
{
return current;
}
public void incrementCurrent()
{
current = current.next;
}
public void followCurrentLink()
{
current = current.link;
}
}
Any specific reason you want to generics for the specific problem domain of the node objects?
If you want to have this effect, another way to do it might be have an interface for node object (maybe call it ILinkNode), have the getInfo and setInfo overridden in two different node classes. Then the nodeLink can point to interface object without special type casting everywhere in the code.
Use in the first list, i.e. the one containing the node you want to link to the node in the other list, Object as the generic type instantiation.
Something like:
LL<Object> ll = new LL<Object>();
If you do this, you have to take care to cast to the specific type, each time you retrieve a node's value from the list.