I am currently working on creating a DoublyLinkedList which uses tail recursion.
I have managed to get all my methods fully working except my insert item.
It works for inserting at any Index other than 0. I have tried to write an if statement which deals with this and my code still runs however although it increments the noOfItems. It never adds the item to my list.
Could the issue be with my toString? Or am I missing something in my if case?
This is my DLLNode class:
public class DLLNode
{
private DLLNode previous;
public DLLNode next;
private String value;
public DLLNode(String value)
{
this.value = value;
this.previous = previous;
this.next = next;
}
public DLLNode(String value, DLLNode next, DLLNode previous)
{
this.value = value;
this.next = next;
this.previous = previous;
}
public String GetDataItem()
{
return value;
}
public void setDataItem()
{
this.value = value;
}
public DLLNode GetPreviousNode()
{
return previous;
}
public void setPrevious(DLLNode previous)
{
this.previous = previous;
}
public DLLNode GetNextNode()
{
return next;
}
public void setNextNode(DLLNode next)
{
this.next = next;
}
public void addItem(String value) {
if(this.next == null) {
DLLNode newNode = new DLLNode(value);
this.next = newNode;
} else {
this.next.addItem(value);
}
}
public void InsertItemHelper(String value, int indexToInsert, int current, DLLNode currNode)
{
if (indexToInsert == 0)
{
DLLNode newNode = new DLLNode(value);
currNode.GetNextNode().setPrevious(newNode);
}
else if (current == indexToInsert-1)
{
DLLNode newNode = new DLLNode(value);
newNode.setNextNode(currNode.GetNextNode());
currNode.setNextNode(newNode);
currNode.GetNextNode().setPrevious(newNode);
newNode.setPrevious(currNode);
}
else
{
InsertItemHelper(value, indexToInsert, current+1, currNode.GetNextNode());
}
}
public void DeleteItemHelper(int indexToDelete, int current, DLLNode currNode)
{
if (current == indexToDelete-1)
{
currNode.setNextNode(currNode.GetNextNode().GetNextNode());
}
else
{
DeleteItemHelper(indexToDelete, current+1, currNode.GetNextNode());
}
}
}
And this is my DoublyLinkedList class:
public class DoublyLinkedList
{
private int noOfItems;
private DLLNode head;
private DLLNode tail;
// Default constructor
public DoublyLinkedList()
{
head = null;
tail = null;
this.noOfItems = 0;
}
public int GetNoOfItems()
{
return noOfItems;
}
public String GetItemByIndex(int index)
{
int count = 0;
while (count < index)
{
head = head.GetNextNode();
count++;
}
return head.GetDataItem();
}
public DLLNode GetNodeByIndex(int index)
{
int count = 0;
while (count < index)
{
head = head.GetNextNode();
count++;
}
return head;
}
public void AddItem(String value)
{
if (head == null)
{
DLLNode newNode = new DLLNode(value);
head = newNode;
noOfItems++;
}
else
{
head.addItem(value);
noOfItems++;
}
}
public void InsertItem(int index, String value)
{
if (index > noOfItems)
{
AddItem(value);
}
else {
head.InsertItemHelper(value, index, 0, head);
noOfItems++;
}
}
public void DeleteItem(int index)
{
if (index ==0)
{
System.out.println("Out of Bounds");
}
if (index > noOfItems)
{
System.out.println("Out of Bounds");
}
if (head == null)
{
System.out.println("No Item to remove");
}
else if (index == 1)
{
head = head.GetNextNode();
noOfItems--;
}
else
{
head.DeleteItemHelper(index, 0, head);
noOfItems--;
}
}
public int getNoOfItems()
{
return this.noOfItems;
}
public boolean isEmpty()
{
return (head == null);
}
public String toString()
{
DLLNode currentNode = head;
StringBuilder sb = new StringBuilder();
while (currentNode != null) {
sb.append(currentNode.GetDataItem());
if (currentNode.GetNextNode() != null)
{
sb.append(",");
}
currentNode = currentNode.GetNextNode();
}
return sb.toString();
}
}
I have added the following code into my insert item:
if (index ==0)
{
DLLNode newNode = new DLLNode(value);
head.setNextNode(head);
// newNode.next= head.GetNextNode();
head = newNode;
noOfItems++;
}
If I include the commented out line I get an error to do with string builder.
With the line commented out it adds in the linked list at position 0, but doesn't add any of the rest. It does however increment noOfItems correctly.
The following error is what appears:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2367)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:415)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at ads2.DoublyLinkedList.toString(DoublyLinkedList.java:155)
at java.lang.String.valueOf(String.java:2847)
at java.lang.StringBuilder.append(StringBuilder.java:128)
at ads2.Main.printList(Main.java:62)
at ads2.Main.main(Main.java:38)
Java Result: 1
BUILD SUCCESSFUL (total time: 1 second)
If you need any more details on the error please let me know.
You need to update the head when adding at position 0
Because you don't update the head, the old head is still linked in the list object, and it's next() returns what should be in the new list object index 1, so you end up with the same list
You could confirm this by confirming
list.getNodeByIndex(0) != list.getNodeByIndex(1).previousNode();
Related
So I have an implementation of the Singly Linked List and I am trying to add a method which reports the second to last node of the list. However, I was not sure if I am allowed to write the method under the Node class then access it from the Singly Linked List class. If I do this, my instance variable of the node class('head' is used as a variable to access the penultimate method but also as the input of the penultimate method. Is that okay? Below is my implementation/attempt.
public class SinglyLinkedList {
private static class Node<Integer>{
private Integer element;
private Node<Integer> next;
private Node<Integer> penultimate;
public Node(Integer e, Node<Integer> n) {
element = e;
next = n;
penultimate = null;
}
public Integer getElement() {return element;}
public Node<Integer> getNext(){return next;}
public void setNext(Node<Integer> n) {next = n;}
public Node<Integer> penultimate(Node<Integer> head) {
Node<Integer> current = head;
while(current != null) {
if(head.getNext() == null) {
penultimate = head;
}
else {
current = current.getNext();
}
}
return penultimate;
}
}
private Node<Integer> head = null;
private Node<Integer> tail = null;
private int size = 0;
public SinglyLinkedList() {}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public Integer first() {
if (isEmpty()) {
return null;
}
return head.getElement();
}
public Integer last() {
if(isEmpty()) {
return null;
}
return tail.getElement();
}
public void addFirst(Integer i) {
head = new Node<> (i, head);
if(size == 0) {
tail = head;
}
size++;
}
public void addLast(Integer i) {
Node<Integer> newest = new Node<>(i,null);
if(isEmpty()) {
head = newest;
}
else {
tail.setNext(newest);
tail = newest;
size++;
}
}
public Integer removeFirst() {
if(isEmpty()) {
return null;
}
Integer answer = head.getElement();
head = head.getNext();
size--;
if(size == 0) {
tail = null;
}
return answer;
}
public void getPenultimate() {
if(isEmpty()) {
System.out.println("List is empty. Please check.");
}
else {
System.out.println("The second last node is: " + head.penultimate(head));
}
}
Remove the field penultimate. You do not want it in every node, in fact in no node, but calculated.
In the Node's penultimate method head should not be used in the loop.
//private Node<Integer> penultimate;
// head: ...#->#->#->P->null
public Node<Integer> penultimate(Node<Integer> head) {
Node<Integer> penultimate = null;
Node<Integer> current = head;
while (current != null) {
if (current.getNext() == null) {
penultimate = current;
break;
}
current = current.getNext();
}
return penultimate;
}
Or the third (second?) to last node:
// head: ...#->#->#->P->#->null
public Node<Integer> penultimate(Node<Integer> head) {
Node<Integer> penultimate = null;
Node<Integer> current = head;
while (current != null) {
if (current.getNext() == null) {
break;
}
penultimate = current;
current = current.getNext();
}
return penultimate;
}
Why not keep track of the second to last node?
private Node<Integer> head = null;
private Node<Integer> tail = null;
private Node<Integer> secondToLast = null;
private int size = 0;
public SinglyLinkedList() {}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public Integer first() {
if (isEmpty()) {
return null;
}
return head.getElement();
}
public Integer last() {
if(isEmpty()) {
return null;
}
return tail.getElement();
}
public void addFirst(Integer i) {
if (size == 1) {
secondToLast = head;
}
head = new Node<> (i, head);
if(size == 0) {
tail = head;
}
size++;
}
public void addLast(Integer i) {
Node<Integer> newest = new Node<>(i,null);
if(isEmpty()) {
head = newest;
}
else {
tail.setNext(newest);
secondToLast = tail;
}
tail = newest;
size++;
}
public Integer removeFirst() {
if(isEmpty()) {
return null;
}
Integer answer = head.getElement();
head = head.getNext();
size--;
if(size == 0) {
tail = null;
}
if (size == 1) {
secondToLast = null;
}
return answer;
}
public void getPenultimate() {
if(isEmpty()) {
System.out.println("List is empty. Please check.");
}
else {
System.out.println("The second last node is: " + secondToLast);
}
}
I am struggling to understand how to implement a remove(); for both a double and single linked class. I have figured out how to remove the first node in the double, but not in the single. First I would like to debug, problem solve the single linked class, then work on the double after that.
Here is the code I have so far for the Single Linked Class.
public class SingleLinkedClass<T> {
private Node <T> head;
private Node <T> tail;
private int size;
public SingleLinkedClass() {
size = 0;
head = null;
tail = null;
}
public void insertAtHead(T v)
{
//Allocate new node
Node newNode = new Node(v, head);
//Change head to point to new node
head = newNode;
if(tail == null)
{
tail = head;
}
//Increase size
size++;
}
public void insertAtTail(T v)
{
if(tail == null)
{
tail = new Node(v, null);
head = tail;
size++;
return;
}
Node newNode = new Node(v, null);
tail.nextNode = newNode;
tail = newNode;
size++;
}
public T removeHead()
{
if(head == null)
{
throw new IllegalStateException("list is empty! cannot delete");
}
T value = head.value;
head = head.nextNode;
size--;
return value;
}
public void removeTail()
{
//Case 1: list empty
if(head == null)
{
return;
}
//Case 2: list has one node
else if(head == tail)
{
head = tail = null;
}
else
{
Node temp = head;
while(temp.nextNode != tail)
{
temp = temp.nextNode;
}
tail = temp;
tail.nextNode = null;
}
size--;
}
public boolean remove(T v) {
Node<T> previous = head;
Node<T> cursor = head.nextNode;
if (head.nextNode == null) {
return false;
}
while(cursor != tail){
if (cursor.value.equals(v)) {
previous = cursor.nextNode;
return true;
}
previous = cursor;
cursor = cursor.nextNode;
}
return false;
}
public String toString() {
if (head == null) {
return "The list is Empty!";
}
String result = "";
Node temp = head;
while (temp != null) {
result += temp.toString() + " ";
temp = temp.nextNode;
}
return result;
}
public int size() {
return size;
}
private class Node <T> {
private T value;
private Node <T> nextNode;
public Node(T v, Node<T> n) {
value = v;
nextNode = n;
}
public String toString() {
return "" + value;
}
}
}
Here is my Double Linked Class
public class DoubelyLinkedList<E> {
private int size;
private Node<E> header;
private Node<E> trailer;
public DoubelyLinkedList() {
size = 0;
header = new Node<E>(null, null, null);
trailer = new Node<E>(null, null, header);
header.next = trailer;
}
public boolean remove(E v) {
//If the list is empty return false
if(header.next == trailer){
return false;
}
//If v is the head of the list remove and return true
Node <E> cursor = header.next;
for (int i = 0; i < size; i++) {
//Remove at Head
if(cursor.value.equals(v)){
removeAtHead();
}
cursor = cursor.next;
}
return true;
}
/*
} */
public void insertAtHead(E v) {
insertBetween(v, header, header.next);
}
public void insertAtTail(E v) {
insertBetween(v, trailer.prev, trailer);
}
private void insertBetween(E v, Node<E> first, Node<E> second) {
Node<E> newNode = new Node<>(v, second, first);
first.next = newNode;
second.prev = newNode;
size++;
}
public E removeAtHead() {
return removeBetween(header, header.next.next);
}
public E removeAtTail() {
return removeBetween(trailer.prev.prev, trailer);
}
private E removeBetween(Node<E> first, Node<E> second) {
if (header.next == trailer)// if the list is empty
{
throw new IllegalStateException("The list is empty!");
}
E result = first.next.value;
first.next = second;
second.prev = first;
size--;
return result;
}
public String toStringBackward() {
if (size == 0) {
return "The list is empty!";
}
String r = "";
Node<E> temp = trailer.prev;
while (temp != header) {
r += temp.toString() + " ";
temp = temp.prev;
}
return r;
}
public String toString() {
if (size == 0) {
return "The list is empty!";
}
String r = "";
Node<E> temp = header.next;
while (temp != trailer) {
r += temp + " ";
temp = temp.next;
}
return r;
}
private static class Node<T> {
private T value;
private Node<T> next;
private Node<T> prev;
public Node(T v, Node<T> n, Node<T> p) {
value = v;
next = n;
prev = p;
}
public String toString() {
return value.toString();
}
}
}
Here is my Driver
public class Driver {
public static void main(String[] args) {
DoubelyLinkedList<String> doubley = new DoubelyLinkedList();
SingleLinkedClass<String> single = new SingleLinkedClass();
single.insertAtHead("Bob");
single.insertAtHead("Sam");
single.insertAtHead("Terry");
single.insertAtHead("Don");
System.out.println(single);
single.remove("Bob");
System.out.println("Single Remove Head: " + single);
/*
single.remove("Don");
System.out.println("Single Remove Tail: " + single);
single.remove("Terry");
System.out.println("Single Remove Inbetween: " + single);
*/
System.out.println();
System.out.println();
doubley.insertAtHead("Bob");
doubley.insertAtHead("Sam");
doubley.insertAtHead("Terry");
doubley.insertAtHead("Don");
System.out.println(doubley);
doubley.remove("Bob");
System.out.println("Double Remove Head: " + doubley);
doubley.remove("Don");
System.out.println("Double Remove Tail: " + doubley);
/*
doubley.remove("Sam");
System.out.println("Double Remove Inbetween: " + doubley);
*/
}
}
In the removeHead moving head to its next, it might become null. Then tail was the head too. Then tail should be set to null too.
DoublyLinkedList is better English than DoubelyLinkedList.
As this is homework, I leave it by this.
I'm currently trying to create a DoublyLinked list that uses tail recursion.
I have my addItem fully working. My InsertItem successfully inserts and item at the specified index. However it removes whatever item was there and doesn't move all the data along. My code also crashes when trying to add at index 1. I have commented out the code I attempted to get this working.
Here is my Node class:
public class DLLNode
{
private DLLNode previous;
public DLLNode next;
private String value;
public DLLNode(String value)
{
this.value = value;
this.previous = previous;
this.next = next;
}
public DLLNode(String value, DLLNode next, DLLNode previous)
{
this.value = value;
this.next = next;
this.previous = previous;
}
public String GetDataItem()
{
return value;
}
public void setDataItem()
{
this.value = value;
}
public DLLNode GetPreviousNode()
{
return previous;
}
public void setPrevious(DLLNode previous)
{
this.previous = previous;
}
public DLLNode GetNextNode()
{
return next;
}
public void setNextNode(DLLNode next)
{
this.next = next;
}
public void addItem(String value) {
if(this.next == null) {
DLLNode newNode = new DLLNode(value);
this.next = newNode;
} else {
this.next.addItem(value);
}
}
public void InsertItemHelper(String value, int indexToInsert, int current, DLLNode currNode)
{
/*if (indexToInsert == 1)
{
DLLNode newNode = new DLLNode(value);
currNode.setNextNode(newNode);
}*/
if (current == indexToInsert-2)
{
DLLNode newNode = new DLLNode(value);
currNode.setNextNode(currNode.GetNextNode().GetNextNode());
newNode.setNextNode(currNode.GetNextNode());
currNode.setNextNode(newNode);
newNode.setPrevious(currNode);
}
else
{
InsertItemHelper(value, indexToInsert, current+1, currNode.GetNextNode());
}
}
public void DeleteItemHelper(int indexToDelete, int current, DLLNode currNode)
{
if (current == indexToDelete-2)
{
currNode.setNextNode(currNode.GetNextNode().GetNextNode());
}
else
{
DeleteItemHelper(indexToDelete, current+1, currNode.GetNextNode());
}
}
}
And here is my DoublyLinkedList class. Any help and tips much appreciated.
public class DoublyLinkedList
{
private int noOfItems;
private DLLNode head;
private DLLNode tail;
// Default constructor
public DoublyLinkedList()
{
head = null;
tail = null;
this.noOfItems = 0;
}
public int GetNoOfItems()
{
return noOfItems;
}
/* Returns the String value held at index (base zero) or null if the index
* is out of bounds */
public String GetItemByIndex(int index)
{
return null;
}
public DLLNode GetNodeByIndex(int index)
{
return null;
}
public void AddItem(String value)
{
if (head == null)
{
DLLNode newNode = new DLLNode(value);
head = newNode;
noOfItems++;
}
else
{
head.addItem(value);
noOfItems++;
}
}
public void InsertItem(int index, String value)
{
if (index > noOfItems)
{
AddItem(value);
}
else {
head.InsertItemHelper(value, index, 0, head);
noOfItems++;
}
}
public void DeleteItem(int index)
{
if (index ==0)
{
System.out.println("Out of Bounds");
}
if (index > noOfItems)
{
System.out.println("Out of Bounds");
}
if (head == null)
{
System.out.println("No Item to remove");
}
else if (index == 1)
{
head = head.GetNextNode();
noOfItems--;
}
else
{
head.DeleteItemHelper(index, 0, head);
noOfItems--;
}
}
public int getNoOfItems()
{
return this.noOfItems;
}
public boolean isEmpty()
{
return (head == null);
}
}
Think about what's going on here:
currNode.setNextNode(currNode.GetNextNode().GetNextNode());
newNode.setNextNode(currNode.GetNextNode());
currNode.setNextNode(newNode);
newNode.setPrevious(currNode);
Analysis of your snippet
let A:= currnode; B:=currnode.getNextNode(); C:=currnode.getNextNode();
So we have something like A -> B -> C
currNode.setNextNode(currNode.GetNextNode().GetNextNode());
A ->C
newNode.setNextNode(currNode.GetNextNode());
newNode -> C
currNode.setNextNode(newNode);
A -> newNode -> C
newNode.setPrevious(currNode);
set backlink from newNode to A
What you probably want to do
newNode.setNextNode(currNode.getNextNode());
newNode -> B
now we can change the link from currNode to the newNode
currNode.setNextNode(newNode);
A -> newNode
So now you should have something like A -> newNode -> B. No need to ever touch C.
So now you can fix the backlinks and you're done.
currNode.getNextNode().setPrevious(newNode);
set backlink from B to newNode
newNode.setPrevious(currNode);
set backlink from newNode to currNode
p.s.: I didn't test this. I didn't look into the if-conditions themselves, I didn't think about your indexToInsert ==1-case, etc.. still I hope to have given you an idea where the mistake is coming from and pointed you in the right direction...
p.p.s.: It is considered good practice to stick to the standard java naming conventions - method-names should start with lowercase letters.
I'm trying to delete odd values in a linked list. My function is called removeOdds. What am I messing up? I am calling cur.next within that if statement. Shouldn't that do the trick?
Here is my code:
public class SLinkedList {
public void editAtIndex(int index, int newElement) {
if (index < 0 || index >= size) {
return;
} else {
Node cur = head;
while (index > 0) {
cur = cur.next;
index--;
}
cur.setElement(newElement);
}
}
public static void main(String[] args) {
Node test = new Node(5);
test.setElement(5);
SLinkedList myList = new SLinkedList();
//System.out.println(myList.contains(5));
myList.addFirst(5);
myList.addFirst(7);
myList.addFirst(9);
myList.addLast(27);
myList.addLast(3);
myList.addLast(453);
myList.addLast(32);
myList.addLast(83);
myList.addLast(43);
myList.addLast(10);
myList.removeOdds();
myList.printList();
//myList.printList();
}
private Node head, tail, nextNode;
public Node getNextNode() {
return nextNode;
}
public void setNextNode(Node nextNode) {
this.nextNode = nextNode;
}
private int size;
public SLinkedList() {
}
public int size() {
int value = 0;
Node temp = head;
while (temp != null) {
temp = temp.next;
value++;
}
return value;
}
public void addFirst(int element) {
head = new Node(element, head);
size++;
if (size == 1) {
tail = head;
}
}
public void addLast(int element) {
Node last = new Node(element);
if (size == 0) {
head = last;
tail = last;
} else {
tail.setNext(last);
tail = last;
}
size++;
}
public void removeFirst() {
if (size == 0) {
return;
}
head = head.getNext();
size--;
if (size == 0) {
tail = null;
}
}
public void removeLast() {
if (size <= 1) {
head = null;
tail = null;
size = 0;
} else {
Node cur = head;
while (cur.next != tail) {
cur = cur.next;
}
tail = cur;
size--;
tail.next = null;
}
}
public void removeOdds() {
if (size <= 1) {
return;
} else {
Node cur = head;
while (cur.next != tail) {
cur = cur.next;
if (cur.getElement() % 2 != 0) {
size--;
cur = cur.next;
}
}
}
}
public boolean contains(int key) {
Node cur = head;
while (cur != null && cur.getElement() != key) {
cur = cur.next;
}
if (cur == null) {
return false;
}
return true;
}
public int indexOf(int key) {
Node cur = head;
int index = 0;
while (cur != null) {
if (cur.getElement() == key) {
return index;
}
cur = cur.next;
index++;
}
return -1;
}
public void printList() {
System.out.println("A list of size " + size);
Node temp = head;
while (temp != null) {
System.out.print(temp.getElement() + " ");
temp = temp.next;
}
System.out.println();
}
public Node getHead() {
return head;
}
public void setHead(Node head) {
this.head = head;
}
public Node getTail() {
return tail;
}
public void setTail(Node tail) {
this.tail = tail;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
private static class Node {
private int element;
private Node next;
public Node(int element) {
this.element = element;
}
public Node(int element, Node next) {
this.element = element;
this.next = next;
}
public Node() {
element = 0;
}
public int getElement() {
return element;
}
public void setElement(int element) {
this.element = element;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
}
cur = cur.next; simply replaces the cur variable with the next node. That doesn't mean the earlier variable is deleted. The reference is still held.
You need to hold a reference to the node before the node you wish to delete.
public void removeOdds() {
if (size <= 1) {
return;
} else {
Node cur = head;
Node previous = cur;
while (cur.next != tail) {
cur = cur.next;
if (cur.getElement() % 2 != 0) {
size--;
previous.next = cur.next;
} else {
previous = previous.next;
}
}
}
}
This will ensure the nodes get deleted. I haven't checked the complete code, but it looks like right now you're not handling the head & tail nodes. They'll be skipped. You might want to handle those nodes too in the method.
I want to write implementation of Deque
I have written code below but unfortunately I have a problem with it
when I use addFirst and addLast or even removeFirst every thing is ok
but when I use removelast the programs throws NullPointerException
I dont know what is the problem exactly so I got really confused
Can Anyone plaese Help me??
Thanks in advance for your attention
Node Class::
public class Node<E>{
E element;
Node<E> prev , next;
public Node(E element, Node<E> prev, Node<E> next) {
this.element = element;
this.prev = prev;
this.next = next;
}
public Node() {
this(null, null, null);
}
public void setNext(Node next)
{
this.next = next;
}
public void setPrev(Node prev)
{
this.prev = prev;
}
public Node getNext()
{
return next;
}
public Node getPrev()
{
return prev;
}
}
here is Deque Interface::
public interface DQ<E> {
public int size();
public boolean isEmpty();
public E getFirst();
public E getLast();
public void addFirst (E element);
public void addLast (E element);
public E removeFirst();
public E removeLast();
}
and finally here is MyDQ Class which implements DQ class::
public class MyDQ<E> implements DQ<E>{
Node<E> head , tail;
int size = 0;
#Override
public int size() {
return size;
}
#Override
public boolean isEmpty() {
return size == 0;
}
#Override
public E getFirst() {
if(head == null)
return null;
return head.element;
}
#Override
public E getLast() {
if(head == null)
return null;
return tail.element;
}
#Override
public void addFirst(E element) {
Node<E> n = new Node<>(element, null, null);
if(head == null)
head = tail = n;
else
{
head.setPrev(n);
n.setNext(head);
head = n;
}
size++;
}
#Override
public void addLast(E element) {
Node<E> n = new Node<>(element, null, null);
if(head == null)
head = tail = n;
else
{
tail.setNext(n);
n.setPrev(head);
tail = n;
}
size++;
}
#Override
public E removeFirst() {
if(head == null)
return null;
Node<E> n = head;
head = head.getNext();
head.setPrev(null);
n.setNext(null);
size --;
return n.element;
}
#Override
public E removeLast() {
if(head == null)
return null;
Node<E> n = tail;
tail = tail.getPrev();
tail.setNext(null);
n.setPrev(null);
size --;
return n.element;
}
}
I created a simple Person object to use:
public class Person {
String name;
Integer age;
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
}
I tested this using the following unit test:
#Test
public void testOneElementDeque() {
MyDQ<Person> deq = new MyDQ<>();
Person p1 = new Person("John", 12);
Person p2 = new Person("Eric", 45);
deq.addLast(p1);
assertEquals(p1, deq.getLast());
assertEquals(p1, deq.getFirst());
deq.removeLast();
}
This throws a null pointer at this line(line 78):
tail.setNext(null);
By this point in the call tail has been set to null by this line:
tail = tail.getPrev();
To correct this I rewrote the implementaion to null check tail at this point:
public E removeLast() {
if(tail == null)
return null;
Node<E> n = tail;
tail = tail.getPrev();
if(tail != null)
tail.setNext(null);
n.setPrev(null);
size --;
return n.element;
}