Adding to the end of a Linked List - java

I'm having trouble with this homework problem, it compiles correctly, but I'm getting an exception that I can't figure out. Here's what's in my main method
MyLinkedListH1 list = new MyLinkedListH1();
list.addLast(5);
list.addLast(6);
list.addLast(7);
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
list.traverse();
list.print();
And the addLast method (which worked when within the main method I performed addFirst before doing a single addLast, but I don't see how that would make a difference).
public void addLast(int d)
{
Node newNode = new Node();
newNode.x = d;
newNode.link = null;
Node p = first;
if(first == null)
{
first = newNode;
}
while (p.link != null)
{
p = p.link;
}
p.link = newNode;
}
And the exception:
Exception in thread "main" java.lang.NullPointerException
at MyLinkedListH1$Node.access$200(Hmwkal.java:23)
at MyLinkedListH1.addLast(Hmwkal.java:50)
at Hmwkal.main(Hmwkal.java:7)
So it seems it's having a problem with the pointer going null. Sorry if it's something obvious, I've only been programming for a few months and linked lists aren't a strong suit of mine.
If necessary, here's the full code:
class Hmwkal
{
public static void main(String[] args)
{
MyLinkedListH1 list = new MyLinkedListH1();
list.addLast(5);
list.addLast(6);
list.addLast(7);
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
list.traverse();
list.print();
}
}
class MyLinkedListH1
{
private class Node
{
private Node link;
private int x;
}
private Node first = null;
public void addFirst(int d)
{
Node newNode = new Node();
newNode.x = d;
newNode.link = first;
first = newNode;
}
public void addLast(int d)
{
Node newNode = new Node();
newNode.x = d;
newNode.link = null;
Node p = first;
if(first == null)
{
first = newNode;
}
while (p.link != null)
{
p = p.link;
}
p.link = newNode;
}
public void print()
{
Node listNode = first;
while (listNode != null)
{
System.out.println(listNode.x);
listNode = listNode.link;
}
}
public void traverse() //This AND the print might be redundant
{
Node p = first;
while (p != null)
{
System.out.println(p.x);
p = p.link;
}
}
}
Thanks so much for any help ^_^

Your addLast method is broken; it will continue to execute logic even after we've established that the node we start on is null.
What you want to do is have a complete if-else case, in which the else branch covers the traversing of the list:
public void addLast(int d) {
Node newNode = new Node();
newNode.x = d;
newNode.link = null;
if(first == null) {
first = newNode;
} else {
Node p = first;
while(p.link != null) {
p = p.link;
}
p.link = newNode;
}
}
This now has the behaviors that one wants; if there are no nodes in the list, and we are adding to the last element, we will add our element in as if it were the last one being added in. If the head element is not null, we will traverse the list, and insert it at the end.

Related

Problem with printing own Linked List and implementing 2 methods

I created my own Linked List using nodes, and I have few methods to do.
Methods in main:
//List<Person> females = peopleFromWarsaw.getWithFilter(p -> p.getName().endsWith("a"));
// Dont know how to implements this methods.
// ObjectContainer.removeIf(p -> p.getAge() > 50);
// peopleFromWarsaw.storeToFile("youngPeopleFromWarsaw.txt",
// p -> p.getAge() < 30, p -> p.getName() + ";" + p.getAge() + ";" + p.getCity());
At the begging i made a linked list and tried to print elements from list but doesnt work.
At first it looks like it doesn't have a method toString but class Person has toString. I guess the program takes the node but I want to print object.
Maybe u can see what is the problem with code, basically nodes and methods in Object Container are fine.
Secondly i have a problem with implementing methods in main (getWithFilter,removeIf and storeToFile)
No matter how I write method in ObjectContainer, always intelij tells me that cannot use lambda and underline p.getName (p -> p.getName().endsWith("a"));
In class Person i have getters and setters with fields name,age.
Maybe someone could explain how properly write this methods ?
public class ObjectContainer<T> {
private Node head;
private Node tail;
private final Predicate<T> predicate;
public ObjectContainer(Predicate<T> predicate) {
this.predicate = predicate;
}
static class Node {
private Object object;
private Node next;
Node(Object object) {
this.object = object;
}
}
public void add(T object) {
if (!predicate.test(object)) {
throw new IllegalArgumentException("Element can not be added");
}
Node newNode = new Node(object);
if (head == null) {
head = newNode;
tail = newNode;
} else {
tail.next = newNode;
tail = newNode;
}
}
public int size() {
int count = 0;
Node current = head;
while (current != null) {
count++;
current = current.next;
}
return count;
}
public void push(T new_data) {
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
public void insertAfter(Node prev_node, T new_data) {
if (prev_node == null) {
System.out.println("The given previous node cannot be null");
return;
}
Node new_node = new Node(new_data);
new_node.next = prev_node.next;
prev_node.next = new_node;
}
public void append(T new_data) {
Node new_node = new Node(new_data);
if (head == null) {
head = new Node(new_data);
return;
}
new_node.next = null;
Node last = head;
while (last.next != null)
last = last.next;
last.next = new_node;
return;
}
public void printList() {
Node tnode = head;
while (tnode != null) {
tnode = tnode.next;
System.out.println(tnode);
}
}
}
Probably you don't want to print the node, but the object contained within. Also, you want to print the first object, too. That is
public void printList() {
Node tnode = head;
while (tnode != null) {
System.out.println(tnode.object);
tnode = tnode.next;
}
}

Method to insert and remove Node at the back of a Linked List

I'm trying to write a method to insert a node and remove a node at the back of a linked list. Here's the main class I'm writing the methods in. They're at the bottom (insertBack and removeBack):
public class LinkedList
{
private LinkedListNode head;
public LinkedList()
{
head = null;
}
public LinkedListNode getHead()
{
return head;
}
public void setHead(LinkedListNode h)
{
head = h;
}
public void insertFront(Object item)
{
if (head == null)
{
LinkedListNode nextNode = new LinkedListNode (item);
head = nextNode;
}
else
{
LinkedListNode nextNode = new LinkedListNode (item);
nextNode.setNext(head);
head = nextNode;
}
}
public Object removeFront()
{
if (head == null)
{
return head;
}
else
{
LinkedListNode t = head;
Object ret = head.getData();
head = head.getNext();
t.setNext(null);
t = null;
return ret;
}
}
//insert a front at the end of linked list
public void insertBack(Object myData)
{
LinkedListNode newNode = new LinkedListNode(myData);
if (head == null)
{
head = newNode;
}
else
{
LinkedListNode current = head;
while (current.getNext() != null)
{
current = current.getNext();
}
current.setNext(newNode);
}
}
//remove a node at the end of linked list
public Object removeBack()
{
if (head == null)
{
return null;
}
if (head.getNext() == null)
{
return null;
}
LinkedListNode secondToLast = head;
while (secondToLast.getNext().getNext() != null)
{
secondToLast = secondToLast.getNext();
}
secondToLast.setNext(null);
return head.getData();
}
}
There's probably formatting errors as I pasted this here, but I'm still trying to figure out how to use this site. When I run my driver class, shown below, I get the results shown below that.
public static void main(String[] args)
{
ValueData data1 = new ValueData("a", 50);
ValueData data2 = new ValueData("b", 70);
ValueData data3 = new ValueData("c", 100);
LinkedList myList = new LinkedList();
//practice insertBack and removeBack
myList.insertBack(data1);
myList.insertBack(data2);
myList.insertBack(data3);
System.out.println("Test insertBack and removeBack");
System.out.println((ValueData) myList.removeBack());
System.out.println((ValueData) myList.removeBack());
System.out.println((ValueData) myList.removeBack());
System.out.println();
//compare insertFront and removeFront
System.out.println("Test insertFront and removeFront");
myList.insertFront(data1);
myList.insertFront(data2);
myList.insertFront(data3);
System.out.println((ValueData)myList.removeFront());
System.out.println((ValueData)myList.removeFront());
System.out.println((ValueData)myList.removeFront());
System.out.println();
RESULTS
Test insertBack and removeBack
a 50.0
a 50.0
null
Test insertFront and removeFront
c 100.0
b 70.0
a 50.0
Can anyone help me figure out why my removeFront and removeBack methods are not working?
First of all this code is unnecessary, as an object that has no reference will just be thrown away.
t.setNext(null);
t = null;
This also may help removeBack()
if(head == null) {
return null;
}
LindedListNode current = head;
while(current.getNext() != null) //searching for last node
current = current.getNext();
current = null; //make the last node null

Copying alternative nodes from one single linked list to another in java

I'm trying to write a method called copyAlternate which copy alternate elements from a single linked list and put them in another Single linked list sent as a parameter in the method
for example: if the first Single Linked List is( 4,6,10,12,2)
the method should generate a single linked list with (4,10,2)
here is my code:
public boolean copyAlternate(SingleLinkedList<E> list1)
{
if(head==null)
return false;
Node <E> temp = head;
ArrayList <E> a1 = new ArrayList<E>();
while(temp!=null) {
a1.add(temp.data);
temp=temp.next;
}
Node<E> tmp1=list1.head;
for(int i=0;i<a1.size();i=i+2){
if(list1.head==null) {
list1.head =new Node(a1.get(i));
tmp1=head;
size++;
}
else
{
tmp1.next=new Node(a1.get(i));
size++;
tmp1=tmp1.next;
}
}
return true;
}
I got only 4 from method not (4,10,2)
so what is the problem with my code?
Here is a full example if you need it, try not to copy it entirely but study it and understand what it's doing:
public class Main {
public static void main(String[] args) {
SingleLinkedList<Integer> list = new SingleLinkedList<>();
// (4, 6, 10, 12, 2)
list.add(4).add(6).add(10).add(12).add(2);
SingleLinkedList<Integer> newList = copyAlternate(list);
System.out.println(newList);
// prints: (14, 10, 2)
}
public static class Node<T> {
public Node<T> next;
public T data;
public Node() {}
public Node(T data) {this.data = data;}
}
public static class SingleLinkedList<T> {
private Node<T> head;
private Node<T> tail;
public SingleLinkedList<T> add(T data) {
if (tail != null) {
tail.next = new Node<>(data);
tail = tail.next;
} else {
head = new Node<>(data);
tail = head;
}
return this;
}
#Override public String toString() {
StringBuilder sb = new StringBuilder();
if (head != null) {
sb.append(head.data);
Node<T> curr = head.next;
while (curr != null) {
sb.append(", ").append(curr.data);
curr = curr.next;
}
}
return sb.toString();
}
}
/**
* Copies only the even index nodes (0, 2, 4..) into a new list and returns that list.
* Doesn't create a deep copy of data
*/
public static <T> SingleLinkedList<T> copyAlternate(SingleLinkedList<T> list) {
Objects.requireNonNull(list, "list");
SingleLinkedList<T> newList = new SingleLinkedList<>();
Node<T> other = list.head;
if (other != null) {
// copy other data to head of new list and remember that as the current node
Node<T> curr = newList.head = new Node<>(other.data);
// get the next next other node
other = other.next;
if (other != null) {
other = other.next;
}
while (other != null) {
// copy the data into the next node then remember that as the current node
curr = curr.next = new Node<>(other.data);
// get the next next other node
other = other.next;
if (other != null) {
other = other.next;
}
}
}
return newList;
}
}
Another way you can achieve it. Hope it will help.
// define the structure of a single node
class ListNode<T>
{
public T data;
public ListNode<T> next;
public ListNode(T data)
{
this.data = data;
this.next = null;
}
}
public class SingleLinkedListGenerics<T>
{
private ListNode<T> head = null;
private ListNode<T> tail = null;
// used to insert a node at the end of linked list
public void insertLast(T data)
{
ListNode<T> newNode = new ListNode<>(data);
if (head == null)
{
head = tail = newNode;
}
else
{
tail.next = newNode;
tail = newNode;
}
}
// For printing Linked List
public void displayList()
{
System.out.println("\nPrinting LinkedList (head --> last) ");
ListNode<T> current = head;
while (current != null)
{
System.out.println(current.data + ", ");
current = current.next;
}
}
public static <T> SingleLinkedListGenerics<T> copyAlternate(SingleLinkedListGenerics<T> list)
{
if (list.head == null)
return null;
SingleLinkedListGenerics<T> newList = new SingleLinkedListGenerics<>();
ListNode<T> tmp = list.head;
ListNode<T> newNode = new ListNode<>(tmp.data); // getting the first node
newList.head = newNode;
newList.tail = newNode;
tmp = tmp.next;
while (tmp != null && tmp.next != null) //
{
tmp = tmp.next; // skipping one node
newList.insertLast(tmp.data);
tmp = tmp.next;
}
return newList;
}
public static void main(String args[])
{
SingleLinkedListGenerics<Integer> myLinkedlist = new SingleLinkedListGenerics<>();
myLinkedlist.insertLast(4);
myLinkedlist.insertLast(6);
myLinkedlist.insertLast(10);
myLinkedlist.insertLast(12);
myLinkedlist.insertLast(2);
myLinkedlist.displayList();
SingleLinkedListGenerics<Integer> myLinkedlist1 = copyAlternate(myLinkedlist);
myLinkedlist1.displayList();
}
}

Unable to delete last node in linked list

I trying to delete the last node from my singly-linked list. But I am still unable to resolve this error in code. My deleteFromEnd method is not removing the last node. After calling the delete method, it's still showing the node that I want to delete. The rest of the list is deleted, but the last node itself is not removed. Can you tell me what I am missing, or where the error is?
LinkedList:
package lab5;
public class LinkedList {
public static void main(String argsp[]) {
List ob = new List();
ob.addAtStart("y", 6);
ob.addAtStart("w", 4);
ob.addAtStart("z", 3);
ob.addAtEnd("a", 3);
ob.addAtEnd("b", 4);
ob.addAtEnd("c", 5);
/*
* ob.display(); System.out.println("Deleted first one");
* ob.deleteFromStart();
*/
ob.display();
System.out.println("Deleted End one");
ob.deleteFromEnd();
ob.display();
}
}
List:
package lab5;
public class List {
Node head;
public List() {
head = null;
}
public List(Node e) {
head = e;
}
Node oldfirst = null;
Node lasthead = null;
public void addAtStart(String name, int age) {
Node newObject = new Node(name, age);
newObject.next = head;
if (oldfirst == null) {
oldfirst = newObject;
}
head = newObject;
lasthead = head;
}
public void display() {
Node store = head;
while (store != null) {
store.display();
store = store.next;
System.out.println();
}
}
public void addAtEnd(String name, int age) {
Node atEndValue = new Node(name, age);
oldfirst.next = atEndValue;
oldfirst = atEndValue;
}
public void deleteFromStart() {
if (head.next != null) {
head = head.next;
}
}
public void deleteFromEnd() {
Node start = head;
Node prev = null;
while (head != null) {
prev = head;
head = head.next;
}
prev.next = null;
head = prev;
}
public Node search(String name) {
return head;
}
public boolean isEmpty() {
return head == null;
}
public int size() {
return (head.toString()).length();
}
}
Node:
package lab5;
public class Node {
String name;
int age;
Node next;
public Node() {
name = "Abc";
age = 10;
next = null;
}
public Node(String name, int age) {
this.name = name;
this.age = age;
next = null;
}
public void display() {
System.out.println("Name: " + name + " Age: " + age);
}
}
You are modifying head pointer of list which is wrong. Following method worked for me.
public void deleteFromEnd() {
Node start = head;
Node prev = null;
if(start == null || start.next == null)
{
head = null;
return;
}
while (start.next != null) {
prev = start;
start = start.next;
}
prev.next = null;
}
After analysing your code for little more, I found few other issues. You would need to update addAtStart and addAtEnd methods.
Node lasthead = null;
public void addAtStart(String name, int age) {
Node newObject = new Node(name, age);
newObject.next = head;
if(head == null)
lasthead = newObject;
else if(head.next == null)
lasthead = head;
head = newObject;
}
public void addAtEnd(String name, int age) {
Node atEndValue = new Node(name, age);
lasthead.next = atEndValue;
lasthead = atEndValue;
}
The reason being, suppose if I delete a single node from the end of the list. I would not be able to add an element to the end of the list.
When you're deleting from the end of a singly-linked list you have to do things:
Traverse the list, and create a variable to refer to the second-to-last element of your list.
Set the node after the second-to-last node to be null
You should never change the value of head while traversing your linked list, because that effectively deletes the entire list. You have no way of finding your way back to the beginning since you've overwritten your head variable. Instead, iterate using a temporary variable which is initialized as head.
Finally, remember to consider the edge-cases where the list only has 1 element, or is already empty:
public void deleteFromEnd() {
Node current = head;
Node previous = null;
while (current != null && current.next != null) {
previous = current;
current = current.next;
}
if (current == head) {
head = null;
}
if (previous != null) {
previous.next = null;
}
}
Do not change head of Linked List, otherwise you will loose the list.
Try following modification of your function:
public void deleteFromEnd() {
Node start = head;
Node prev = null;
if(start == null){
return;
}
if (start.next == null){
head = null;
return;
}
while (start.next != null) {
prev = start;
start = start.next;
}
prev.next = null;
}

Linked list implementation - prints first element in infinite loop

I am trying to implement linked list and I dont get whats wrong with this code.
Goes into an infinite loop printing 1...the start node is instantiated the first time when insert() is invoked
Node
public class Node {
int data;
Node next;
public Node(int data, Node next) {
super();
this.data = data;
this.next = next;
}
public Node()
{
super();
}
}
LinkedList
public class LinkedList {
Node start = null;
void insert(int value)
{
Node current;
current = start;
if(start == null)
{
start = new Node(value, null);
start.data = value;
start.next = null;
}
else
{
while(current.next != null)
{
current = current.next;
}
current.next = new Node();
current.next.data = value;
current.next.next = null;
}
}
void show()
{
Node curr = start;
while(curr.next != null)
{
System.out.println(curr.data);
}
}
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.insert(1);
ll.insert(7);
ll.insert(5);
ll.insert(3);
ll.insert(9);
ll.show();
}
}
Change you show() method like below:
void show() {
Node curr = start;
while (curr.next != null) {
System.out.println(curr.data);
curr = curr.next; // This part was missing.
}
}
In your show() method you are missing the:
curr = curr.next
after you are printing the current node's value;
use curr = curr.next; in the while loop of

Categories

Resources