LinkedList Insert Last - java

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);
}
}
}

Related

AddFirst() method doesn't work in my Linked List

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;
}
}

Why am I not able to insert elements into my linked-list implementation?

I am doing linkedlist implementation in java. Particularly, while doing insert operation, if the given index is more than the length of the linkedlist, I have to append the value to the linkedlist. Though I have written code for the same, it is not happening that way.
In order to debug this, I added lines for printing linkedlist. I could print the list just before the condition if(index >= this.length()) in the insert function but not able to print the linkedlist in the line inside the condition.
package com.learning.algorithms.LinkedList;
public class Node {
int data;
Node next;
public Node() {
}
public Node(int i) {
this.data = i;
this.next = null;
}
}
package com.learning.algorithms.LinkedList;
public class LinkedList {
Node head;
Node tail;
public LinkedList() {
this.head = new Node();
this.tail = this.head;
}
public LinkedList(int value) {
this.head = new Node();
this.head.data = value;
this.head.next = null;
this.tail = this.head;
}
public LinkedList append(int value) {
Node newNode = new Node(value);
this.tail.next = newNode;
this.tail = newNode;
return this;
}
public void printList() {
Node useNode = this.head;
while(useNode!=null)
{
System.out.println(useNode.data);
useNode = useNode.next;
}
//print(useNode);
}
private void print(Node useNode) {
if(useNode!=null)
{
System.out.println(useNode.data);
print(useNode.next);
}
}
public LinkedList prepend(int i) {
Node newNode = new Node(i);
newNode.next = this.head;
this.head = newNode;
return this;
}
public LinkedList insert(int index, int value) {
if(index == 0)
{
this.prepend(value);
return this;
}
this.printList();
if(index >= this.length())
{
System.out.println("inside");
this.printList();
this.append(value);
return this;
}
Node nodeJustBeforeGivenIndex = this.head;
// getting node just before given index using while loop
while(index>1)
{
nodeJustBeforeGivenIndex = nodeJustBeforeGivenIndex.next;
index--;
}
// make an insert
Node newNode = new Node(value);
newNode.next = nodeJustBeforeGivenIndex.next;
nodeJustBeforeGivenIndex.next = newNode;
return this;
}
private int length() {
int counnt = 0;
if(this.head !=null ) {
while(this.head !=null )
{
this.head = this.head.next;
counnt++;
}
}
return counnt;
}
}
package com.learning.algorithms.LinkedList;
public class LinkedListImplementation {
public static void main(String[] args)
{
LinkedList list = new LinkedList(10);
list.append(5);
list.append(16);
list.prepend(1);
list.insert(0, 15);
list.insert(10, 222);
list.printList();
}
}
Console output for running this implementation class:
15
1
10
5
16
inside
You should not modify the head value inside the length method.
This will fix it:
private int length() {
int counnt = 0;
Node iter = this.head;
while(iter !=null )
{
iter = iter.next;
counnt++;
}
return counnt;
}
Commenting just the two print stamtents inside insert, the output gets to be:
inside
15
1
10
5
16
222

Pass by value Linked list

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.

Adding at the End

Thank you for taking the time to read this, I'm currently taking a Java class and the professor told us that a good practice to understand links would be to make a doubly linked list. I have made a singly linked list but I am having trouble converting it to a doubly linked list. The problem I am having is I'm trying to add a number to the end of the list but when I try to add a new number to the end it just shows that numbers and not the others. I think I'm just creating a new list and displaying that but I'm not sure. An example of code would be really appreciated.
Normal Add Code:
public void add(int element){
Node n = new Node();
n.setItem(element);
n.setNext(head);
n.setBefore(null);
if(head != null) {
head.setBefore(n);
}
head = n;
}
The add to last code:
public void addLast(int element) {
Node currentNode = head;
currentNode.setItem(element);
currentNode.setBefore(tail);
currentNode.setNext(null);
tail = currentNode;
}
FULL CODE:
public class DoubleLink {
private Node head;
private Node tail;
//Methods
//Constructors
public DoubleLink(){
head = null;
tail = null;
}
public void add(int element){
Node n = new Node();
n.setItem(element);
n.setNext(head);
n.setBefore(null);
if(head != null) {
head.setBefore(n);
head = n;
}
public void display(){ //LIST TRAVERSAL!
// Reference traversal
//Needed an interatior
Node currentNode = head;
while(currentNode != null){
System.out.print(currentNode.getItem()+ " ");
currentNode = currentNode.getNext();
}
System.out.println();
}
public int search(int element){
int position = 0;
Node currentNode = head;
while(currentNode != null){
if(currentNode.getItem() == element){
return position;
}
position++;
currentNode = currentNode.getNext();
}
return -1;
}
public void insert(int element, int position){
int currentposition = 0;
Node currentNode = head;
//Traverse to the right position
while(currentposition < position-1){
currentposition++;
}
Node n = new Node();
n.setItem(element);
n.setNext(currentNode.getNext());
currentNode.setNext(n);
//The previous number connecting to the new number
currentNode = tail;
}
public void remove(int position){
int currentposition = 0;
Node currentNode = head;
//Traverse to the right position
while(currentposition < position-1){
currentposition++;
}
Node dyingNode = currentNode.getNext();
currentNode.setNext(dyingNode.getNext());
}
public void addLast(int element) {
Node nodeToInsert = new Node();
nodeToInsert.setItem(element);
nodeToInsert.setBefore(tail);
nodeToInsert.setNext(null);
if(tail != null)
tail.setNext(nodeToInsert); //link the list
tail = nodeToInsert; //now the tail is the new node i added
if(head == null) // if the list has no elements then set the head
head = nodeToInsert;
}
public static void main(String[] args) {
DoubleLink l = new DoubleLink();
l.add(1);
l.add(2);
l.add(3);
l.display();
l.addLast(99);
l.display();
}
}
Node Class:
public class Node {
//Data
private int item;
private Node next;
private Node before;
//Methods
public int getItem(){
return item;
}
public void setItem(int item){
this.item = item;
}
public Node getNext(){
return next;
}
public void setNext (Node next){
this.next = next;
}
public Node getBefore(){
return before;
}
public void setBefore(Node before){
this.before = before;
}
}
You should change your code, creating a new Node() like this.
public void addLast(int element) {
Node nodeToInsert = new Node();
nodeToInsert.setItem(element);
nodeToInsert.setBefore(tail);
nodeToInsert.setNext(null);
if(tail != null)
tail.setNext(nodeToInsert); //link the list
tail = nodeToInsert; //now the tail is the new node i added
if(head == null) // if the list has no elements then set the head
head = nodeToInsert;
}
UPDATE
The problem is in your add method , you are not setting never tail
public void add(int element){
Node n = new Node();
n.setItem(element);
n.setNext(head);
n.setBefore(null);
if(head != null)
head.setBefore(n);
else{
tail=n; // if head == null then now you have an element so head = tail
}
head = n;
}
Try this :
public void addLast(int element) {
Node newNode = new Node();
newNode.setItem(element);
newNode.setNext(null);
newNode.setBefore(tail);
tail.setNext(newNode);
tail = newNode;
}
In addlast(int element) you are not creating memory for new node you just overwriting in the
head node.
So, your code goes like this
public void addlist(int element)
{
Node currentNode = new node();
currentNode.setItem(element);
currentNode.setBefore(tail);
currentNode.setNext(null);
if(tail!=null)
tail.setNext(currentNode);
tail = currentNode;
}

Linked list node pointing to nodes of different type

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.

Categories