linkedlist implementation add method - java

I'm implementing a linked list for a course online, and there seems to be something wrong with my add function. When I try to add the first element, the Eclipse prints null, and for a second element Eclipse shows an error. (I'm assuming because the first element was never added, so there can't be a second one.)
This is the implementation of my linked list:
package textgen;
import java.util.AbstractList;
public class MyLinkedList<E> extends AbstractList<E> {
LLNode<E> head;
LLNode<E> tail;
int size;
/** Create a new empty LinkedList */
public MyLinkedList() {
size = 0;
head = new LLNode<E>();
tail = new LLNode<E>();
head.next = tail;
tail.prev = head;
}
/**
* Appends an element to the end of the list
* #param element The element to add
*/
public boolean add(E element )
{
add(size, element);
return false;
}
/** Get the element at position index
* #throws IndexOutOfBoundsException if the index is out of bounds. */
public E get(int index) throws IndexOutOfBoundsException
{
if(index >= this.size){
throw new IndexOutOfBoundsException("Your index is out of bounds!");
}
LLNode<E> lGet = head;
for(int i = 0; i < index + 1; i++){
lGet = lGet.next;
}
return lGet.data;
}
public void printList(){
LLNode lTemp = head;
while(lTemp.next != tail){
System.out.println(lTemp.next.data);
lTemp = lTemp.next;
}
}
/**
* Add an element to the list at the specified index
* #param The index where the element should be added
* #param element The element to add
*/
public void add(int index, E element ) throws IndexOutOfBoundsException
{
if(index > this.size){
throw new IndexOutOfBoundsException("Oops! Out of bounds!");
}
else{
LLNode<E> nAdd = new LLNode<E>(element);
LLNode<E> nIt = null;
if(index <= size/2) // if the index is closer to the start from the beginning of the list
{
nIt = head;
for(int i = 0; i < index + 1; i++){
nIt = nIt.next;
}
}
else {
nIt = tail;
for(int i = this.size; i > index; i--){
nIt = nIt.prev;
}
}
nIt.prev.next.prev = nAdd;
nAdd.next = nIt.prev.next;
nIt.prev.next = nAdd;
nAdd.prev = nIt.prev;
size++;
}
}
/** Return the size of the list */
public int size()
{
return size;
}
/** Remove a node at the specified index and return its data element.
* #param index The index of the element to remove
* #return The data element removed
* #throws IndexOutOfBoundsException If index is outside the bounds of the list
*
*/
public E remove(int index)
{
// TODO: Implement this method
size--;
return null;
}
/**
* Set an index position in the list to a new element
* #param index The index of the element to change
* #param element The new element
* #return The element that was replaced
* #throws IndexOutOfBoundsException if the index is out of bounds.
*/
public E set(int index, E element)
{
// TODO: Implement this method
return null;
}
}
class LLNode<E>
{
LLNode<E> prev;
LLNode<E> next;
E data;
public LLNode(){
this.data = null;
this.prev = null;
this.next = null;
}
public LLNode(E e)
{
this.data = e;
this.prev = null;
this.next = null;
}
}
This is the main:
package textgen;
public class fixAdd {
public static void main(String [] Arg){
MyLinkedList<String> ll = new MyLinkedList<String>();
ll.add(0, "happy");
ll.add(1, "gilda");
System.out.println(ll);
}
}
And this is the error printed:
Exception in thread "main" java.lang.NullPointerException
at textgen.MyLinkedList.get(MyLinkedList.java:57)
at java.util.AbstractList$Itr.next(Unknown Source)
at java.util.AbstractCollection.toString(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at textgen.fixAdd.main(fixAdd.java:11)
I've gone over my add method a number of times, and compared it to other implementations I found online, and everything seems in order. I'm totally confused and would appreciate any help. Thanks!

You should try to implement a simpler add first, instead of doing the size / 2 optimization.
There are several problems with your code:
don't create dummy nodes at initialization, initialize them with null
your loop in get method should be for(int i = 0; i < index; i++)
your aren't updating the size in your add method
EDIT: Changed add method to cover all cases:
public void add(int index, E element)
{
if (index > size)
{
throw new IndexOutOfBoundsException("Oops! Out of bounds!");
}
LLNode<E> node = new LLNode<E>(element);
//Add first and last
if(size == 0)
{
head = tail = node;
}
else
{
//Add first
if(index == 0)
{
node.next = head;
head.prev = node;
head = node;
}
//Add last
else if(index == size)
{
node.prev = tail;
tail.next = node;
tail = node;
}
//Add between
else
{
LLNode<E> current = this.head;
for(int i = 0; i < index; i++)
{
current = current.next;
}
node.next = current;
node.prev = current.prev;
current.prev.next = node;
}
}
size++;
}

Multiple issues with this implementation:
You're setting both head and tail to be empty Nodes when you initialize the list (constructor). You shouldn't do that, it makes your list to be of size two with two null elements.
The exception is thrown from the printing in the main which, in turn, calls your get() method (by calling AbstractList.toString())
In add(E element) you're calling add(size, element); and you pass the size as the index, later on you check if if(index > this.size) which is practically asking if size > size - makes no sense.
In remove() implementation you just decrease the size - this is not good enough, you should also move the tail backwards (and if the list is of size 1 - handle the head as well).
The is the main issue: the logic of insertion in the following lines is incorrect:
nIt.prev.next.prev = nAdd;
nAdd.next = nIt.prev.next;
nIt.prev.next = nAdd;
nAdd.prev = nIt.prev;
Two suggestions:
Don't inherit from AbstractList - after all you're creating your own implementation
Start simple, forget about tail or about trying to insert from the end for better efficiency. Only after you have a simple implementation working - try to improve it.

Try the following code:
public void insert(int index, T item)
{
if(index == size())
{
add(item);
}
else if(index == 0)
{
MyNode<T> temp = new MyNode<T>();
temp.data = item;
temp.next = head;
head.previous = temp;
head = temp;
count++;
}
temp = head;
for(int i = 0; i < index-1; i++)
{
temp = temp.next;
MyNode<T> myNode = new MyNode<T>();
myNode.data = item;
myNode.next = temp.next;
temp.next = myNode;
count++;
}
}

Related

Doubly Linked List moving item to end java

I found this code for adding an item to the front of the linked list, but since I have a last node, it doesn't work quite right, so I changed it a tiny bit:
public void moveToFront(String node) {
DoubleNode previous = first;
temp = first;
while (temp != null) {
if (node.equals(temp.item)) {
//Found the item
previous.next = temp.next;
temp.next = first;
first = temp;
if (last.next != null) {
last = last.prev;
last.prev = previous;
}
return;
}
previous = temp;
temp = temp.next;
}
The if (last.next != null) is asking if the original last was moved, and checking if the new last has the right links. Now I think it works properly for my code.
I'd like to implement this code, but for adding an item to the end. However, last just isn't right now. When calling last.prev it only gets the one item behind it, but last.prev.prev to infinity is the same item.
My idea was instead of working from first like in moveToFront(), I work from last, and step through each node backwards, but obviously that doesn't work when last doesn't work anymore.
public void moveToEnd(String node) {
DoubleNode previous = last;
temp = last;
System.out.println("last = " + last.prev.item);
System.out.println("temp = " + temp.item);
while (!temp.item.equals(first.item)) {
if(node.equals(temp.item)){
System.out.println("previous.prev = " + previous.prev.item);
}
previous = temp;
temp = temp.prev;
System.out.println("temp.prev = " + temp.prev.prev.prev.prev.prev.prev.prev.prev.prev.prev.prev.item);
}
Here's how I implement my linked list:
public class LinkedListDeque {
public DoubleNode first = new DoubleNode(null);
public DoubleNode last = new DoubleNode(null);
public DoubleNode temp;
public int N;
LinkedListDeque() {
first.next = last;
last.prev = first;
}
private class DoubleNode {
String item;
int counter = 0;
DoubleNode next;
DoubleNode prev;
DoubleNode(String i) {
this.item = i;
}
}
I found this example of a complete doubly linked list. It does not have an add to front method, but it is adding to the back of the linked list each time. Hopefully, it will help and give you a better idea of how this data structure is supposed to work and function. I would definitely test it first as it states in the readme for this GitHub that none of the code has been tested. Sorce
/*******************************************************
* DoublyLinkedList.java
* Created by Stephen Hall on 9/22/17.
* Copyright (c) 2017 Stephen Hall. All rights reserved.
* A Linked List implementation in Java
********************************************************/
package Lists.Doubly_Linked_List;
/**
* Doubly linked list class
* #param <T> Generic type
*/
public class DoublyLinkedList<T extends Comparable<T>> {
/**
* Node class for singly linked list
*/
public class Node{
/**
* private Members
*/
private T data;
private Node next;
private Node previous;
/**
* Node Class Constructor
* #param data Data to be held in the Node
*/
public Node(T data){
this.data = data;
next = previous = null;
}
}
/**
* Private Members
*/
private Node head;
private Node tail;
private int count;
/**
* Linked List Constructor
*/
public DoublyLinkedList(){
head = tail = null;
count = 0;
}
/**
* Adds a new node into the list with the given data
* #param data Data to add into the list
* #return Node added into the list
*/
public Node add(T data){
// No data to insert into list
if (data != null) {
Node node = new Node(data);
// The Linked list is empty
if (head == null) {
head = node;
tail = head;
count++;
return node;
}
// Add to the end of the list
tail.next = node;
node.previous = tail;
tail = node;
count++;
return node;
}
return null;
}
/**
* Removes the first node in the list matching the data
* #param data Data to remove from the list
* #return Node removed from the list
*/
public Node remove(T data){
// List is empty or no data to remove
if (head == null || data == null)
return null;
Node tmp = head;
// The data to remove what found in the first Node in the list
if(equalTo(tmp.data, data)) {
head = head.next;
count--;
return tmp;
}
// Try to find the node in the list
while (tmp.next != null) {
// Node was found, Remove it from the list
if (equalTo(tmp.next.data, data)) {
if(tmp.next == tail){
tail = tmp;
tmp = tmp.next;
tail.next = null;
count--;
return tmp;
}
else {
Node node = tmp.next;
tmp.next = tmp.next.next;
tmp.next.next.previous = tmp;
node.next = node.previous = null;
count--;
return node;
}
}
tmp = tmp.next;
}
// The data was not found in the list
return null;
}
/**
* Gets the first node that has the given data
* #param data Data to find in the list
* #return Node First node with matching data or null if no node was found
*/
public Node find(T data){
// No list or data to find
if (head == null || data == null)
return null;
Node tmp = head;
// Try to find the data in the list
while(tmp != null) {
// Data was found
if (equalTo(tmp.data, data))
return tmp;
tmp = tmp.next;
}
// Data was not found in the list
return null;
}
/**
* Gets the node at the given index
* #param index Index of the Node to get
* #return Node at passed in index
*/
public Node indexAt(int index){
//Index was negative or larger then the amount of Nodes in the list
if (index < 0 || index > size())
return null;
Node tmp = head;
// Move to index
for (int i = 0; i < index; i++)
tmp = tmp.next;
// return the node at the index position
return tmp;
}
/**
* Gets the current count of the array
* #return Number of items in the array
*/
public int size(){
return count;
}
/**
* Determines if a is equal to b
* #param a: generic type to test
* #param b: generic type to test
* #return boolean: true|false
*/
private boolean equalTo(T a, T b) {
return a.compareTo(b) == 0;
}
}
There is a problem with your moveToFront() method. It does not work for if node == first. If the node that needs to be moved is the first node, you end up setting first.next = first which is incorrect. The below code should work
public void moveToFront(DoubleNode node) {
DoubleNode previous = first;
temp = first;
while (temp != null && node != first) {
if (node.equals(temp.item)) {
//Found the item
previous.next = temp.next;
temp.next = first;
first = temp;
if (last.next != null) {
last = last.prev;
last.prev = previous;
}
return;
}
previous = temp;
temp = temp.next;
}
Now coming to moveToLast() the following code should work
public void moveToLast(DoubleNode node) {
DoubleNode temp = first;
DoubleNode prev = new DoubleNode(null); //dummy sentinel node
while (temp != null && node != last) {
if (temp == node) {
if (temp == first) first = temp.next;
prev.next = temp.next;
if (temp.next != null) temp.next.prev = prev;
last.next = temp;
temp.prev = last;
last = temp;
last.next = null;
break;
}
prev = temp;
temp = temp.next;
}
}

Created Linked List not returning correct index

I created a list that goes {50, 10, 60, 30, 40} and want to return the index when I reach 30 in my Linked List, however my program always returns -1 (basically it is unable to increment and return my index). I am not sure about how to go about getting back the index in a different manor unless I am able to cast the anEntry object into an integer and equal it my index.
class MyLinkedList {
private Node firstNode; // index = 0
private int length;
public MyLinkedList() {
firstNode = null;
length = 0;
} // end default constructor
/** Task: Adds a new entry to the end of the list.
* #param newEntry the object to be added as a new entry
* #return true if the addition is successful, or false if not */
public boolean add(Object newEntry) {
Node newNode = new Node(newEntry);
if (isEmpty())
firstNode = newNode;
else {
Node lastNode = getNode(length-1);
lastNode.next = newNode;
}
length++;
return true;
} // end add
/** Task: Adds a new entry at a specified index
* #param newEntry the object to be added at the specified index
* #return true if successful, or false if not */
public boolean add(int index, Object newEntry) {
boolean isSuccessful = true;
if ((index >= 0) && (index <= length)) {
Node newNode = new Node(newEntry);
if (isEmpty() || (index == 0)) {
newNode.next = firstNode;
firstNode = newNode;
}
else {
Node nodeBefore = getNode(index - 1);
Node nodeAfter = nodeBefore.next;
newNode.next = nodeAfter;
nodeBefore.next = newNode;
}
length++;
}
else
isSuccessful = false;
return isSuccessful;
} // end add
/** Task: Determines whether the list contains a given entry.
* #param anEntry the object that is the desired entry
* #return true if the list contains anEntry, or false if not */
public boolean contains(Object anEntry) {
boolean found = false;
Node currentNode = firstNode;
while (!found && (currentNode != null)) {
if (anEntry.equals(currentNode.data))
found = true;
else
currentNode = currentNode.next;
} // end while
return found;
} // end contains
/** Task: Gets an entry in the list.
* #param the desired index
* #return the desired entry, or
* null if either the list is empty or index is invalid */
public Object getEntry(int index) {
Object result = null; // result to return
if (!isEmpty() && (index >= 0) && (index < length))
result = getNode(index).data;
return result;
} // end getEntry
/** Task: Gets index of an entry in the list.
* #param the desired entry
* #return index of the first occurrence of the specified entry
* in this list, or -1 if this list does not contain the entry */
public int getIndex(Object anEntry) {
Node currentNode = firstNode;
int index = 0; // result to return
while (anEntry != currentNode.data) {
currentNode = currentNode.next;
index++;
if (anEntry.equals(currentNode.data)){
break;
}
else {
return -1;
}
}
return index;
} // end getIndex
private Node getNode(int index) {
Node currentNode = firstNode;
// traverse the list to locate the desired node
for (int counter = 0; counter < index; counter++)
currentNode = currentNode.next;
return currentNode;
} // end getNode
private Node getNode(int index) {
Node currentNode = firstNode;
// traverse the list to locate the desired node
for (int counter = 0; counter < index; counter++)
currentNode = currentNode.next;
return currentNode;
} // end getNode
private class Node {
private Object data; // data portion
private Node next; // link to next node
private Node(Object dataPortion) {
data = dataPortion;
next = null;
} // end constructor
private Node(Object dataPortion, Node nextNode) {
data = dataPortion;
next = nextNode;
} // end constructor
private void setData(Object dataPortion) {
data = dataPortion;
} // end setData
private Object getData() {
return data;
} // end getData
private void setNextNode(Node nextNode) {
next = nextNode;
} // end setNextNode
private Node getNextNode() {
return next;
} // end getNextNode
} // end Node
} // end MyLinkedList
The problem is that your while loop never does more than one iteration.
if (anEntry.equals(currentNode.data)){
break;
}
else {
return -1;
}
If the current element matches, then I have found the item so we can stop. If it doesn't, then the list does not contain this item. It should be relatively clear that this logic is wrong. Just because the current element doesn't match does not mean that subsequent elements might not match.
You can demonstrate this further by observing that getIndex(50) actually does return the correct index: zero. Your statement "my program always returns -1" is actually incorrect.
We need to swap this logic around - only return -1 after we have already tried all the elements.
while (anEntry != currentNode.data) {
currentNode = currentNode.next;
index++;
if (anEntry.equals(currentNode.data)){
return index;
}
}
return -1;
You will still have a problem where your code will throw an exception if the element is not in the list. This can be trivially solved with a minor change to the above code, but I'll leave that up to you to figure out!

Java LinkedList inserting Object at index

I am having a bit of trouble understanding how to place an object in a linked.
In this case, if there is already an object at the specific index, it won't replace it (that is for another method). I guess I am having trouble understanding how to get to a specific index, retrieve the data from that index, and then either put data there and connect the nodes or tell the user there is already an object there.
Here is my code:
public class CourseList {
private Coursenode head;
int currentSize;
public void insertAtIndex(Course c, int index) {
Coursenode insert =new Coursenode(c,head);
Coursenode temp = new Coursenode();
if (index > currentSize - 1 || index < 0) {
throw (new IndexOutOfBoundsException());
}
for(int x = 0; x < index; x++) {
if (insert.getNext()!= null) {
temp = insert;
insert.setNext(insert);
insert.setData(temp.getData());
}
if (insert.getNext() == null && x == index) {
insert.setNext(insert.getNext());
}
if (insert.getNext() != null && x == index) {
System.out.println("There is already a Course at that Index");
}
}
}
}
Here is the inner class Coursenode:
public class Coursenode {
private Course data;
private Coursenode next;
public Coursenode() {
this.data = null;
this.next = null;
}
public Coursenode(Course course, Coursenode next) {
this.data=course;
this.next= next;
}
public Coursenode(Coursenode x) {
this.data = x.getData();
this.next = x.getNext();
}
public Course getData() {
return data;
}
public void setData(Course data) {
this.data = data;
}
public Coursenode getNext() {
return next;
}
public void setNext(Coursenode next) {
this.next = next;
}
//Clone method
public void clone(Coursenode new_cn){
new_cn = new Coursenode (this.getData(),this.getNext());
}
}
Any thought would be appreciated, I suspect I am getting lost within the head reference between nodes but I can't quite figure out how to solve the problem.
There are three ways (assuming positive index values) to make an insertion at an index in a linked list:
At the head (index == 0)
After the tail (index >= currentSize)
In the middle (at an occupied index) (index > 0 && index < currentSize)
There may be a tendency to think that inserting at the tail is another case, but later we'll see that insertion at the tail is the same as an insertion in the middle, because the tail will be slid forward.
If the insertion is at the head, you need to set the next of the inserted node to the old head and then set head to the inserted node:
private void insertAtHead(Course course) {
Coursenode insertedNode = new Coursenode(c, head);
head = insertedNode;
}
If the insertion occurs past the tail, a common way of dealing with this is to throw some sort of exception, such as an IndexOutOfBoundsException:
throw new IndexOutOfBoundsException("Cannot insert course after the tail of the course list");
If the insertion occurs at an occupied index, the existing node (and all nodes after the existing node) must be pushed forward. This means that the next of the inserted node must be set to the node that currently occupies the index and the next of the node previous to the node at the current index must be set to the inserted node. In essence, the inserted node is fused into the list. To do this, the list must be traversed until the occupied node is found:
private void insertAtOccupied(Course course, int index) {
Coursenode previous = null;
Coursenode current = head;
for (int i = 1; i <= index; i++) {
// Track the previous and current nodes
// previous = node at i - 1
// current = node at i
previous = current;
current = current.next;
}
Coursenode insertedNode = new Coursenode(c, current.next);
previous.next = insertedNode;
}
Pulling these cases together, we can create the following logic:
public void insertAt(Course course, int index) {
if (index == 0) {
insertAtHead(course);
}
else if (index >= currentSize) {
throw new IndexOutOfBoundsException("Cannot insert course after the tail of the course list");
}
else if (index > 0 && index < currentSize) {
insertAtOccupied(course, index);
}
}
First of all in a linkedlist if
index < linkedlistsize
then there is an object already in a linkedlist. If you have a null node in node.next that how you know you have reached the end of your linked list.
public class CourseList {
private Coursenode head;
int currentSize;
public void insertAtIndex(Course c, int index) {
Coursenode insert =new Coursenode(c,head);
Coursenode temp = new Coursenode();
if (index > currentSize - 1 || index < 0) {
throw (new IndexOutOfBoundsException());
}
//tempnode = head;
for(int x=1; x< index;x++) {
//tempnode = tempnode.next;
}
//nodeatindex = tempnode;
//you can get details of the node
}
Hope this helps!

DoublyLinkedList Issues traveling backwards

I have an assignment to complete a DoublyLinkList assignment and I am having some difficulty with two of the methods. I was given the code for MyList and MyAbstractList and was told to extend MyAbstractList with my DoublyLinkedList. I am not allowed to change MyList or MyAbstractList.
Here is the code for MyList I was provided:
public interface MyList<E extends Comparable<E>> {
/** Return true if this list contains no elements */
public boolean isEmpty();
/** Return the number of elements in this list */
public int size();
/** Add a new element at the proper point */
public void add(E e);
/** Clear the list */
public void clear();
/** Return true if this list contains the element */
public boolean contains(E e);
/** Return the element from this list at the specified index */
public E get(int index);
/** Return the first element in the list */
public E getFirst();
/** Return the last element in the list */
public E getLast();
/** Return the index of the first matching element in this list.
* Return -1 if no match. */
public int indexOf(E e);
/** Return the index of the last matching element in this list
* Return -1 if no match. */
public int lastIndexOf(E e);
/** Remove the first occurrence of the element o from this list.
* Shift any subsequent elements to the left.
* Return true if the element is removed. */
public boolean remove(E e);
/** Remove the element at the specified position in this list
* Shift any subsequent elements to the left.
* Return the element that was removed from the list. */
public boolean remove(int index);
/** Remove the first element in the list, return true if done, false if list is empty */
public boolean removeFirst();
/** Remove the Last element in the list, return true if done, false if list is empty */
public boolean removeLast();
/** Replace the element at the specified position in this list
* with the specified element and return true if done, false if index out of range. */
public boolean set(int index, E e);
}
and this was the code I was provided for MyAbstractList:
public abstract class MyAbstractList<E extends Comparable<E>> implements MyList<E> {
protected int size = 0; // The size of the list
/** Create a default list */
protected MyAbstractList() {
}
/** Create a list from an array of objects */
public MyAbstractList(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
#Override /** Return true if this list contains no elements */
public boolean isEmpty() {
return size == 0;
}
#Override /** Return the number of elements in this list */
public int size() {
return size;
}
}
Finally here is my code for MyDoublyLinkedList:
import java.util.ArrayList;
public class MyDoublyLinkedList<E extends Comparable<E>> extends MyAbstractList<E>
{
int size =0;
Node<E> head = null;
Node<E> current = null;
Node<E> tail = null;
public MyDoublyLinkedList() {
}
/** Create a list from an array of objects */
public MyDoublyLinkedList(E[] objects) {
super(objects);
}
#Override
public boolean isEmpty()
{
return size == 0;
}
#Override
public int size()
{
return size;
}
/** Add a new element at the proper point */
#Override
public void add(E e)
{
Node<E> newNode = new Node<E>(e);
if (tail == null) {
head = tail = newNode;
}
else //if (head != null)
{
tail.next = newNode;
tail = newNode;
}
size++;
}
#Override
public void clear()
{
size = 0;
head = tail = null;
}
#Override
public boolean contains(E e)
{
Node<E> current = head;
for (int i = 0; i < size; i++) {
if (current.element.equals(e))
return true;
current = current.next;
}
return false;
}
#Override
public E get(int index)
{
if (index < 0 || index > size - 1)
return null;
Node<E> current = head;
for (int i = 0; i < index; i++)
current = current.next;
return current.element;
}
#Override
public E getFirst()
{
if (size == 0) {
return null;
}
else {
return head.element;
}
}
#Override
public E getLast()
{
if (size == 0) {
return null;
}
else {
return tail.element;
}
}
#Override
public int indexOf(E e)
{
Node<E> current = head;
for (int i = 0; i < size; i++) {
if (current.element.equals(e))
return i;
current = current.next;
}
return -1;
}
#Override
public int lastIndexOf(E e)
{
int lastIndex = -1;
Node<E> current = head;
for (int i = 0; i < size; i++) {
if (current.element.equals(e))
lastIndex = i;
current = current.next;
}
return lastIndex;
}
/** Remove the first occurrence of the element o from this list.
* Shift any subsequent elements to the left.
* Return true if the element is removed. */
#Override
public boolean remove(E e)
{
int index = indexOf(e);
if (index != -1) {
return remove(index);
} else {
return false;
}
}
/** Remove the element at the specified position in this list
* Shift any subsequent elements to the left.
* Return the element that was removed from the list. */
#Override
public boolean remove(int index)
{
if (index < 0 || index >= size) {
return false;
}
else if (index == 0) {
return removeFirst();
}
else if (index == size - 1) {
return removeLast();
}
else {
Node<E> previous = head;
for (int i = 1; i < index; i++) {
previous = previous.next;
}
Node<E> current = previous.next;
previous.next = current.next;
size--;
return true;
}
}
#Override
public boolean removeFirst()
{
if (size == 0) {
return false;
}
else {
Node<E> temp = head;
head = head.next;
size--;
if (head == null) {
tail = null;
}
return true;
}
}
#Override
public boolean removeLast()
{
if (size == 0) {
return false;
}
else if (size == 1) {
Node<E> temp = head;
head = tail = null;
size = 0;
return true;
}
else {
Node<E> current = head;
for (int i = 0; i < size - 2; i++) {
current = current.next;
}
Node<E> temp = tail;
tail = current;
tail.next = null;
size--;
return true;
}
}
#Override
public boolean set(int index, E e)
{
if (index < 0 || index > size - 1)
return false;
Node<E> current = head;
for (int i = 0; i < index; i++)
current = current.next;
E temp = current.element;
current.element = e;
return true;
}
#Override
public String toString()
{
StringBuilder result = new StringBuilder("[");
Node<E> current = head;
for (int i = 0; i < size; i++) {
result.append(current.element);
current = current.next;
if (current != null) {
result.append(", "); // Separate two elements with a comma
}
else {
result.append("]"); // Insert the closing ] in the string
}
}
return result.toString();
}
public String toStringBack()
{
StringBuilder result = new StringBuilder("[");
Node<E> current = tail;
for (int i = 0; i < size; i++) {
result.append(current.element);
current = current.previous;
if (current != null) {
result.append(", "); // Separate two elements with a comma
}
else {
result.append("]"); // Insert the closing ] in the string
}
}
return result.toString();
}
public void add(int index, E e)
{
if (index ==0) {
addFirst(e);// The new node is the only node in list
}
else if(index > size)
{
addLast(e);//The index location was bigger than size
}
else
{
Node<E> current = getAtIndex(index-1);
Node<E> temp = current.next;
current.next = new Node<E>(e);
(current.next).next = temp;
size++;
}
}
public void addFirst(E e)
{
Node<E> newNode = new Node<E>(e); // Create a new node
newNode.next = head; // link the new node with the head
head = newNode; // head points to the new node
size++; // Increase list size
if (tail == null) // the new node is the only node in list
tail = head;
}
public void addLast(E e)
{
Node<E> newNode = new Node<E>(e); // Create a new for element e
if (tail == null) {
head = tail = newNode; // The new node is the only node in list
}
else {
tail.next = newNode; // Link the new with the last node
tail = tail.next; // tail now points to the last node
}
size++;
}
protected Node<E> getAtIndex(int index)
{
int count;
if (index < 0 || index > size - 1)
return null;
Node<E> temp = null;
if(index <= (size/2))
{
count = -1;
temp = head;
while(++count <= index){
temp = temp.next;
}
}
else if (index > (size/2))
{
count = size;
temp = tail;
while(--count >= index){
temp = temp.previous; //--> this is Where the null pointer exception occurs
}
}
return temp;
}
private static class Node<E>{
E element;
Node<E> next;
Node<E> previous;
public Node(E element){
this.element = element;
next = null;
previous = null;
}
}
}
When I run the add(int index, E e) Method I receive a null pointer exception in the getAtIndext() method. I also have had issues getting the add(E e) Method to add properly when I change the current location. The methods are all as I am being required to use them. The use of iterators while they would be nice are not allowed. I am using Bluj as a compiler. Please let me know what questions you have.
Thank you
EDIT: I do know what a Null Pointer Exception is, I can not figure out why this is coming back as null. The Node "current" should point to the end, then go back in the list until it reaches the indexed location. This only happens when I try to add a node in the last half of the list. The error is thrown at temp = temp.previous;
The stack trace is:
java.lang.NullPointerException at MyDoublyLinkedList.getAtIndex(MyDoublyLinkedList.java:345) at MyDoublyLinkedList.add(MyDoublyLinkedList.java:289) at TestMyDoublyLinkedList.main(TestMyDoublyLinkedList.java:50)
Edit: I figured out the issue. The add() and getAtIndex functions are running properly. When I run the test the function that is throwing a Null Pointer Exception is throwing it at position 8. It cycles through the first few nodes fine, but dies at node 8
When inserting in the add() method, you never assign previous so it is null for all nodes.

What is wrong with the set method of my LinkedList

Im trying to implement a linkedlist.. All of my methods work except for the set method. It is only supposed to change the replace the element at the given index. But after setting the element in the index it is making the rest of the elements in the list to null, can anyone point out what I'm doing wrong in the set method?
public class LArrayList<E> {
private static class Node<E> {
Node<E> next;
E data;
public Node(E dataValue) {
next = null;
data = dataValue;
}
#SuppressWarnings("unused")
public Node(E dataValue, Node<E> nextValue) {
next = nextValue;
data = dataValue;
}
public E getData() {
return data;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> nextValue) {
next = nextValue;
}
}
private Node<E> head;
private static int listCount;
public LArrayList() {
head = new Node<>(null);
listCount = 0;
}
public void add(int index, E e) throws IndexOutOfBoundsException{
if (index < 0 || index >= listCount + 1) {
throw new IndexOutOfBoundsException("Bad index, please use index within range");
}
else{
Node<E> positionTemp = new Node<>(e);
Node<E> positionCurrent = head;
for (int i = 0; i < index && positionCurrent.getNext() != null; i++) {
positionCurrent = positionCurrent.getNext();
}
positionTemp.setNext(positionCurrent.getNext());
positionCurrent.setNext(positionTemp);
listCount++;
}
}
public E set(int index, E e) throws IndexOutOfBoundsException {
if (index < 0 || index >= listCount)
throw new IndexOutOfBoundsException("Bad index, please use index within range");
Node<E> positionTemp = new Node<>(e);
Node<E> positionCurrent = head;
for (int i = 0; i < index; i++) {
positionCurrent = positionCurrent.getNext();
}
positionCurrent.setNext(positionTemp);
return positionCurrent.getData();
}
public E get(int index) throws IndexOutOfBoundsException
{
if (index < 0 || index >= listCount)
throw new IndexOutOfBoundsException("Bad index, please use index within range");
Node<E> positionCurrent = head.getNext();
for (int i = 0; i < index; i++) {
if (positionCurrent.getNext() == null)
return null;
positionCurrent = positionCurrent.getNext();
}
return positionCurrent.getData();
}
public static void main(String[] args) {
LArrayList<String> aa = new LArrayList<String>();
aa.add(0, "0");
aa.add(1, "1");
aa.add(2, "2");
aa.add(3, "3");
aa.add(4, "4");
aa.add(5, "5");
System.out.println("The contents of AA are: " + aa);
aa.set(0, "a");
System.out.println("The contents of AA are: " + aa);
System.out.println(aa.get(0));
System.out.println(aa.get(1));
System.out.println(aa.get(2));
System.out.println(aa.get(3));
System.out.println(aa.get(4));
System.out.println(aa.get(5));
//OUTPUT IS: The contents of aa are: [0][1][2][3][4][5]
//The contents of AA are: [a][b][c][d][e]
//a
//A
//null
//null
//null
//null
}
}
After a quick look over your code:
positionCurrent.setNext(positionTemp);
Don't you need to also link positionTemp to the element after it?
First get the item just before current index:
for (int i = 0; i < index; i++) {
positionCurrent = positionCurrent.getNext();
}
You are missing a link between currently set item and rest of your list, Establish that by:
positionTemp.setNext(positionCurrent.getNext().getNext());
positionCurrent.setNext(positionTemp);
And return
positionCurrent.getNext().getData()
Hope it helps.
ok, so you have many problems in your code, i will help you with some but not all.
I really advise you to use Eclipse debugger(If you use eclipse), check this out:
http://www.vogella.com/tutorials/EclipseDebugging/article.html
First of all, the reason that your whole list is null after a set is that your index is 0 than you use a for loop that does nothing(cause the index is 0), so in the line after that:
positionCurrent.setNext(positionTemp);
You are setting head's next to be positionTemp, and than you are loosing the rest of the list cause you are not setting next for postionTemp(postionTemp next is null)
second, when you are adding the first item to the list, or when the list is empty and you are adding something, you need to make this new node the list's head, otherwise your list head will always be null.
third, when you want to print list, you cant use:
System.out.println("The contents of AA are: " + aa);
You need to do this instead:
Node<E> head = aa.head;
while(head != null){
system.out.println(head.data)
}
It looks like you have more bugs on your code, so i simply advise you use debugger.
Good luck

Categories