I'm asked this question and I'm not really sure what it means,
In our LinkedList class, the Node class is an internal class. Briefly
describe two things that would have to be coded differently if the
Node class was a separate class from the LinkedList class.
Here's the code for my LinkedList class:
public class LinkedList<T> implements LinkedListInterface<T> {
private Node head;
private Node tail;
private int count;
public LinkedList() {
head = null;
tail = null;
count = 0;
}
class Node {
T data;
Node next;
Node(T data) {
this.data = data;
next = null;
}
}
public Node getHead() {
return head;
}
public int add(T item) {
Node newNode = new Node(item);
if (isEmpty()) {
head = newNode;
} else {
tail.next = newNode;
}
tail = newNode;
count++;
return count;
}
public void add(T item, int pos) throws ListException {
if (pos < 1 || pos > count + 1) {
throw new ListException("Invalid position to insert at");
}
Node newNode = new Node(item);
if (count == 0) {
add(item);
} else if (pos == count + 1) {
add(item);
} else if (pos == 1) {
newNode.next = head;
head = newNode;
count++;
} else {
Node prev = jump(pos - 2);
newNode.next = prev.next;
prev.next = newNode;
count++;
}
}
private Node jump(int numJumps) {
Node nd = head;
for (int i = 0; i < numJumps; i++) {
nd = nd.next;
}
return nd;
}
public LinkedList<T> combine(LinkedList<T> obj2) {
Node list1 = this.getHead();
Node list2 = obj2.getHead();
if (list2 == null) {
return this;
}
if(list1==null) {
return obj2;
}
Node temp=list1;
while(temp.next!=null) {
temp = temp.next;
}
temp.next=list2;
return this;
}
public int contains(T item) {
Node nd = this.head;
for (int pos = 1; pos <= count; pos++) {
if (nd.data.equals(item)) {
return pos;
}
nd = nd.next;
}
return 0;
}
public LinkedList<T> copy() {
LinkedList<T> l = new LinkedList<T>();
try {
for (int pos = 1; pos <= count; pos++)
l.add(retrieve(pos));
}
catch(ListException e) {
System.out.println("Should not occur (Copy)");
}
return l;
}
public boolean equals(Object list) {
if (list == null) {
return false;
}
LinkedList myLinkedList = (LinkedList)list;
if(myLinkedList.getClass() != this.getClass()) {
return false;
}
if(myLinkedList.length() != this.length()) {
return false;
}
try{
for (int pos = 1; pos <= count; pos++) {
if(!myLinkedList.retrieve(pos).equals(this.retrieve(pos))) {
return false;
}
}
}
catch (ListException e) {
System.out.println("Should not occur");
}
return true;
}
public boolean isEmpty() {
return length() == 0;
}
public int length() {
return count;
}
#SuppressWarnings("unchecked")
public T remove(int pos) throws ListException {
if (pos < 1 || pos > count) {
throw new ListException("Invalid position to remove from");
}
Node removedItem = null;
if (count == 1) {
removedItem = head;
head = null;
tail = null;
} else if (pos == 1) {
removedItem = head;
head = head.next;
} else if (pos == count) {
removedItem = tail;
Node prev = jump(pos - 2);
prev.next = null;
tail = prev;
} else {
Node prev = jump(pos - 2);
removedItem = prev.next;
prev.next = prev.next.next;
}
count--;
return removedItem.data;
}
public int remove(T item) {
int numRemoved = 0;
int pos = -1;
try {
while ((pos = contains(item)) > 0) {
remove(pos);
numRemoved++;
}
} catch (ListException e){
System.out.print(e);
}
return numRemoved;
}
int find_length(Node list){
int count = 0;
while (list!=null) {
count++;
list=list.next;
}
return count;
}
public void replace(T item, int pos) throws ListException {
if (pos < 1 || pos > count + 1) {
throw new ListException("Invalid position to replace at");
}
Node list = this.getHead();
int length = find_length(list);
if(pos<1||pos>length){
return;
}
while(list!=null){
pos--;
if(pos==0){
list.data=item;
return;
}
list=list.next;
}
}
public T retrieve(int pos) throws ListException {
T item = null;
if (pos < 1 || pos > count) {
throw new ListException("Invalid position to retrieve from");
}
if (pos == 1) {
return head.data;
}
Node prev = jump(pos - 2);
item = prev.next.data;
return item;
}
public LinkedList<T> reverse() {
LinkedList<T> l = new LinkedList<T>();
try {
for (int pos = count; pos > 0; pos--)
l.add(retrieve(pos));
}
catch (ListException e) {
System.out.println("Should not occur (Reverse)");
}
return l;
}
public String toString() {
String temp = "";
Node nd = head;
while (nd != null) {
temp += nd.data + "-";
nd = nd.next;
}
return temp;
}
}
What I'm trying to get is the since the Node class is located in the same class as my LinkedList class, it is referred to as an internal class. If it were to be separate, would I have to implement a Node class similarly to the LinkedListInterface<T> class? What else would have to be coded differently?
I was solving a small assignment from the Infytq Learning program, where I come across this hindrance. i can't seem to figure out the problem I'm having.
Given a queue.
I have to form a new queue of whole numbers from the given queue where the numbers in the queue are evenly
divisible by all the numbers from 1 to 10.
Here's what I have done so far. I'm currently getting empty queue.
class Queue {
private int front;
private int rear;
private int maxSize;
private int arr[];
Queue(int maxSize) {
this.front = 0;
this.rear = -1;
this.maxSize = maxSize;
this.arr = new int[this.maxSize];
}
public boolean isFull() {
if (rear == maxSize - 1) {
return true;
}
return false;
}
public boolean enqueue(int data) {
if (isFull()) {
return false;
} else {
arr[++rear] = data;
return true;
}
}
public void display() {
if(isEmpty())
System.out.println("Queue is empty!");
else {
for (int index = front; index <= rear; index++) {
System.out.println(arr[index]);
}
}
}
public boolean isEmpty() {
if (front > rear)
return true;
return false;
}
public int dequeue() {
if (isEmpty()) {
return Integer.MIN_VALUE;
} else {
int data = arr[this.front];
arr[front++] = Integer.MIN_VALUE;
return data;
}
}
public int getMaxSize() {
return maxSize;
}
}
class Tester {
public static void main(String[] args) {
Queue queue = new Queue(7);
queue.enqueue(13983);
queue.enqueue(10080);
queue.enqueue(7113);
queue.enqueue(2520);
queue.enqueue(2500);
Queue outputQueue = findEvenlyDivisibleNumbers(queue);
System.out.println("Evenly divisible numbers");
outputQueue.display();
}
public static Queue findEvenlyDivisibleNumbers(Queue queue) {
//Implement your code here and change the return value accordingly
Queue nqueue = new Queue(queue.getMaxSize());
boolean flag = true;
while(!(queue.isEmpty())){
int val = queue.dequeue();
for(int i=2;i<=10;i++){
if(val%i!=0){
flag=false;
break;
}
}
if(flag){
nqueue.enqueue(val);
}
}
return nqueue;
}
}
You should reset your flag to true before each iteration of your while loop (as you've been suggested already).
In order to avoid such issues, consider extracting the internal loop into a separate method. That will help avoiding nested loop breaking confusion:
public static boolean isDivisible(int value) {
for (int i = 2; i < 10; i++) {
if (value % i > 0) {
return false;
}
}
return true;
}
then simply use it while iterating over your queue:
public static Queue findEvenlyDivisibleNumbers(Queue queue) {
Queue nqueue = new Queue(queue.getMaxSize());
while (!(queue.isEmpty())) {
int value = queue.dequeue();
if (isDivisible(value)) {
nqueue.enqueue(value);
}
}
return nqueue;
}
I currently want a data structure that acts like a Deque with indexing.
So, it should have O(1) addition and removal of elements at the front and back, as well as O(1) access of elements based on the index. It is not that hard to imagine a setup that would work for this.
It seems like ArrayDeque would be a natural choice for this. However, ArrayDeque does not implement List. Since the underlying data structure is an array, is there a good reason that it does not allow indexing?
Also, on a more practical note, does anyone know of any library doing the thing I want. Apache Commons does not have one as far as I can see.
(edit, original answer was mostly wrong)
There's no good reason why this class doesn't have an indexing. I checked the source code. It runs exactly like I suggested above. Some of the other items might be harder to add within the List interface. But, simple get wouldn't be one of them.
You take an array of a given size depending on your usage. Then set the start position halfway into it. Then you track a variable for the head and the tail. As you iterate items you move the head back and tail forward expanding outward. If you reach need a value outside the range you modulo that value so .length is equal to 0, and -1 is equal to (.length -1) and you keep adding values until ((tail - head) > .length) at which point you build another array copying all the pieces to be coherent usually about twice the size. Then to index it, you take head +index to get the real index.
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayDeque.java
Pretty sure the get is trivially akin to:
#Override
public E get(int index) {
int i = (head + index) & (elements.length - 1);
return elements[i];
}
Which seems like they should almost certainly have that. (See source code link for licensing info for the following).
import java.io.*;
import java.util.AbstractCollection;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
public class ArrayDequeList<E> extends AbstractCollection<E> implements Deque<E>, Cloneable, Serializable, List<E>
{
private transient E[] elements;
private transient int head;
private transient int tail;
private static final int MIN_INITIAL_CAPACITY = 8;
private void allocateElements(int numElements) {
int initialCapacity = MIN_INITIAL_CAPACITY;
// Find the best power of two to hold elements.
// Tests "<=" because arrays aren't kept full.
if (numElements >= initialCapacity) {
initialCapacity = numElements;
initialCapacity |= (initialCapacity >>> 1);
initialCapacity |= (initialCapacity >>> 2);
initialCapacity |= (initialCapacity >>> 4);
initialCapacity |= (initialCapacity >>> 8);
initialCapacity |= (initialCapacity >>> 16);
initialCapacity++;
if (initialCapacity < 0) // Too many elements, must back off
initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
}
elements = (E[]) new Object[initialCapacity];
}
#Override
public boolean addAll(int index, #NonNull Collection<? extends E> c) {
return false;
}
#Override
public E get(int index) {
int i = (head + index) & (elements.length - 1);
return elements[i];
}
#Override
public E set(int index, E element) {
int i = (head + index) & (elements.length - 1);
E old = elements[i];
elements[i] = element;
return old;
}
#Override
public void add(int index, E element) {
throw new IllegalStateException("This one is hard to do.");
}
#Override
public E remove(int index) {
throw new IllegalStateException("This one is hard to do.");
}
#Override
public int indexOf(Object o) {
throw new IllegalStateException("This one's not that hard but pass..");
}
#Override
public int lastIndexOf(Object o) {
throw new IllegalStateException("This one's not that hard but pass..");
}
#Override
public ListIterator<E> listIterator() {
throw new IllegalStateException("Needs to write a new iterator..");
}
#NonNull
#Override
public ListIterator<E> listIterator(int index) {
throw new IllegalStateException("Needs to write a new iterator..");
}
#NonNull
#Override
public List<E> subList(int fromIndex, int toIndex) {
throw new IllegalStateException("Hm, not sure how this would work.");
}
private void doubleCapacity() {
assert head == tail;
int p = head;
int n = elements.length;
int r = n - p; // number of elements to the right of p
int newCapacity = n << 1;
if (newCapacity < 0)
throw new IllegalStateException("Sorry, deque too big");
Object[] a = new Object[newCapacity];
System.arraycopy(elements, p, a, 0, r);
System.arraycopy(elements, 0, a, r, p);
elements = (E[])a;
head = 0;
tail = n;
}
private <T> T[] copyElements(T[] a) {
if (head < tail) {
System.arraycopy(elements, head, a, 0, size());
} else if (head > tail) {
int headPortionLen = elements.length - head;
System.arraycopy(elements, head, a, 0, headPortionLen);
System.arraycopy(elements, 0, a, headPortionLen, tail);
}
return a;
}
public ArrayDequeList() {
elements = (E[]) new Object[16];
}
public ArrayDequeList(int numElements) {
allocateElements(numElements);
}
public ArrayDequeList(Collection<? extends E> c) {
allocateElements(c.size());
addAll(c);
}
public void addFirst(E e) {
if (e == null)
throw new NullPointerException();
elements[head = (head - 1) & (elements.length - 1)] = e;
if (head == tail)
doubleCapacity();
}
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e;
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();
}
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
public boolean offerLast(E e) {
addLast(e);
return true;
}
public E removeFirst() {
E x = pollFirst();
if (x == null)
throw new NoSuchElementException();
return x;
}
public E removeLast() {
E x = pollLast();
if (x == null)
throw new NoSuchElementException();
return x;
}
public E pollFirst() {
int h = head;
E result = elements[h]; // Element is null if deque empty
if (result == null)
return null;
elements[h] = null; // Must null out slot
head = (h + 1) & (elements.length - 1);
return result;
}
public E pollLast() {
int t = (tail - 1) & (elements.length - 1);
E result = elements[t];
if (result == null)
return null;
elements[t] = null;
tail = t;
return result;
}
public E getFirst() {
E x = elements[head];
if (x == null)
throw new NoSuchElementException();
return x;
}
public E getLast() {
E x = elements[(tail - 1) & (elements.length - 1)];
if (x == null)
throw new NoSuchElementException();
return x;
}
public E peekFirst() {
return elements[head]; // elements[head] is null if deque empty
}
public E peekLast() {
return elements[(tail - 1) & (elements.length - 1)];
}
public boolean removeFirstOccurrence(Object o) {
if (o == null)
return false;
int mask = elements.length - 1;
int i = head;
E x;
while ( (x = elements[i]) != null) {
if (o.equals(x)) {
delete(i);
return true;
}
i = (i + 1) & mask;
}
return false;
}
public boolean removeLastOccurrence(Object o) {
if (o == null)
return false;
int mask = elements.length - 1;
int i = (tail - 1) & mask;
E x;
while ( (x = elements[i]) != null) {
if (o.equals(x)) {
delete(i);
return true;
}
i = (i - 1) & mask;
}
return false;
}
public boolean add(E e) {
addLast(e);
return true;
}
public boolean offer(E e) {
return offerLast(e);
}
public E remove() {
return removeFirst();
}
public E poll() {
return pollFirst();
}
public E element() {
return getFirst();
}
public E peek() {
return peekFirst();
}
public void push(E e) {
addFirst(e);
}
public E pop() {
return removeFirst();
}
private void checkInvariants() {
assert elements[tail] == null;
assert head == tail ? elements[head] == null :
(elements[head] != null &&
elements[(tail - 1) & (elements.length - 1)] != null);
assert elements[(head - 1) & (elements.length - 1)] == null;
}
private boolean delete(int i) {
checkInvariants();
final E[] elements = this.elements;
final int mask = elements.length - 1;
final int h = head;
final int t = tail;
final int front = (i - h) & mask;
final int back = (t - i) & mask;
// Invariant: head <= i < tail mod circularity
if (front >= ((t - h) & mask))
throw new ConcurrentModificationException();
// Optimize for least element motion
if (front < back) {
if (h <= i) {
System.arraycopy(elements, h, elements, h + 1, front);
} else { // Wrap around
System.arraycopy(elements, 0, elements, 1, i);
elements[0] = elements[mask];
System.arraycopy(elements, h, elements, h + 1, mask - h);
}
elements[h] = null;
head = (h + 1) & mask;
return false;
} else {
if (i < t) { // Copy the null tail as well
System.arraycopy(elements, i + 1, elements, i, back);
tail = t - 1;
} else { // Wrap around
System.arraycopy(elements, i + 1, elements, i, mask - i);
elements[mask] = elements[0];
System.arraycopy(elements, 1, elements, 0, t);
tail = (t - 1) & mask;
}
return true;
}
}
public int size() {
return (tail - head) & (elements.length - 1);
}
public boolean isEmpty() {
return head == tail;
}
public Iterator<E> iterator() {
return new DeqIterator();
}
public Iterator<E> descendingIterator() {
return new DescendingIterator();
}
private class DeqIterator implements Iterator<E> {
private int cursor = head;
private int fence = tail;
private int lastRet = -1;
public boolean hasNext() {
return cursor != fence;
}
public E next() {
if (cursor == fence)
throw new NoSuchElementException();
E result = elements[cursor];
// This check doesn't catch all possible comodifications,
// but does catch the ones that corrupt traversal
if (tail != fence || result == null)
throw new ConcurrentModificationException();
lastRet = cursor;
cursor = (cursor + 1) & (elements.length - 1);
return result;
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
if (delete(lastRet)) { // if left-shifted, undo increment in next()
cursor = (cursor - 1) & (elements.length - 1);
fence = tail;
}
lastRet = -1;
}
}
private class DescendingIterator implements Iterator<E> {
private int cursor = tail;
private int fence = head;
private int lastRet = -1;
public boolean hasNext() {
return cursor != fence;
}
public E next() {
if (cursor == fence)
throw new NoSuchElementException();
cursor = (cursor - 1) & (elements.length - 1);
E result = elements[cursor];
if (head != fence || result == null)
throw new ConcurrentModificationException();
lastRet = cursor;
return result;
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
if (!delete(lastRet)) {
cursor = (cursor + 1) & (elements.length - 1);
fence = head;
}
lastRet = -1;
}
}
public boolean contains(Object o) {
if (o == null)
return false;
int mask = elements.length - 1;
int i = head;
E x;
while ( (x = elements[i]) != null) {
if (o.equals(x))
return true;
i = (i + 1) & mask;
}
return false;
}
public boolean remove(Object o) {
return removeFirstOccurrence(o);
}
public void clear() {
int h = head;
int t = tail;
if (h != t) { // clear all cells
head = tail = 0;
int i = h;
int mask = elements.length - 1;
do {
elements[i] = null;
i = (i + 1) & mask;
} while (i != t);
}
}
public Object[] toArray() {
return copyElements(new Object[size()]);
}
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
copyElements(a);
if (a.length > size)
a[size] = null;
return a;
}
public ArrayDequeList<E> clone() {
try {
ArrayDequeList<E> result = (ArrayDequeList<E>) super.clone();
result.elements = Arrays.copyOf(elements, elements.length);
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
private static final long serialVersionUID = 2340785798034038923L;
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
// Write out size
s.writeInt(size());
// Write out elements in order.
int mask = elements.length - 1;
for (int i = head; i != tail; i = (i + 1) & mask)
s.writeObject(elements[i]);
}
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
// Read in size and allocate array
int size = s.readInt();
allocateElements(size);
head = 0;
tail = size;
// Read in all elements in the proper order.
for (int i = 0; i < size; i++)
elements[i] = (E)s.readObject();
}
}
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.
I am currently in the midst of defining my own class of Deque called myDeque using ListNodes. A problem I am facing concerns the remove() method. How do you modify the Deque to point to the node behind back and delete what used to be "back"? Thank you
private ListNode<E> front; // Reference to first ListNode in the Deque
private ListNode<E> back; // Reference to last ListNode in the Deque
private int numElems; // Current number of ListNodes in the Deque
public MyDeque() {
front = null;
back = null;
numElems = 0;
}
public void addLast(E e) {
if (numElems == 0){
front = new ListNode<E>(e,null);
back = front;
} else {
back.next = new ListNode<E>(e,null);
back = back.next;
}
numElems += 1;
}
public boolean add(E e) {
if (numElems == 0){
front = new ListNode<E>(e,null);
back = front;
} else {
ListNode<E> prevData = back;
back.next = new ListNode<E>(e,null);
back = back.next;
}
numElems += 1;
return true;
}
public boolean remove(Object o) {
if (numElems == 0){
throw new NoSuchElementException();
}
return false;
}
public E removeLast() {
if (numElems == 0){
throw new NoSuchElementException();
}
else{
numElems = numElems - 1;
}
return null;
}
back = back.back; //modify the Deque to point to the node behind back
back.next = null; //and delete what used to be "back"