LinkedList addToTail() not working - java

I can't figure why the addition to the tail of this LinkedList class is not working and is simply ignored in the output.
Here's a simple Node class:
public class IntNode {
private int val;
private IntNode next;
public IntNode() {
this.val = 0;
IntNode next = null;
}
public IntNode(int val) {
this.val = val;
this.next = null;
}
public IntNode next() {
return this.next;
}
public int getVal() {
return this.val;
}
public void setNextNode(int val) {
this.next = new IntNode(val);
}
public void setNextNode(IntNode a)
{
this.next = new IntNode(a.getVal());
}
public void setVal(int val) {
this.val = val;
}
public String toString() {
StringBuffer buff = new StringBuffer();
return toString(this, buff);
}
private String toString(IntNode node, StringBuffer buff) {
if (node == null) {
return buff.toString();
}
buff.append(node.val);
if (node.next != null) {
buff.append(", ");
} else {
buff.append(".");
}
return toString(node.next(), buff);
}
}
And here's the linked list for it:
public class LinkedList {
private IntNode header;
private IntNode trailer;
private int listSize;
public LinkedList()
{
this.header = null;
this.trailer = null;
this.listSize = 0;
}
public LinkedList(IntNode a, IntNode b)
{
this.header = a;
this.trailer = b;
this.header.setNextNode(this.trailer);
this.listSize = 2;
}
public void addNode(IntNode a)
{
this.trailer.setNextNode(a.getVal());
this.trailer = this.trailer.next();
this.listSize++;
}
public String toString()
{
return this.header.toString();
}
public static void main(String args[])
{
LinkedList lst = new LinkedList(new IntNode(1), new IntNode(2));
lst.addNode(new IntNode(3));
lst.addNode(new IntNode(4));
System.out.println(lst.toString());
}
}
The output of the main method is: 1, 2.
Why is the addition method not working?

In your constructor with two IntNodes, your header is not pointing to your trailer. Instead it points to a new IntNode(trailer.val). You should change
public void setNextNode(IntNode a)
{
this.next = a;
}

Your problem is that the LinkedList constructor sets header to a and trailer to b, but then calls header.setNextNode(this.trailer);
IntNode's method setNextNode() method discards the node that it is passed and instead creates a node with the same value as the one that it had passed in.
This means that at the end of your LinkedList constructor you have the header assigned to a which has a next node value of something other than b that has the same value as b, while trailer is set to b.
You should change your setNextNode() method to not discard the node it's handed in, as follows:
public void setNextNode(IntNode a) {
this.next = a;
}

In the constructor of the LinkedList class you have the code this.header.setNextNode(this.trailer);. This will not set the next node of the head to the trailer, but set the next node of the head to another node with the value of the trailer. When the trailer's next node is set, the head is not affected.

Related

Java Linked List add Method

I am attempting to implement a linked list that uses a node class containing head, tail, and current nodes. Part of the linked list is an add method that should add a value to the end of the current node in the list just like an actual linked list would. My issue is that it only works for the first node and then just stops there. For example, in my main I tried testing the code by calling add(1); and add(2);. The console shows me 1 but that's all. I'm unsure if the error is in my add method, toString method, or node class.
I'll also add that I tested whether the correct values were being assigned to "current" in either case, and they were. This has led me to wonder if it's the toString that is the root of the issues, however no matter how much I try I can't change it to make any improvements.
I've hoping fresh eyes may be able to find any blaring issues that may exist.
Add method:
public void add(int val){
if(current != null){
Node nextNode = new Node(val, current);
current = nextNode;
tail = nextNode;
}
else{
head = tail = new Node(val, null);
current = head;
}
}
Node class:
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = next;
}
}
toString:
public String toString(){
for(Node x = head; x != null; x = x.next){
System.out.println(x.data);
}
All:
public class IntLList extends IntList{
public IntLList(){
}
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = next;
}
}
Node head = null;
Node tail = null;
Node current = null;
public void add(int val){
if(current != null){
Node nextNode = new Node(val, current);
current = nextNode;
tail = nextNode;
}
else{
head = tail = new Node(val, null);
current = head;
}
}
public int get(int index){
return 0;
}
public void set(int index, int val){
}
public void remove(int index) throws ArrayIndexOutOfBoundsException{
}
public int size(){
return 0;
}
public String toString(){
for(Node x = head; x != null; x = x.next){
System.out.println(x.data);
}
return "temp";
}
public void removeLast(){
}
public boolean isEmpty(){
boolean isEmpty = false;
if(head == null){
isEmpty = true;
}
return isEmpty;
}
public void clear(){
}
public static void main(String[] args) {
IntLList i = new IntLList();
i.add(1);
i.add(2);
i.toString();
}
}
Make the following changes:
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = NULL; // this is to set the next node of current node to null
if(next!=NULL)
next.next=this; // this is to set the previous node to point to current node
}
}

Parsing Through ListNodes in List

I'm having trouble figuring out why my code won't parse through the ListNodes in the Lists, in order to add a new String as a ListNode. I'm trying to write the function add(String s), to add a new ListNode to the List. If the list is empty, I just add the String as a ListNode, and if not, I parse through using node and myNext, and then if node.myNext is null, I replace it with the newly created ListNode. What is the reason this isn't working? It either does not throw an output or it says it is out of bounds.
public class List {
private ListNode myHead;
private int mySize;
public List() {
this.myHead = null;
this.mySize = 0;
}
public class ListNode {
public String myData;
public ListNode myNext;
public ListNode(String element, ListNode next) {
this.myData = element;
this.myNext = next;
}
public ListNode(String element) {
this(element, null);
}
public boolean isEmpty() {
return this.length() == 0;
}
public void add(String s) {
if(this.isEmpty() == true) {
this.addToFront(s);
}
else {
this.mySize++;
for(ListNode node = this.myHead; node.myData != null; node = node.myNext) {
if(node.myNext == null) {
ListNode lno = new ListNode(s, null);
node.myNext = lno;
}
else {
node.myData = node.myData;
}
}
}
}
In you ListNode you can't access methods and variables of your List class.
Assuming that you want to add the new String at the top of your List you should do something like this:
public class List {
private ListNode myHead;
private int mySize;
public List() {
this.myHead = null;
this.mySize = 0;
}
public boolean isEmpty() {
return this.mySize == 0;
}
public void add(String s) {
this.myHead = new ListNode(s, myHead);//add new String as head element
this.mySize++;
}
}
public class ListNode {
public String myData;
public ListNode myNext;
public ListNode(String element, ListNode next) {
this.myData = element;
this.myNext = next;
}
public ListNode(String element) {
this(element, null);
}
}
If you want to add it at the end of your List you can try it like this:
public void add(String s) {
if(this.isEmpty()){
this.myHead = new ListNode(s, myHead);//add new String as head element
}else{
ListNode node = this.myHead;
while (node.myNext != null){
node = node.myNext;
}
//now you hav the last node of your list
node.myNext = new ListNode(s,null);
}
this.mySize++;
}
The code you have pasted is not complete.
Also, If I am correct, your List is having the ListNodes and thus, it is your List where you should put methods to check if it is Empty (does not have any ListNodes in it) or add, delete, count, search etc. functions.
For isEmpty(), There is no length() defined, so simply check the size to be == 0.
For add(), if it is empty just point myHead to your new ListNode; If you have to add in end, iterate the myHead using a currentNode reference, till its next is null and add.
If it is to be in middle somewhere, you will need to check for ListNode myData to decide where it fits white moving from myHead towards null and once you find a place to insert, you will need to change the [PrevNode] -> new ListNode -> [nextNode]

My implementation of a lock free linked list returns always an empty string on toString()

I am experimenting with lock free linked lists. This is my first shot but I have no idea why the toString method always returns an empty string even if I can see values in the debugger.
package com.linkedq;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
public class LinkedQueue <E> {
private static class Node <E> {
final E item;
final AtomicReference<Node<E>> next;
Node(E item, Node<E> next) {
this.item = item;
this.next = new AtomicReference<>(next);
}
#Override
public String toString() {
return item.toString();
}
}
private AtomicReference<Node<E>> head = new AtomicReference<>(new Node<E>(null, null));
private AtomicReference<Node<E>> tail = head;
public boolean put(E item) {
Node<E> newNode = new Node<E>(item, null);
while (true) {
Node<E> curTail = tail.get();
Node<E> residue = curTail.next.get();
if (curTail == tail.get()) {
if (residue == null) /* A */ {
if (curTail.next.compareAndSet(null, newNode)) /* C */ {
tail.compareAndSet(curTail, newNode) /* D */ ;
return true;
}
} else {
tail.compareAndSet(curTail, residue) /* B */;
}
}
}
}
public void remove(E item) {
Node<E> current = this.head.get().next.get();
Node<E> next = null;
while (current != null) {
next = current.next.get();
if (next.equals(item)) {
if (!current.next.compareAndSet(next, next.next.get())) {
// some other thread changed the list, do a retry
remove(item);
}
}
current = next;
}
}
#Override
public String toString() {
Node<E> current = head.get().next.get();
StringBuilder sb = new StringBuilder();
while (current != null) {
sb.append(current).append(", ");
current = current.next.get();
}
return sb.toString();
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService es = Executors.newFixedThreadPool(10);
final LinkedQueue<Integer> q = new LinkedQueue<>();
for (int i=0; i<10000; i++) {
es.execute(new Inserter(q, i));
}
// es.shutdown();
// es.awaitTermination(1L, TimeUnit.HOURS);
System.out.println("FIN" + q);
}
private static class Inserter implements Runnable {
private final LinkedQueue<Integer> q;
private final int value;
public Inserter(LinkedQueue<Integer> q, int value) {
this.q = q;
this.value = value;
}
#Override
public void run() {
q.put(value);
System.out.println("q = " + q);
}
}
}
At least one obvious error is that your head and tail are actually the same AtomicReference object, so when you update the tail, the head is updated as well. Use
private AtomicReference<Node<E>> head = new AtomicReference<>(new Node<E>(null, null));
private AtomicReference<Node<E>> tail = new AtomicReference<>(head.get());
Another obvious mistmatch is that the first element you add inside the tail and the head:
tail.compareAndSet(curTail, newNode) ;
While when you read, you start printing from the next of the head:
Node<E> current = head.get().next.get();
So even without having multiple threads, etc, just adding one element and printing the list does not work. Add unit tests to verify the behavior!

Linked list: Not working as expected

I created a singly linked list , it giving below error . not sure what is wrong, ant suggestion
Error/ OP - List is javaTest.LinkedListcreation#1540e19d
I am not sure what this value in Output is meant for .
Process finished with exit code 0
public class LinkedList{
public static void main (String[] a){
LinkedListcreation L1 = new LinkedListcreation();
L1.addNodeAtEnd("1");
System.out.print("List is " + L1);
}
}
class LinkedListcreation {
int listcount;
node head;
LinkedListcreation() {
head = new node(0);
listcount=0;
}
node Temp;
void addNodeAtEnd(Object d){
node Current = head;
Temp = new node(d);
while (Current.getNext()!= null){
Current = Current.getNext();
}
Current.setNext(Temp);
listcount++;
}
}
class node {
Object data;
node next;
node(Object d) {
next = null;
this.data=d;
}
node(Object d, node nextNode) {
next = nextNode;
this.data=d;
}
public Object getdata(){
return data;
}
public void setdata(int d){
data = d;
}
public node getNext(){
return next;
}
public void setNext (node nextValue){
next = nextValue;
}
}
Your code is all right, but in order to print useful information about an object (your list in this example), you need to override the toString method in your LinkedListcreation class.
For example:
public String toString() {
return "List with " + this.listcount + " nodes.";
}
As everybody said, you have to override toString(). Here you have the right implementation:
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append(head.data.toString());
node n;
while(n = head.getNext() != null)
sb.append(", " + n.data.toString());
sb.append("]");
return sb.toString();
}
you are trying to print the list object rather than the element which you have added and more over what you see is not error. check about toString() method in java to understand the output which you see.
Modify your main() as below to see the element you added.
public static void main (String[] a){
LinkedListcreation L1 = new LinkedListcreation();
L1.addNodeAtEnd("1");
System.out.print("List is " + L1.head.next.data);
}
output : List is 1
Your code does not have any error. If you want to print the nodes in your list you just have to add another function in you LinkedListcreation class which will iterate over your list and print each node's data. Add this block in your LinkedListcreation class.
public void printList(){
node current = head.next;
while(current!=null){
System.out.println("node's data is: "+ current.getdata());
current = current.getNext();
}
}
Also in your main function call the above mentioned function using your list's object L1.
L1.printList();
The code has compiler errors. Try corrected code below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class LinkedList
{
static void Main(String[] a){
LinkedListcreation L1 = new LinkedListcreation();
L1.addNodeAtEnd("1");
Console.WriteLine("List is " + L1);
}
}
public class LinkedListcreation
{
int listcount;
node head;
public LinkedListcreation()
{
head = new node(0);
listcount = 0;
}
node Temp;
public void addNodeAtEnd(Object d)
{
node Current = head;
Temp = new node(d);
while (Current.getNext() != null)
{
Current = Current.getNext();
}
Current.setNext(Temp);
listcount++;
}
}
public class node
{
Object data;
node next;
public node(Object d)
{
next = null;
this.data = d;
}
node(Object d, node nextNode)
{
next = nextNode;
this.data = d;
}
public Object getdata()
{
return data;
}
public void setdata(int d)
{
data = d;
}
public node getNext()
{
return next;
}
public void setNext(node nextValue)
{
next = nextValue;
}
}
}
​

return a linked list of first n elements

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

Categories