whats wrong with my implementation of Tree in java - java

Im trying to implement a Tree that holds the list of the children of a given node. When I try output the size in my main method it returns 1. Can anyone see if theres anything wrong with my createNode method? And before anyone gets angry, I'm just including all of my code so that you can see what I'm trying to do :)
public class LinkedTree<E> implements Tree<E> {
protected TreePosition<E> root; // reference to the root
protected int size; // number of nodes
public LinkedTree() {
root = null; // start with an empty tree
size = 0;
}
/** Returns the number of nodes in the tree. */
public int size() {
return size;
}
/** Returns whether the tree is empty. */
public boolean isEmpty() {
return (size == 0);
}
/** Returns whether a node is internal. */
public boolean isInternal(Position<E> v) throws InvalidPositionException {
return !isExternal(v);
}
/** Returns whether a node is external. */
public boolean isExternal(Position<E> v) throws InvalidPositionException {
TreePosition<E> vv = checkPosition(v); // auxiliary method
return (vv.getChildren() == null) || vv.getChildren().isEmpty();
}
/** Returns whether a node is the root. */
public boolean isRoot(Position<E> v) throws InvalidPositionException {
checkPosition(v);
return (v == root());
}
/** Returns the root of the tree. */
public Position<E> root() throws EmptyTreeException {
if (root == null)
throw new EmptyTreeException("The tree is empty");
return root;
}
/** Returns the parent of a node. */
public Position<E> parent(Position<E> v) throws InvalidPositionException,
BoundaryViolationException {
TreePosition<E> vv = checkPosition(v);
Position<E> parentPos = vv.getParent();
if (parentPos == null)
throw new BoundaryViolationException("No parent");
return parentPos;
}
/** Returns an iterable collection of the children of a node. */
public Iterable<Position<E>> children(Position<E> v)
throws InvalidPositionException {
TreePosition<E> vv = checkPosition(v);
if (isExternal(v))
throw new InvalidPositionException(
"External nodes have no children");
return vv.getChildren();
}
/** Returns an iterable collection of the tree nodes. */
public Iterable<Position<E>> positions() {
PositionList<Position<E>> positions = new NodePositionList<Position<E>>();
if (size != 0)
preorderPositions(root(), positions); // assign positions in
// preorder
return positions;
}
/** Returns an iterator of the elements stored at the nodes */
public Iterator<E> iterator() {
Iterable<Position<E>> positions = positions();
PositionList<E> elements = new NodePositionList<E>();
for (Position<E> pos : positions)
elements.addLast(pos.element());
return elements.iterator(); // An iterator of elements
}
/** Replaces the element at a node. */
public E replace(Position<E> v, E o) throws InvalidPositionException {
TreePosition<E> vv = checkPosition(v);
E temp = v.element();
vv.setElement(o);
return temp;
}
/** Adds a root node to an empty tree */
public Position<E> addRoot(E e) throws NonEmptyTreeException {
if (!isEmpty())
throw new NonEmptyTreeException("Tree already has a root");
size = 1;
root = createNode(e, null, null);
return root;
}
/** Swap the elements at two nodes */
public void swapElements(Position<E> v, Position<E> w)
throws InvalidPositionException {
TreePosition<E> vv = checkPosition(v);
TreePosition<E> ww = checkPosition(w);
E temp = w.element();
ww.setElement(v.element());
vv.setElement(temp);
}
/** If v is a good tree node, cast to TreePosition, else throw exception */
protected TreePosition<E> checkPosition(Position<E> v)
throws InvalidPositionException {
if (v == null || !(v instanceof TreePosition))
throw new InvalidPositionException("The position is invalid");
return (TreePosition<E>) v;
}
/** Creates a new tree node */
protected TreePosition<E> createNode(E element, TreePosition<E> parent,
PositionList<Position<E>> children) {
return new TreeNode<E>(element, parent, children);
}
/**
* Creates a list storing the the nodes in the subtree of a node, ordered
* according to the preorder traversal of the subtree.
*/
protected void preorderPositions(Position<E> v,
PositionList<Position<E>> pos) throws InvalidPositionException {
pos.addLast(v);
for (Position<E> w : children(v))
preorderPositions(w, pos); // recurse on each child
}
public Iterator<E> iteratorO() {
return null;
}
public boolean islnternal(Position<E> v) throws InvalidPositionException {
return false;
}
public static void main(String[] args) {
LinkedTree<Character> T = new LinkedTree();
// add root
T.addRoot('A');
// add children of root
T.createNode('B', (TreeNode) (T.root()), new NodePositionList());
TreePosition C = T.createNode('C', (TreeNode) (T.root()),
new NodePositionList());
T.createNode('D', (TreeNode) (T.root()), new NodePositionList());
// add children of node C
T.createNode('E', C, new NodePositionList());
TreePosition F = T.createNode('F', C, new NodePositionList());
T.createNode('G', C, new NodePositionList());
// add childrn of Node F
T.createNode('H', F, new NodePositionList());
T.createNode('I', F, new NodePositionList());
// print out tree
System.out.println("Size = " + T.size());
}
}

Simple. The value of size is not set adequately. There are only two places where size is ever accessed for write.
Line 4: protected int size; // number of nodes
Line 8: size = 0;
Line 12: public int size() {
Line 13: return size;
Line 18: return (size == 0);
Line 69: if (size != 0)
Line 97: size = 1;
Line 173: System.out.println("Size = " + T.size());
And this is your size() method:
/** Returns the number of nodes in the tree. */
public int size() {
return size;
}
Main problem seems to be that size is essentially redundant. However, it prevents you from parsing the whole tree to determine the element count, so it can be considered a cache.
As you experienced right now, the general problem with caches and other redundant information is, that you need to carefully track them and keep them up to date. Placing some assert statements strategically can greatly help you with that task.

Related

Implementation of addFirst method in singly linked list in Java returns null?

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++;
}

Failing J-unit test for Shallow Copy on a Linked Stack

I am trying to implement a shallow copy for a Linked Stack, but I am failing the J-unit test provided by my instructor.
I have tried to implement a for loop that will cycle through the stack top to bottom and create a reference for each node to the new list on the pass through. I've added a print statement and the data references seem to match up,but my test are still failing.
public class LinkedStack<E> implements Stack<E>{
private int size = 0;
// Unlike the book, we'll use an inner class for our Node.
// Its two data members can be accessed directly by the Stack
// code, so we don't need setters and getters.
protected class Node{
E data;
Node next;
}
protected Node top; // not public, but can still be seen by other classes in the
// csci211 package.
/** Create an empty stack.
*
*/
public LinkedStack(){
top = null;
}
#Override // see interface for comments.
public void push(E e){
//TODO 75
Node temp = new Node();
temp.data = e;
temp.next = top;
top = temp;
}
#Override // see interface for comments.
public E pop(){
if (top==null) {
throw new NoSuchElementException("Cannout pop an Empty Stack.");
}
E topvar;
topvar = top.data;
top = top.next;
return topvar;
}
#Override // see interface for comments.
public E peek() {
if (top == null) {
throw new NoSuchElementException("Cannout peek an Empty Stack.");
}
//E topvar;
//topvar = top.data;
return top.data;
}
/** Retrieve the number of elements on this stack.
*
* #return an int containing the number of elements
*/
public int size() {
return this.size;
}
/** An Iterator for our LinkedStack.
*
* #author rhodes
*
*/
class LinkedStackIterator implements Iterator<E> {
LinkedStack<E>.Node next; // the book calls this "current"
public LinkedStackIterator(LinkedStack<E> s){
next = s.top;
}
#Override
public boolean hasNext() {
return top != null;
//TODO 100
//return false;
}
#Override
public E next() {
if (!hasNext()) throw new NoSuchElementException();
E data = top.data;
top = top.next;
return data;
//TODO 100
//return null;
}
}
#Override
public void add(E element) {
push(element);
}
#Override
public void clear() {
this.top = null;
this.size = 0;
}
#Override
public List<E> shallowCopy() {
LinkedStack<E> newstack = new LinkedStack<E>();
ArrayList<E> Alist = new ArrayList<E>();
//Iterate through while we haven't hit the end of the stack
Node newtest = top;
while (newtest != null) {
Alist.add(newtest.data);
newtest = newtest.next;
//TODO 85
}
for(int i = Alist.size()-1;i>=0;i--) {
newstack.push(Alist.get(i));
}
return newstack;
}
#Override
public Iterator<E> iterator() {
return new LinkedStackIterator(this);
}
}
This is the Junit tests that I am failing
#Test
#SuppressWarnings("deprecation") // for Date.setHours(), Date.getHours()
public void shallowCopy1() {
// let's use Date, since it's mutable.
LinkedStack<Date> s = new LinkedStack<Date>();
Date d = new Date();
d.setHours(17);
s.push(d);
LinkedStack<Date> s2 =(LinkedStack<Date>) s.shallowCopy();
Date d2=s2.pop();
// The shallow copy should contain references to the same objects
// as the original.
assertTrue(d == d2);
// So, we can change the Date in the original list using the Date that
// came from the shallow copy.
d2.setHours(14);
assertTrue(d.getHours() == 14);
// I don't usually put two asserts in one test, but this seems like
// an instructive example.
}
#Test(expected=NoSuchElementException.class)
public void shallowCopy2() {
LinkedStack<Integer> s1 = new LinkedStack<Integer>();
for(int i=0; i<10; i++) {
s1.push(i);
}
LinkedStack<Integer> s2 =(LinkedStack<Integer>) s1.shallowCopy();
s2.push(10); // supposed to only affect s2
s2.push(11); // supposed to only affect s2
for(int i=0; i<10; i++) {
s1.pop();
}
int last = s1.pop(); // should throw
}
#Test
public void shallowCopy3() {
LinkedStack<Integer> q1 = new LinkedStack<Integer>();
for(int i=0; i<10; i++) {
q1.push(i);
}
LinkedStack<Integer> q2 =(LinkedStack<Integer>) q1.shallowCopy();
//Let's check that the order of elements is correct in the copy.
for(int i=0; i<10; i++) {
int v1=q1.pop();
int v2=q2.pop();
assertEquals(v1, v2);
}
}
If anyone could point me in the right direction I would appreciate it. This is a Homework Problem.
Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure, not the elements. With a shallow copy, two collections now share the individual elements.
Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.
protected class Node{
E data;
Node next;
Node(Node node){
this.next = node.next;
this.data = node.data;
}
}
#Override
public List<E> shallowCopy() {
// LinkedStack<E> newStack = new LinkedStack<E>();
//Iterate through while we haven't hit the end of the stack
Node s = new Node(top);
while (top.next != null) {
s.next = new Node(top.next);
top = top.next;
s = s.next;
}
System.out.println("FINSHED!");
return (List<E>) s;
}
#Override
public List<E> shallowCopyWithoutUpdatingNodeClass() {
// LinkedStack<E> newStack = new LinkedStack<E>();
//Iterate through while we haven't hit the end of the stack
Node s = new Node(top);
while (top.next != null) {
s.next = new Node();
s.next.next = top.next;
s.next.data = top.data;
top = top.next;
s = s.next;
}
System.out.println("FINSHED!");
return (List<E>) s;
}
Answer Inspired by :- What is the difference between a deep copy and a shallow copy?
The original problem was the node data was just being overwritten not creating a new node. Then the stack was backwards. Finally I implement and array to reverse the stack.
#Override
public List<E> shallowCopy() {
LinkedStack<E> newstack = new LinkedStack<E>();
ArrayList<E> Alist = new ArrayList<E>();
//Iterate through while we haven't hit the end of the stack
Node newtest = top;
while (newtest != null) {
Alist.add(newtest.data);
newtest = newtest.next;
//TODO 85
}
for(int i = Alist.size()-1;i>=0;i--) {
newstack.push(Alist.get(i));
}
//System.out.println("FINSHED!");
return newstack;
}

MyLinkedList.java Project Issue

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);

Trying to get this linked list started

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!

BinaryTreeLUT , tree deletion

I have the following binary search tree as below, and am trying to delete a node using the method illustrated in this wiki
http://en.wikipedia.org/wiki/Binary_search_tree#Deletion
The main idea is to modify lrMerge (method in below code) when both subtrees are present. Then the node to be deleted is replaced by the rightmost node in the left tree (which itself is deleted). There is a test file at the end of the code below. I tried to change IrMerge to be like the wiki deletion code - but have not been succesful.
class KeyNotFoundInTableException extends Exception {
}
public class BinaryTreeLUT {
/**
* The member class Key is used for the indexing keys of the LUT. It
* is a String with basic comparative methods added.
*/
protected class Key {
public Key(String s) {
kString = s;
}
public boolean equals(Key k) {
return kString.equals(k.toString());
}
public boolean lessThan(Key k) {
return (kString.compareTo(k.toString()) < 0);
}
public boolean greaterThan(Key k) {
return (kString.compareTo(k.toString()) > 0);
}
public String toString() {
return kString;
}
private String kString;
}
/**
* The member class Entry encapsulates an entry of the LUT and contains
* a {key, value} pair.
*/
protected class Entry {
public Entry(Key k, Object v) {
key = k;
value = v;
}
protected Key key;
protected Object value;
}
/**
* The member class BSTreeNode encapsulates node of the binary search
* tree, which contains a LUT entry and links to left and right
* subtrees.
*/
protected class BSTreeNode {
public BSTreeNode(Entry e) {
kvPair = e;
left = null;
right = null;
}
public BSTreeNode(Entry e, BSTreeNode l, BSTreeNode r) {
kvPair = e;
left = l;
right = r;
}
protected Entry kvPair;
protected BSTreeNode left;
protected BSTreeNode right;
}
//Single protected data member - the LUT is stored in a sequence.
protected BSTreeNode root;
/**
* Default constructor - no need to specify capacity of LUT.
*/
public BinaryTreeLUT() {
root = null;
}
/**
* Inserts a new key-value pair into the look-up table.
*/
public void insert(String key, Object value) {
BSTreeNode newNode = new BSTreeNode(new Entry(new Key(key), value));
addToTree(newNode, root);
}
/**
* Removes the key-value pair with the specified key from the look-up
* table.
*/
public void remove(String key) throws KeyNotFoundInTableException {
Key searchKey = new Key(key);
removeFromTree(searchKey, root);
}
/**
* Retrieves the key-value pair with the specified key from the look-up
* table.
*/
public Object retrieve(String key) throws KeyNotFoundInTableException {
Key searchKey = new Key(key);
BSTreeNode treeNode = getFromTree(searchKey, root);
return treeNode.kvPair.value;
}
/**
* Updates the key-value pair with the specified key with the new
* specified value.
*/
public void update(String key, Object value) throws KeyNotFoundInTableException {
Key searchKey = new Key(key);
BSTreeNode treeNode = getFromTree(searchKey, root);
treeNode.kvPair.value = value;
}
/**
* Returns a string listing all the key-entry pairs in the LUT
*/
public String toString() {
return treeString(root);
}
//protected methods implementing recursive operations on the tree.
/**
* Adds newNode to the tree rooted at curNode recursively.
*/
protected void addToTree(BSTreeNode newNode, BSTreeNode curNode) {
//Special case for empty tree.
if(curNode == null) {
root = newNode;
}
//General case: recurse left or right depending on comparison.
else if(curNode.kvPair.key.lessThan(newNode.kvPair.key)) {
if(curNode.left == null) {
curNode.left = newNode;
}
else {
addToTree(newNode, curNode.left);
}
}
else {
if(curNode.right == null) {
curNode.right = newNode;
}
else {
addToTree(newNode, curNode.right);
}
}
}
/**
* Returns the node containing k from the tree rooted at node.
*/
protected BSTreeNode getFromTree(Key k, BSTreeNode node) throws KeyNotFoundInTableException {
if(node == null) {
throw new KeyNotFoundInTableException();
}
else if(node.kvPair.key.equals(k)) {
return node;
}
else if(node.kvPair.key.lessThan(k)) {
return getFromTree(k, node.left);
}
else {
return getFromTree(k, node.right);
}
}
/**
* Removes the node containing k from the tree rooted at node.
*/
protected void removeFromTree(Key k, BSTreeNode node) throws KeyNotFoundInTableException {
//Special case for empty tree.
if(node == null) {
throw new KeyNotFoundInTableException();
}
//Special case when deleting the root node.
else if(root.kvPair.key.equals(k)) {
root = lrMerge(root);
}
//If the key at the current node is less than
//the search key, go to the left subtree.
else if(node.kvPair.key.lessThan(k)) {
//If the left subtree is empty, the tree cannot contain
//the search key.
if(node.left == null) {
throw new KeyNotFoundInTableException();
}
//If this is the parent of the node to be removed, do
//the removal.
if(node.left.kvPair.key.equals(k)) {
node.left = lrMerge(node.left);
}
//Otherwise, recurse down another level.
else {
removeFromTree(k, node.left);
}
}
//Otherwise go to the right subtree.
else {
//If the right subtree is empty, the tree cannot contain
//the search key.
if(node.right == null) {
throw new KeyNotFoundInTableException();
}
//If this is the parent of the node to be removed, do
//the removal.
if(node.right.kvPair.key.equals(k)) {
node.right = lrMerge(node.right);
}
//Otherwise, recurse down another level.
else {
removeFromTree(k, node.right);
}
}
}
/**
* Merges the two subtrees of node prior to removal of
* the node from the tree.
*/
protected BSTreeNode lrMerge(BSTreeNode node) {
BSTreeNode mergedTrees = null;
//First two cases occur when one or both
//subtrees of the node to be deleted are empty.
if(node.left == null) {
mergedTrees = node.right;
}
else if(node.right == null) {
mergedTrees = node.left;
}
//Otherwise, merge the left and right subtrees
//and link the merged structure to the current
//node.
else {
addToTree(node.right, node.left);
mergedTrees = node.left;
}
return mergedTrees;
}
/**
* Uses in order tree traversal to construct a string containing all the
* key value pairs in the binary search tree.
*/
protected String treeString(BSTreeNode node) {
if(node == null) {
return "";
}
Entry lutEntry = node.kvPair;
String thisNode = "";
thisNode = lutEntry.key.toString();
thisNode += ":";
thisNode += lutEntry.value;
thisNode += ", ";
return treeString(node.left) + treeString(node.right) + thisNode;
}
}
The test file is here:
BinaryTreeLUTTest.java:
public class BinaryTreeLUTTest {
public static void main(String[] args) {
try {
BinaryTreeLUT myLUT = new BinaryTreeLUT();
myLUT.insert("Priscilla", new Integer(41));
myLUT.insert("Travis", new Integer(34));
myLUT.insert("Samuel", new Integer(28));
myLUT.insert("Helena", new Integer(39));
myLUT.insert("Andrew", new Integer(14));
myLUT.insert("Kay", new Integer(24));
myLUT.insert("John", new Integer(67));
System.out.println(myLUT);
myLUT.remove("Helena");
System.out.println(myLUT);
myLUT.remove("John");
System.out.println(myLUT);
myLUT.remove("Travis");
System.out.println(myLUT);
myLUT.remove("Samuel");
System.out.println(myLUT);
myLUT.remove("Andrew");
System.out.println(myLUT);
} catch (Exception e) {
System.out.println(e);
}
}
}

Categories