Second programming class
So we have been tasked with a linked list, building each method from scratch.
Well I started on this day before yesterday and had a null pointer exception, I figured id iron it out later and continued.
Well after cutting my program down to nothing to find the culprit im left with code that SHOULD work as its copied from our lab (that worked).
If you guys think you can figure out why im getting a null pointer exception on my add method id greatly appreciate it and see if im doing the second constructor correctly. If I can get SOME traction on this to get started it would go allot easier but as is I cant even begin.
You will notice allot of blank methods, ill get to them once I can get my constructor + add method working
My code:
import java.util.Collection;
import java.util.Iterator;
/**
* Created by hhhh on 11/2/2014.
*/
public class Lset<R> implements Set151Interface<R> {
private Node head;
private int length;
/**In the first (following) constructor im trying to re use code and call my clear method.
*Should save space and make code look cleaner.
*/
public Lset(){
clear();
}
public Lset(Collection<? extends R> list){
this();
for (R object : list) {
add(object);
}
}
/**
* Copied from Lab7, this add method checks to see if there are more nodes than just the head.
* After the check if false, creates a new node and adds it to the end of the list.
* #param entry
* #return
*/
#Override
public boolean add(R entry) {
Node newNode = new Node(entry);
// empty list is handled differently from a non-empty list
if (head.next == null) {
head = newNode;
} else {
Node lastNode = getNodeAt(length - 1);
lastNode.next = newNode;
}
length++;
return true;
}
#Override
public void clear() {
this.length = 0;
this.head = null;
}
#Override
public boolean contains(Object o) {
return false;
}
#Override
public Iterator<R> iterator() {
return null;
}
#Override
public boolean containsAll(Collection<?> c) {
return false;
}
#Override
public boolean isEmpty() {
return false;
}
#Override
public boolean remove(Object o) {
return false;
}
#Override
public boolean addAll(Collection<? extends R> c) {
return false;
}
#Override
public boolean removeAll(Collection<?> c) {
return false;
}
#Override
public boolean retainAll(Collection<?> c) {
return false;
}
#Override
public int size() {
return length;
}
#Override
public Object[] toArray() {
return null;
}
#Override
public <T> T[] toArray(T[] array) {
return null;
}
/**
* Code used in Lab 7, getNodeAt uses the length field and starts at head to traverse array and arrive at the
* position desired.
* #param position
* #return
*/
private Node getNodeAt(int position) {
assert !isEmpty() && (position >= 0) && position < length;
Node cNode = head;
for (int i = 0; i < position; i++)
cNode = cNode.next;
assert cNode != null;
return cNode;
}
public String toString(){
String arrayString = "<";
for(int i = 0; i < length; i++){
String two = getNodeAt(i).toString();
arrayString += two;
if(i <= (length - 2)){
two = ", ";
arrayString += two;
}
}
arrayString += ">";
return arrayString;
}
//TODO comment better
public class Node {
/** Reference to the data */
public R data;
/** Reference to the next node is in the list */
public Node next;
/**
* Sets the data for this node.
* #param data data to be carried by this node.
*/
public Node(R data) {
this.data = data;
this.next = null;
}
/**
* Sets the data for the node and assigns the next node in the list.
* #param data data to be carried by this node.
* #param nextNode next node in the list.
*/
public Node(R data, Node nextNode) {
this.data = data;
this.next = nextNode;
}
/**
* Returns just the data portion of the node.
* #return The data portion of the node.
*/
public R getData() {
return this.data;
}
/**
* Modified just the data portion of the node.
* #param data new data to be contained within the node.
*/
public void setData(R data) {
this.data = data;
}
/**
* What node does this node point to.
* #return the node that this node points to or null if it does not
* point anywhere.
*/
public Node getNextNode() {
return this.next;
}
/**
* Change the node that this node points to.
* #param nextNode a new node for this node to point to.
*/
public void setNextNode(Node nextNode) {
this.next = nextNode;
}
/**
* Display the state of just the data portion of the node.
*/
public String toString() {
return this.data.toString();
}
}
}
This is the method in main thats killing it
private void testConstruction() {
System.out.println("\nTesting Constructor");
System.out.print("----------------------------------------");
System.out.println("----------------------------------------");
Set151Interface s = makeSet();
//added
s.add("Butterfinger");
test(s.size() == 0,
"size() should return 0: " + s.size());
test(s.toString().equals("<>"),
"toString returns \"<>\": " + s.toString());
ArrayList<String> temp = new ArrayList<String>();
temp.add("Butterfinger");
temp.add("Milky Way");
temp.add("Kit Kat");
temp.add("Three Muskateers");
Set151Interface s3 = makeSet(temp);
test(s3.size() == 4,
"size should return 4: " + s3.size());
test(s3.toString().equals("<Butterfinger, Milky Way, Kit Kat, Three Muskateers>"),
"toString should return\n "+
"\"<Butterfinger, Milky Way, Kit Kat, Three Muskateers>\":\n "
+ s3.toString());
}
as soon as butterfinger attempts to get added I get null pointer exception pointing to this line
if (head.next == null) {
You just declared private Node head; and it doesnt takes any value assigned . so the compiler throws NPE
Thanks for the help guys, I figured it out :).
On day one I had edited my driver (and forgot) once I re copied the driver everything works (so far) thanks again guys!
Related
I am trying to implement addFirst to a singly linked list in Java. For some reason my implementation does not print out the linked list correctly. I prdict the problem is in either the addFirst, get, or toString methods. Any help would be greatly appreciated. Thanks in advance.
I predict that i am not creating the nodes correctly and I would appreciate an extra eye to spot what I am missing
import java.util.Iterator;
/**
* A basic singly linked list implementation.
*/
public class SinglyLinkedList<E> implements Cloneable, Iterable<E>, List<E> {
//---------------- nested Node class ----------------
/**
* Node of a singly linked list, which stores a reference to its
* element and to the subsequent node in the list (or null if this
* is the last node).
*/
private static class Node<E> {
E value;
Node<E> next;
public Node(E e)
{
e = value;
next = null;
}
}
//----------- end of nested Node class -----------
// instance variables of the SinglyLinkedList
private Node<E> head = null; // head node of the list (or null if empty)
private int size = 0; // number of nodes in the list
public SinglyLinkedList() {
} // constructs an initially empty list
// access methods
/**
* Returns the number of elements in the linked list.
*
* #return number of elements in the linked list
*/
public int size() {
return size;
}
/**
* Tests whether the linked list is empty.
*
* #return true if the linked list is empty, false otherwise
*/
public boolean isEmpty() {
return size == 0;
}
#Override
public E get(int i) throws IndexOutOfBoundsException {
if(i>this.size()) {
int count = 0;
Node<E> a = head;
while(count != i) {
count ++;
System.out.println(a.value);
a = a.next;
}
}
return null;
}
#Override
public E set(int i, E e) throws IndexOutOfBoundsException {
return null;
}
#Override
public void add(int i, E e) throws IndexOutOfBoundsException {
}
#Override
public E remove(int i) throws IndexOutOfBoundsException {
return null;
}
/**
* Returns (but does not remove) the first element of the list
*
* #return element at the front of the list (or null if empty)
*/
public E first() {
// TODO
return null;
}
/**
* Returns the last node of the list
*
* #return last node of the list (or null if empty)
*/
public Node<E> getLast() {
// TODO
return null;
}
/**
* Returns (but does not remove) the last element of the list.
*
* #return element at the end of the list (or null if empty)
*/
public E last() {
// TODO
return null;
}
// update methods
/**
* Adds an element to the front of the list.
*
* #param e the new element to add
*/
public void addFirst(E e) {
if(this.size() == 0) {
Node<E> first = new Node<E>(e);
this.size++;
this.head = first;
} else {
Node<E> first = new Node<E>(e);
first.next = this.head;
this.head = first;
this.size++;
}
}
/**
* Adds an element to the end of the list.
*
* #param e the new element to add
*/
public void addLast(E e) {
// TODO
}
/**
* Removes and returns the first element of the list.
*
* #return the removed element (or null if empty)
*/
public E removeFirst() {
// TODO
return null;
}
#SuppressWarnings({"unchecked"})
public boolean equals(Object o) {
// TODO
return false; // if we reach this, everything matched successfully
}
#SuppressWarnings({"unchecked"})
public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
// TODO
return null;
}
/**
* Produces a string representation of the contents of the list.
* This exists for debugging purposes only.
* #return
*/
public String toString() {
for(int i=0;i<this.size();i++) {
System.out.println(this.get(i));
}
return "end of Linked List";
}
private class SinglyLinkedListIterator<E> implements Iterator<E> {
#Override
public boolean hasNext() {
// TODO
return false;
}
#Override
public E next() {
// TODO
return null;
}
}
public Iterator<E> iterator() {
return new SinglyLinkedListIterator<E>();
}
public static void main(String[] args) {
//ArrayList<String> all;
//LinkedList<String> ll;
/*SinglyLinkedList<String> sll = new SinglyLinkedList<String>();
String[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
for (String s : alphabet) {
sll.addFirst(s);
sll.addLast(s);
}
System.out.println(sll.toString());
for (String s : sll) {
System.out.print(s + ", ");
}
*/
SinglyLinkedList <Integer> ll =new SinglyLinkedList <Integer>();
ll.addFirst(1);
ll.addFirst(3);
System.out.println(ll);
}
}
You have a bug in the constructor of the Node class:
public Node(E e)
{
e = value;
should be
public Node(E e)
{
value = e;
Also, assuming this is the method that you've added:
* Adds an element to the front of the list.
*
* #param e the new element to add
*/
public void addFirst(E e) {
if(this.size() == 0) {
Node<E> first = new Node<E>(e);
this.size++;
this.head = first;
} else {
Node<E> first = new Node<E>(e);
first.next = this.head;
this.head = first;
this.size++;
}
}
You don't really have to differentiate between the cases when the list is empty or otherwise.
You could:
Create a new node
Chain the current head to this newly created node
Set the head to the newly created node
Handle updates to other auxiliary variables, e.g. size in this case
* Adds an element to the front of the list.
*
* #param e the new element to add
*/
public void addFirst(E e) {
Node<E> first = new Node<>(e);
first.next = this.head;
this.head = first;
this.size++;
}
I'm so close to completing my project, but I am stuck on one part. I am trying to implement abstract methods from a file called AbstractLinkedList.java in my file MyLinkedList.java.
Here are the two project files:
AbstractLinkedList.java
/*
Models a doubly-linked list with dummy header and tail.
You should extend this class with your MyLinkedList to complete
the implementation.
*/
public abstract class AbstractLinkedList<E> {
protected final Node<E> myFront,
myBack; // dummy header/tail
protected int mySize; // # of elements in list
/* Constructs a new empty list. */
public AbstractLinkedList() {
myFront = new Node<E> (null);
myBack = new Node<E> (null);
myBack.setPrevious(myFront);
myFront.setNext(myBack);
mySize = 0;
}
/* Inserts the given element at the given index. */
public void add(int index, E element) {
checkIndex(index, size());
Node<E> curr = getNodeAt(index);
// create the new node to hold the new element
Node<E> newNode = new Node<E> (element, curr.getPrevious(), curr);
(newNode.getNext()).setPrevious(newNode);
(newNode.getPrevious()).setNext(newNode);
mySize++;
}
/* Appends the given element to the end of this list. Returns true. */
public void add(E element) {
add(size(), element);
}
/*
Removes the element of this list at the given index and returns it.
Throws IndexOutOfBoundsException if index is out of range.
*/
public void remove(int index) {
checkIndex(index, size() - 1);
// get the node to remove, and update the references
Node<E> nodeToRemove = getNodeAt(index);
(nodeToRemove.getPrevious()).setNext(nodeToRemove.getNext());
(nodeToRemove.getNext()).setPrevious(nodeToRemove.getPrevious());
mySize--;
}
/*
Sets the element of this list at the given index to have the given value.
Throws IndexOutOfBoundsException if index is out of range.
*/
public void set(int index, E value) {
checkIndex(index, size() - 1);
getNodeAt(index).element = value;
}
/* Returns the number of elements in this list. */
public int size() {
return mySize;
}
/* Returns true if this list contains no elements. */
public boolean isEmpty() {
return mySize == 0;
}
/* Removes all elements from this list. */
public void clear() {
myFront.setNext(myBack);
myBack.setPrevious(myFront);
mySize = 0;
}
/*
Helper method: Throws an IndexOutOfBoundsException
if 0 <= index <= max is not true.
*/
private void checkIndex(int index, int max) throws IndexOutOfBoundsException {
if (index < 0 || index > max) throw new IndexOutOfBoundsException();
}
/*
Removes the given element from this list, if it is present in the list.
Returns true if the element was in the list and was removed.
*/
public abstract boolean remove(E element);
/* Returns true if this list contains the given element. */
public abstract boolean contains(E element);
/*
Returns the element of this list at the given index.
Throws IndexOutOfBoundsException if index is out of range.
*/
public abstract E get(int index);
/*
Returns the first index where the given element occurs in this list,
or -1 if the element is not in this list.
*/
public abstract int indexOf(E element);
/*
Returns the last index where the given element occurs in this list,
or -1 if the element is not in this list.
*/
public abstract int lastIndexOf(E element);
/*
Helper method: returns the node at the given index.
-1 returns dummy header, and size() returns the dummy tail.
Consider the effiency of this method. How can you write it
minimize the number of comparisons?
*/
protected abstract Node < E > getNodeAt(int index) throws IndexOutOfBoundsException;
/*
Returns an array containing all of the elements in this list
in the correct order.
*/
public abstract E[] toArray();
/*
Returns a String representation of this list.
*/
public abstract String toString();
/* Represents one doubly-linked node in the list. */
protected class Node<E> {
private E element;
/* The data element */
private Node < E > next;
/* Reference to the next node in the list */
private Node<E> prev;
/* Reference to the previous node in the list */
/* Constructs a new node to store the given element, with no next node. */
public Node(E element) {
this(element, null, null);
}
/* Constructs a new node to store the given element and the given next node. */
public Node(E element, Node<E> prev, Node<E> next) {
this.element = element;
this.prev = prev;
this.next = next;
}
/* Accessor methods. */
public E getElement() {
return element;
}
public Node<E> getNext() {
return next;
}
public Node<E> getPrevious() {
return prev;
}
/* Mutator methods.*/
public void setElement(E el) {
element = el;
}
public void setNext(Node<E> newNext) {
next = newNext;
}
public void setPrevious(Node<E> newPrev) {
prev = newPrev;
}
/* Returns a string representation of this node. */
public String toString() {
return "(" + element + ")";
}
}
}
The file that I have written is MyLinkedList.java (found below).
public class MyLinkedList<Object> extends AbstractLinkedList<Object>{
private Node first, last;
private int mySize;
/** Create a default list */
public MyLinkedList() {
}
/** Inserts the given element at the given index. */
public void add(int index, Object element) {
checkIndex(index, size());
Node curr = getNodeAt(index);
// create the new node to hold the new element
Node newNode = new Node(element, curr.getPrevious(), curr);
(newNode.getNext()).setPrevious(newNode);
(newNode.getPrevious()).setNext(newNode);
mySize++;
}
/** Removes all elements from this list. */
public void clear() {
myFront.setNext(myBack);
myBack.setPrevious(myFront);
mySize = 0;
}
/** Appends the given element to the end of this list. Returns true. */
public void add(Object element) {
add(size(), element);
}
/**
Removes the element of this list at the given index and returns it.
Throws IndexOutOfBoundsException if index is out of range.
*/
public void remove(int index) {
checkIndex(index, size() - 1);
//get the node to remove, and update the references
Node nodeToRemove = getNodeAt(index);
(nodeToRemove.getPrevious()).setNext(nodeToRemove.getNext());
(nodeToRemove.getNext()).setPrevious(nodeToRemove.getPrevious());
mySize--;
}
/*
Sets the element of this list at the given index to have the given value.
Throws IndexOutOfBoundsException if index is out of range.
*/
public void set(int index, Object value) {
checkIndex(index, size() - 1);
getNodeAt(index).element = value;
}
/** Returns the number of elements in this list. */
public int size() {
return mySize;
}
/** Returns true if this list contains no elements. */
public boolean isEmpty() {
return mySize == 0;
}
/**
Helper method: Throws an IndexOutOfBoundsException
if 0 <= index <= max is not true.
*/
private void checkIndex(int index, int max) throws IndexOutOfBoundsException{
if (index < 0 || index > max)
throw new IndexOutOfBoundsException();
}
/** Override toString() to return elements in the list */
public String toString() {
StringBuffer result = new StringBuffer("[");
Node current = first;
for (int i = 0; i < mySize; 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();
}
/**
Helper method: returns the node at the given index.
-1 returns dummy header, and size() returns the dummy tail.
Consider the effiency of this method. How can you write it
minimize the number of comparisons?
*/
#Override
protected MyLinkedList<Object>.Node getNodeAt(int index) throws IndexOutOfBoundsException{
if (index == -1){
return first;
}
else if (index == mySize){
return last;
}
}
/** Return true if this list contains the element o */
public boolean contains(Object o) {
// Implementation left as an exercise
return true;
}
/** Return the element from this list at the specified index */
public Object get(int index) {
// Implementation left as an exercise
return null;
}
/** Returns the index of the first matching element in this list.
* Returns -1 if no match. */
public int indexOf(Object o) {
// Implementation left as an exercise
return 0;
}
/** Returns the index of the last matching element in this list
* Returns -1 if no match. */
public int lastIndexOf(Object o) {
// Implementation left as an exercise
return 0;
}
private class Node {
Object element;
Node next;
Node prev;
/** Constructs a new node to store the given element and the given next node. */
public Node(Object element, Node prev, Node next) {
this.element = element;
this.prev = prev;
this.next = next;
}
/** Accessor methods. */
public Object getElement(){
return element;
}
public Node getNext(){
return next;
}
public Node getPrevious(){
return prev;
}
/** Mutator methods.*/
public void setElement(Object obj){
element = obj;
}
public void setNext(Node newNext){
next = newNext;
}
public void setPrevious(Node newPrev){
prev = newPrev;
}
/** Returns a string representation of this node. */
public String toString() {
return "(" + element + ")";
}
}
#Override
public boolean remove(Object element) {
// TODO Auto-generated method stub
return false;
}
#Override
public Object[] toArray() {
return null;
}
}
The error that I keep getting is with the following line
#Override
protected MyLinkedList<Object>.Node getNodeAt(int index) throws IndexOutOfBoundsException{
if (index == -1){
return first;
}
else if (index == mySize){
return last;
}
}
Eclipse keeps telling me that "The return type is incompatible with AbstractLinkedList.getNodeAt(int)" and I am unable to overcome this obstacle.
Any and all help would be greatly appreciated.
You have a nested Node class in both of your classes.
The method in MyLinkedList is declared to return MyLinkedList.Node, but AbstractLinkedList requires the return type of AbstractLinkedList.Node.
Try changing
Node curr = getNodeAt(index);
to
Node<Object> curr = getNodeAt(index);
Java newbie question: I'm trying to implement a deque in Java and am having issues with the dequeueBack (remove an element from the rear of the queue) and enqueueFront (add an element to the front of the queue) methods. I've gotten the opposite methods to work (dequeueFront and enqueueBack), but I'm stumped at this point. Any suggestions?
public class Carr_A06Q4
{
/**
* Program entry point for deque testing.
* #param args Argument list.
*/
public static void main(String[] args)
{
LinkedDequeue<Integer> deque = new LinkedDequeue<Integer>();
System.out.println("DEQUE TESTING");
//per Q1
deque.enqueueBack(3);
deque.enqueueBack(7);
deque.enqueueBack(4);
deque.dequeueFront();
deque.enqueueBack(9);
deque.enqueueBack(8);
deque.dequeueFront();
System.out.println("The size of the deque is: " + deque.size());
System.out.println("The deque contains:\n" + deque.toString());
//new features
System.out.println(deque.dequeueFront());
deque.enqueueFront(1);
deque.enqueueFront(11);
deque.enqueueFront(3);
deque.enqueueFront(5);
System.out.println(deque.dequeueBack());
System.out.println(deque.dequeueBack());
System.out.println(deque.last());
deque.dequeueFront();
deque.dequeueFront();
System.out.println(deque.first());
System.out.println("The size of the deque is: " + deque.size());
System.out.println("The deque contains:\n" + deque.toString());
}
/**
* LinkedDeque represents a linked implementation of a deque.
*
*/
public static class LinkedDequeue<T> implements DequeADT<T>
{
private int count;
private LinearDoubleNode<T> head, tail; //front, back
/**
* Creates an empty queue.
*/
public LinkedDequeue()
{
count = 0;
head = tail = null;
}
/**
* Adds the specified element to the tail of this queue.
* #param element the element to be added to the tail of the queue
*/
public void enqueueBack(T element)
{
LinearDoubleNode<T> node = new LinearDoubleNode<T>(element);
if (isEmpty())
head = node;
else
tail.setNext(node);
tail = node;
count++;
}
/**
* Adds the specified element to the head of this queue.
* #param element the element to be added to the head of the queue
*/
public void enqueueFront(T element)
{
LinearDoubleNode<T> node = new LinearDoubleNode<T>(element);
count++ ;
if (head == null)
{
head = node;
}
else
{
node.setNext(head);
head = node;
}
}
/**
* Removes the element at the head of this queue and returns a
* reference to it.
* #return the element at the head of this queue
* #throws EmptyCollectionException if the queue is empty
*/
public T dequeueFront() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("queue");
T result = head.getElement();
head = head.getNext();
count--;
if (isEmpty())
head = null;
return result;
}
/**
* Removes the element at the tail of this queue and returns a
* reference to it.
* #return the element at the tail of this queue
* #throws EmptyCollectionException if the queue is empty
*/
public T dequeueBack() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("queue");
T result = tail.getElement();
tail = tail.getNext();
if (isEmpty())
head = null;
count --;
return result;
}
/**
* Returns a reference to the element at the head of this queue.
* The element is not removed from the queue.
* #return a reference to the first element in this queue
* #throws EmptyCollectionsException if the queue is empty
*/
public T first() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
T result = head.getElement();
return result;
}
/**
* Returns a reference to the element at the tail of this queue.
* The element is not removed from the queue.
* #return a reference to the first element in this queue
* #throws EmptyCollectionsException if the queue is empty
*/
public T last() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
T result = tail.getElement();
return result;
}
/**
* Returns true if this queue is empty and false otherwise.
* #return true if this queue is empty
*/
public boolean isEmpty()
{
if (head == null)
{
return true;
}
else
{
return false;
}
}
/**
* Returns the number of elements currently in this queue.
* #return the number of elements in the queue
*/
public int size()
{
return count;
}
/**
* Returns a string representation of this queue. The front element
* occurs first, and each element is separated by a space. If the
* queue is empty, returns "empty".
* #return the string representation of the queue
*/
public String toString()
{
StringBuilder sb = new StringBuilder();
LinearDoubleNode<T> tmp = head;
while (tmp != null)
{
sb.append(tmp.getElement()).append(" ");
tmp = tmp.getNext();
}
return sb.toString();
}
}
}
I need to get an output of:
DEQUE TESTING:
The size of the deque is: 3
The deque contains:
498
4
8
9
1
11
The size of the deque is: 2
The deque contains:
11 1
But instead I'm getting:
DEQUE TESTING:
The size of the deque is: 3
The deque contains:
498
4
8
and then I get a NullPointerException in the dequeueBack method.
Any help is appreciated!
Also, the interface is:
public interface DequeADT<T>
{
/**
* Adds one element to the front of this deque.
* #param element the element to be added to the front of the deque
*/
public void enqueueFront(T element); //deque specific
/**
* Adds one element to the back of this deque.
* #param element the element to be added to the back of the deque
*/
public void enqueueBack(T element);
/**
* Removes and returns the element at the front of this deque.
* Should throw an exception if the deque is empty.
* #return the element at the front of this deque
*/
public T dequeueFront();
/**
* Removes and returns the element at the back of this deque.
* Should throw an exception if the deque is empty.
* #return the element at the back of the deque.
*/
public T dequeueBack(); //deque specific
/**
* Returns, without removing, the element at the front of this deque.
* Should throw an exception if the deque is empty.
* #return the first element in the deque
*/
public T first();
/**
* Returns, without removing, the element at the back of this deque.
* Should throw an exception if the deque is empty.
* #return the last element in the deque
*/
public T last(); //deque specific
/**
* Returns true if this deque is empty and false otherwise.
* #return true if this deque is empty
*/
public boolean isEmpty();
/**
* Returns the number of elements in this deque.
* #return the number of elements in the deque
*/
public int size();
/**
* Returns a string representation of this deque. The front element
* occurs first, and each element is separated by a space. If the
* deque is empty, returns "empty".
* #return the string representation of the deque
*/
public String toString();
}
and a description of the node is:
public class LinearDoubleNode<T>
{
private LinearDoubleNode<T> next;
private T element;
/**
* Creates an empty node.
*/
public LinearDoubleNode()
{
next = null;
element = null;
}
/**
* Creates a node storing the specified element.
* #param elem element to be stored
*/
public LinearDoubleNode(T elem)
{
next = null;
element = elem;
}
/**
* Returns the node that follows this one.
* #return reference to next node
*/
public LinearDoubleNode<T> getNext()
{
return next;
}
/**
* Sets the node that follows this one.
* #param node node to follow this one
*/
public void setNext(LinearDoubleNode<T> node)
{
next = node;
}
/**
* Returns the element stored in this node.
* #return element stored at the node
*/
public T getElement()
{
return element;
}
/**
* Sets the element stored in this node.
* #param elem element to be stored at this node
*/
public void setElement(T elem)
{
element = elem;
}
}
The only way you can get that to perform, is for the internal list to be double-linked.
Otherwise you'll have to scan the entire list to find the second-last node, in order to remove the last node.
Double-ended queue ➔ Double-linked list
or dynamic array (see Implementations section).
public class LinkedDQueue implements DQueue {
private int size;
private LinearDoubleNode<T> head, tail; // front, back
private int capcity;
public LinkedDQueue() {
capcity = 10;
}
public LinkedDQueue(int capcity) {
this.capcity = capcity;
}
#Override
public boolean full() {
return size == capcity;
}
#Override
public void addFirst(T e) throws CapcityExceededException {
if (full())
throw new CapcityExceededException("size overflow");
LinearDoubleNode<T> node = new LinearDoubleNode<T>(e);
if (head == null) {
head = node;
tail = node;
} else {
node.setNext(head);
head = node;
}
size++;
}
#Override
public void addLast(T e) throws CapcityExceededException {
LinearDoubleNode<T> node = new LinearDoubleNode<T>(e);
if (full())
throw new CapcityExceededException("size overflow");
if (tail == null) {
head = tail = node;
} else {
tail.setNext(node);
node.setPrevious(tail);
}
tail = node;
size++;
}
#Override
public T removeFirst() {
if (isEmpty())
return null;
T result = head.getElement();
head.getNext().setPrevious(null);
head = head.getNext();
size--;
return result;
}
#Override
public T removeLast() {
LinearDoubleNode<T> temp = tail; // Save address of Node to delete
if (isEmpty()) {
return null;
}
if (head == tail) {
head = null;
tail = null;
size = 0;
return tail.getElement();
}
T result = tail.getElement();
tail = temp.getPrevious();
tail.setNext(null);
size--;
return result;
}
#Override
public T getFirst() {
if (isEmpty())
return null;
T result = head.getElement();
return result;
}
#Override
public T getLast() {
if (isEmpty())
return null;
T result = tail.getElement();
return result;
}
#Override
public int length() {
return size;
}
#Override
public void reverse() {
}
#Override
public boolean isEmpty() {
if (head == null) {
return true;
} else {
return false;
}
}
#Override
public int size() {
return size;
}
#Override
public String toString() {
LinearDoubleNode<T> temp = head; // Save address of Node to delete
StringBuilder builder = new StringBuilder();
while (temp != null) {
builder.append(temp.getElement() + "");
temp = temp.getNext();
}
return builder.toString();
}
class LinearDoubleNode<T> {
private LinearDoubleNode<T> next;
private LinearDoubleNode<T> previous;
private T element;
/**
* Creates an empty node.
*/
public LinearDoubleNode() {
next = null;
previous = null;
element = null;
}
/**
* Creates a node storing the specified element.
*
* #param elem
* element to be stored
*/
public LinearDoubleNode(T elem) {
next = null;
previous = null;
element = elem;
}
/**
* Returns the node that follows this one.
*
* #return reference to next node
*/
public LinearDoubleNode<T> getNext() {
return next;
}
public LinearDoubleNode<T> getPrevious() {
return previous;
}
public void setPrevious(LinearDoubleNode<T> previous) {
this.previous = previous;
}
/**
* Sets the node that follows this one.
*
* #param node
* node to follow this one
*/
public void setNext(LinearDoubleNode<T> node) {
next = node;
}
/**
* Returns the element stored in this node.
*
* #return element stored at the node
*/
public T getElement() {
return element;
}
/**
* Sets the element stored in this node.
*
* #param elem
* element to be stored at this node
*/
public void setElement(T elem) {
element = elem;
}
}
}
class CapcityExceededException extends Exception {
private String message;
public CapcityExceededException(String message) {
super(message);
this.message = message;
}
}
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The type Deque.
*
* #param <Item> the type parameter
*/
public class Deque<Item> implements Iterable<Item> {
/**
* The Head.
*/
private Node<Item> head;
/**
* The Tail.
*/
private Node<Item> tail;
/**
* The Deque size.
*/
private int dequeSize;
private class Node<Item> {
/**
* The Data.
*/
Item data;
/**
* The Next.
*/
Node<Item> next;
/**
* The Prev.
*/
Node<Item> prev;
/**
* Instantiates a new Node.
*
* #param data the data
*/
Node(Item data) {
this.data = data;
}
}
/**
* Instantiates a new Deque.
*/
public Deque() {
dequeSize = 0;
}
/**
* Is empty boolean.
*
* #return the boolean
*/
public boolean isEmpty() {
return dequeSize == 0;
}
/**
* Size int.
*
* #return the int
*/
public int size() {
return dequeSize;
}
/**
* Add first.
*
* #param item the item
*/
public void addFirst(Item item) {
if (item == null) {
throw new IllegalArgumentException();
}
Node<Item> newNode = new Node<Item>(item);
if (head == null) {
head = newNode;
tail = newNode;
} else {
head.prev = newNode;
newNode.next = head;
head = newNode;
}
dequeSize++;
}
/**
* Add last.
*
* #param item the item
*/
public void addLast(Item item) {
if (item == null) {
throw new IllegalArgumentException();
}
Node<Item> newNode = new Node<Item>(item);
if (head == null) {
head = newNode;
tail = newNode;
} else {
tail.next = newNode;
newNode.prev = tail;
tail = newNode;
}
dequeSize++;
}
/**
* Remove first item.
*
* #return the item
*/
public Item removeFirst() {
if (isEmpty()) {
throw new NoSuchElementException();
}
Item headData = head.data;
if (dequeSize == 1) {
head = null;
tail = null;
} else {
Node<Item> headNext = head.next;
headNext.prev = null;
head = headNext;
}
dequeSize--;
return headData;
}
/**
* Remove last item.
*
* #return the item
*/
public Item removeLast() {
if (isEmpty()) {
throw new NoSuchElementException();
}
Item tailData = tail.data;
if (dequeSize == 1) {
head = null;
tail = null;
} else {
Node<Item> tailPrev = tail.prev;
tailPrev.next = null;
tail = tailPrev;
}
dequeSize--;
return tailData;
}
/**
* Iterator iterator.
*
* #return the iterator
*/
public Iterator<Item> iterator() {
return new CustomIterator();
}
private class CustomIterator implements Iterator<Item> {
private Node<Item> temp;
/**
* Instantiates a new Custom iterator.
*/
CustomIterator() {
temp = head;
}
public boolean hasNext() {
return temp.next != null;
}
public Item next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Item tempData = temp.data;
temp = temp.next;
return tempData;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* The entry point of application.
*
* #param args the input arguments
*/
public static void main(String[] args) {
// unit testing (required)
}
}
Does anything need to go into the main method or the constructor method for a linkedlist class like this? Also, I think my program is working fine, but I think I might be using more lines of code that I have to for my purposes, which are just to sort a list of strings. Are there any redundancies or logical errors in the add/remove methods and the OrderedListNode class below? Should I make all variables private in the LinkedList class?
package orderedlinkedlist;
/**
* Class OrderedLinkedList.
*
* This class functions as a linked list, but ensures items are stored in ascending order.
*/
public class OrderedLinkedList
{
public static void main(String args[]){
}
/** return value for unsuccessful searches */
private static final OrderedLinkedList NOT_FOUND = null;
/** current number of items in list */
public int theSize; //was private
/** reference to list header node */
private OrderedListNode head;
/** reference to list tail node */
private OrderedListNode tail;
/** current number of modifications to list */
public int modCount;
/**
* Create an instance of OrderedLinkedList.
*
*/
public OrderedLinkedList()
{
clear();
}
public boolean add(String obj) //is it ok that you changed from comparable to string?
{
OrderedListNode newNode = new OrderedListNode(obj); // placed at end of list
if(this.isEmpty()){ //
head.setNextNode(newNode);
newNode.setNextNode(tail);
newNode.setPreviousNode(head);
tail.setPreviousNode(newNode);
} else if(obj == null) {
head.getNext().setPreviousNode(newNode);
newNode.setNextNode(head.getNext());
head.setNextNode(newNode);
newNode.setPreviousNode(head);
} else {
int compareToNode;
for(OrderedListNode node = head.getNext(); node != tail; node = node.getNext()){
compareToNode = obj.compareToIgnoreCase((node.getData() == null)? "": node.getData().toString());
if(compareToNode < 0){
OrderedListNode nodeBefore = node.getPrevious();
OrderedListNode nodeAfter = node;
nodeBefore.setNextNode(newNode);
nodeAfter.setPreviousNode(newNode);
newNode.setNextNode(nodeAfter);
newNode.setPreviousNode(nodeBefore);
break;
} else if(node.getNext() == tail) {
OrderedListNode nodeBefore = node;
OrderedListNode nodeAfter = node.getNext();
nodeBefore.setNextNode(newNode);
nodeAfter.setPreviousNode(newNode);
newNode.setNextNode(nodeAfter);
newNode.setPreviousNode(nodeBefore);
break;
}
}
}
theSize++;
modCount++;
return true;
}
public boolean remove(String obj) //removes first string obj instance it finds?
{
// TODO: implement this method (7 points)
for(OrderedListNode node = head.getNext();node != tail; node=node.getNext()){
if(node.getData() == obj){
OrderedListNode nodeBefore = node.getPrevious();
OrderedListNode nodeAfter = node.getNext();
nodeBefore.setNextNode(nodeAfter);
nodeAfter.setPreviousNode(nodeBefore);
node = null;
theSize--;
modCount++;
return true;
}
}
return false;
}
public void clear()
{
// reset header node
head = new OrderedListNode("HEAD", null, null);
// reset tail node
tail = new OrderedListNode("TAIL", head, null);
// header references tail in an empty LinkedList
head.next = tail;
// reset size to 0
theSize = 0;
// emptying list counts as a modification
modCount++;
}
public boolean isEmpty()
{
return theSize == 0;
}
public int size()
{
return theSize;
}
public String toString()
{
String s = "";
OrderedListNode currentNode = head.next;
while (currentNode != tail)
{
s += currentNode.getData(); //getData was "theItem.toString()"
if (currentNode.next != tail)
{
s += ", ";
}
currentNode = currentNode.next;
}
return s;
}
/**************************************************************************
* Inner Classes
*************************************************************************/
/**
* Nested class OrderedListNode.
*
* Encapsulates the fundamental building block of an OrderedLinkedList
* contains a data item, and references to both the next and previous nodes
* in the list
*/
public class OrderedListNode {
private Comparable data;
private OrderedListNode next;
private OrderedListNode previous;
public OrderedListNode() {
this.data = null;
this.next = null;
}
public OrderedListNode(Comparable inputData) { //check this
this.data = inputData;
}
public OrderedListNode(Comparable inputData, OrderedListNode previous, OrderedListNode next) {
this.data = inputData;
this.previous = previous;
this.next = next;
}
public Comparable getData() {
return data;
}
public void setData(Comparable data) {
this.data = data;
}
public OrderedListNode getNext() {
return next;
}
public void setNextNode(OrderedListNode next) {
this.next = next;
}
public OrderedListNode setPreviousNode(OrderedListNode previous) {
this.previous = previous;
return previous;
}
private OrderedListNode getPrevious() {
return getNodeAt(indexOf(this)>=0 ? indexOf(this): theSize);//0
}
private OrderedListNode getNodeAt(int givenPosition){
OrderedListNode currentNode = head;
for(int counter = 0; counter < givenPosition; counter++){
currentNode = currentNode.getNext();
}
return currentNode;
}
private int indexOf(OrderedListNode givenNode){
int count = 0;
for(OrderedListNode node = head.getNext();node != tail; node=node.getNext(), count++){
if(givenNode == node)
return count;
}
return -1;
}
}
}
package orderedlinkedlist;
public class testClass {
public static void main(String args[]){
OrderedLinkedList list = new OrderedLinkedList();
list.add("tesla");
list.add(null);
list.add("walnuts"); //move these to main method
list.add("chocolate");
list.add("swordfish");
list.add(null);
list.remove("chocolate");
list.add("pizza");
list.add("apple");
list.add(null);
list.add("1");
list.add("zebra");
System.out.println(list.toString());
System.out.println("Items in this list: " + list.theSize);
System.out.println("Modifications made: " + list.modCount);
}
}
A general purpose utility class designed should not have a main method, since someone else is expected to use this class.
An example would be the test class you have that uses your code and has a main method.
As far as you code goes,
I don't think it is thread safe. That might not be a problem, but in general it is recommended that you document that the code is not thread safe
Does you code compile? The statement should have given a compilation issue since the + operator is not overloaded for Comparable
s += currentNode.getData(); //getData was "theItem.toString()"
You might want to avoid the use of + operator in your toString method and instead go for the more efficient StringBuilder
theSize and modCount should not be public.
Following Java convention, you should add a constructor taking another Collection as an arg, e.g.
public OrderedLinkedList(Collection in)
that copies from that Collection.
What's the best way to implement a stack using linked lists in Java?
EDIT: I would define best as most efficient using clean code. I have already used an array to implement a stack, but am not familiar with link lists so was wondering if anyone could help me implement something similar to below:
public class StackArray{
private Object [] objArray;
private int stackSize;
public StackArray(){
objArray = new Object[50];
stackSize = 0;
}
public StackArray(int size){
objArray = new Object[size];
stackSize = 0;
}
//public interface methods - push, pop, top, empty & clear
public void push(Object o)throws StackArrayException{
if(stackSize < objArray.length){
objArray[stackSize] = o;
stackSize ++;
}else{
throw new StackArrayException("Stack Overflow");
}
}
public Object pop()throws StackArrayException{
if(stackSize != 0){
stackSize--;
return(objArray[stackSize]);
}else{
throw new StackArrayException("Stack Underflow");
}
}
public void top() throws StackArrayException{
if(stackSize != 0){
return(objArray[stackSize-1]);
}else{
throw new StackArrayException("Stack Underflow");
}
}
public boolean empty(){
return (stackSize == 0):
}
public void clear(){
stackSize = 0;
}
}
EDIT: Here is the linked list implementation if anyone is interested..
public class StackList{
private Node listHead;
protected class Node{
protected Object datum;
protected Node next;
public Node(Object o, Node n){
datum = o;
next = n;
}
public StackList(){
listHead = null;
}
//public interface methods - push pop top empty clear
public void push(Object o){
listHead = new Node(o, listHead);
}
public Object pop() throws StackListException{
if(listHead!=null){
Object top = listHead.datum;
listHead = listHead.next;
return top;
}else{
throw new StackListException("Stack Underflow");
}
}
public Object top()throws StackListException{
if(listHead != null){
return(listHead.datum);
}else{
throw new StackListException("Stack Underflow");
}
}
public boolean empty(){
return (listHead == null);
}
public void clear(){
listHead = null;
}
}
Assuming you genuinely want to do this from scratch rather than using one of the perfectly good existing stack implementations then I would recommend:
Create a "MyStack< T >" class which implements any interfaces you want (perhaps List < T >?)
Within MyStack create a "private static final class Node< T >" inner class for each linked list item. Each node contains a reference to an object of type T and a reference to a "next" Node.
Add a "topOfStack" Node reference to MyStack.
The push and pop operations just need to operate on this topOfStack Node. If it is null, the Stack is empty. I'd suggest using the same method signatures and semantics as the standard Java stack, to avoid later confusion.....
Finally implement any other methods you need. For bonus points, implement "Iterable< T >" in such a way that it remembers the immutable state of the stack at the moment the iterator is created without any extra storage allocations (this is possible :-) )
Why don't you just use the Stack implementation already there?
Or better (because it really a linked list, its fast, and its thread safe): LinkedBlockingDeque
If you're talking about a single linked list (a node has a reference to the next object, but not the previous one), then the class would look something like this :
public class LinkedListStack {
private LinkedListNode first = null;
private LinkedListNode last = null;
private int length = 0;
public LinkedListStack() {}
public LinkedListStack(LinkedListNode firstAndOnlyNode) {
this.first = firstAndOnlyNode;
this.last = firstAndOnlyNode;
this.length++;
}
public int getLength() {
return this.length;
}
public void addFirst(LinkedListNode aNode) {
aNode.setNext(this.first);
this.first = aNode;
}
}
public class LinkedListNode {
private Object content = null;
private LinkedListNote next = null;
public LinkedListNode(Object content) {
this.content = content;
}
public void setNext(LinkedListNode next) {
this.next = next;
}
public LinkedListNode getNext() {
return this.next;
}
public void setContent(Object content) {
this.content = content;
}
public Object getContent() {
return this.content;
}
}
Of course you will need to code the rest of the methods for it to work properly and effectively, but you've got the basics.
Hope this helps!
For implementing stack using using LinkedList- This StackLinkedList class internally maintains LinkedList reference.
StackLinkedList‘s push method internally calls linkedList’s insertFirst() method
public void push(int value){
linkedList.insertFirst(value);
}
StackLinkedList’s method internally calls linkedList’s deleteFirst() method
public void pop() throws StackEmptyException {
try{
linkedList.deleteFirst();
}catch(LinkedListEmptyException llee){
throw new StackEmptyException();
}
}
Full Program
/**
*Exception to indicate that LinkedList is empty.
*/
class LinkedListEmptyException extends RuntimeException{
public LinkedListEmptyException(){
super();
}
public LinkedListEmptyException(String message){
super(message);
}
}
/**
*Exception to indicate that Stack is empty.
*/
class StackEmptyException extends RuntimeException {
public StackEmptyException(){
super();
}
public StackEmptyException(String message){
super(message);
}
}
/**
*Node class, which holds data and contains next which points to next Node.
*/
class Node {
public int data; // data in Node.
public Node next; // points to next Node in list.
/**
* Constructor
*/
public Node(int data){
this.data = data;
}
/**
* Display Node's data
*/
public void displayNode() {
System.out.print( data + " ");
}
}
/**
* LinkedList class
*/
class LinkedList {
private Node first; // ref to first link on list
/**
* LinkedList constructor
*/
public LinkedList(){
first = null;
}
/**
* Insert New Node at first position
*/
public void insertFirst(int data) {
Node newNode = new Node(data); //Creation of New Node.
newNode.next = first; //newLink ---> old first
first = newNode; //first ---> newNode
}
/**
* Deletes first Node
*/
public Node deleteFirst()
{
if(first==null){ //means LinkedList in empty, throw exception.
throw new LinkedListEmptyException("LinkedList doesn't contain any Nodes.");
}
Node tempNode = first; // save reference to first Node in tempNode- so that we could return saved reference.
first = first.next; // delete first Node (make first point to second node)
return tempNode; // return tempNode (i.e. deleted Node)
}
/**
* Display LinkedList
*/
public void displayLinkedList() {
Node tempDisplay = first; // start at the beginning of linkedList
while (tempDisplay != null){ // Executes until we don't find end of list.
tempDisplay.displayNode();
tempDisplay = tempDisplay.next; // move to next Node
}
System.out.println();
}
}
/**
* For implementing stack using using LinkedList- This StackLinkedList class internally maintains LinkedList reference.
*/
class StackLinkedList{
LinkedList linkedList = new LinkedList(); // creation of Linked List
/**
* Push items in stack, it will put items on top of Stack.
*/
public void push(int value){
linkedList.insertFirst(value);
}
/**
* Pop items in stack, it will remove items from top of Stack.
*/
public void pop() throws StackEmptyException {
try{
linkedList.deleteFirst();
}catch(LinkedListEmptyException llee){
throw new StackEmptyException();
}
}
/**
* Display stack.
*/
public void displayStack() {
System.out.print("Displaying Stack > Top to Bottom : ");
linkedList.displayLinkedList();
}
}
/**
* Main class - To test LinkedList.
*/
public class StackLinkedListApp {
public static void main(String[] args) {
StackLinkedList stackLinkedList=new StackLinkedList();
stackLinkedList.push(39); //push node.
stackLinkedList.push(71); //push node.
stackLinkedList.push(11); //push node.
stackLinkedList.push(76); //push node.
stackLinkedList.displayStack(); // display LinkedList
stackLinkedList.pop(); //pop Node
stackLinkedList.pop(); //pop Node
stackLinkedList.displayStack(); //Again display LinkedList
}
}
OUTPUT
Displaying Stack > Top to Bottom : 76 11 71 39
Displaying Stack > Top to Bottom : 71 39
Courtesy : http://www.javamadesoeasy.com/2015/02/implement-stack-using-linked-list.html
Use the STL adapter std::stack. Why? Because the code you don't have to write is the fastest way to completion of your task. stack is well-tested, and likely to not need any attention from you. Why not? Because there are some special-purpose requirements needed by your code, undocumented here.
By default stack uses a deque double-ended queue, but it merely requires the underlying container to support "Back Insertion Sequence", also known as .push_back.
typedef std::stack< myType, std::list<myType> > myStackOfTypes;
Here is a tutorial implement using an array and linked list stack implementation.
It depends on the situation.
Array :- you can not resize it (fix size)
LinkedList :- it takes more memory than the array-based one because it wants to keep next node in memory.
I saw many stack implementation using LinkedList, At the end I understand what stack is.. and implemented stack by myself(for me it's clean and efficient). I hope you welcome new implementations. Here the code follows.
class Node
{
int data;
Node top;
public Node()
{
}
private Node(int data, Node top)
{
this.data = data;
this.top = top;
}
public boolean isEmpty()
{
return (top == null);
}
public boolean push(int data)
{
top = new Node(data, top);
return true;
}
public int pop()
{
if (top == null)
{
System.out.print("Stack underflow<-->");
return -1;
}
int e = top.data;
top = top.top;
return e;
}
}
And here the main class for it.
public class StackLinkedList
{
public static void main(String[] args)
{
Node stack = new Node();
System.out.println(stack.isEmpty());
stack.push(10);
stack.push(20);
stack.push(30);
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.isEmpty());
System.out.println(stack.pop());
System.out.println(stack.isEmpty());
System.out.println(stack.pop());
}
}