Print Expression Tree - java

I am trying to print out an expression tree diagram for an infix expression. I already have methods that does the conversion of the infix expressions to post and prefix and returns them as strings. What I expect the output to be for the expression "1 + 3 - 6 ^ 7 * 5" is the following
-
+ *
1 3 ^ 5
6 7
Preorder, Postorder and inorder traversal print does not seem to give me the right result. It traverses the tree / print the contents of the tree but does not distinguish between operators and operands. Is there a way to edit these traversals to print out the expression tree the right way (i.e, with spacing like the example above), or do I need to make a new traversal/print statement function that finds the root node (in this case the "-") and then sets the operators as roots and the operands as leaf nodes. How do I let the function know what operator in the expression is the root operator (ex, the "-" in the example above) and treat the rest as roots for sub trees?
import java.util.Iterator;
import java.util.Stack;
/**
* Binary Tree.
*/
public class DDBinaryTree<E>{
protected Node<E> root;
/**
* Constructs an empty binary tree.
*/
public DDBinaryTree() {
}
/**
* Constructs a binary tree with given data in the root and the specified left and right
* subtrees.
*
* #param data The data to store in root.
* #param leftTree The left subtree.
* #param rightTree The right subtree.
*/
public DDBinaryTree(E data, DDBinaryTree<E> leftTree, DDBinaryTree<E> rightTree) {
root = new Node<E>(data);
if (leftTree!=null) {
root.left = leftTree.root;
}
if (rightTree!=null) {
root.right = rightTree.root;
}
}
/**
* Constructs a binary tree with a given node as its root.
* #param root The root of the binary tree.
*/
protected DDBinaryTree(Node<E> root) {
this.root = root;
}
/**
* Gets the left subtree of this tree.
* #return The left subtree, or null if it doesn't exist.
*/
public DDBinaryTree<E> getLeftSubtree() {
if (root!=null && root.left!=null) return new DDBinaryTree<E>(root.left);
else return null;
}
/**
* Gets the right subtree of this tree.
* #return The right subtree, or null if it doesn't exist.
*/
public DDBinaryTree<E> getRightSubtree() {
if (root!=null && root.right!=null) return new DDBinaryTree<E>(root.right);
else return null;
}
/**
* Gets the data from the root node.
* #return The data from the root, or null if tree is empty.
*/
public E getData() {
if (root!=null) return root.data;
else return null;
}
/**
* Checks if tree is empty
* #return true if root is null, and false otherwise
*/
public boolean isEmpty() {
return root == null;
}
/**
* Checks if tree is a leaf.
* #return true if this tree is a leaf, and false otherwise.
*/
public boolean isLeaf() {
return root != null && root.left == null && root.right == null;
}
/**
* Performs a preorder traversal, executing the specified operation
* on the data in each node it visits.
*
* #param visitOperation An operation to apply to the data of each visited node.
*/
protected void preOrderTraversal(ProcessData<E> visitOperation) {
preOrderTraversal(root, visitOperation);
}
private void preOrderTraversal(Node<E> node, ProcessData<E> visitOperation) {
if (node==null) return;
visitOperation.process(node.data);
preOrderTraversal(node.left, visitOperation);
preOrderTraversal(node.right, visitOperation);
}
/**
* Performs a postorder traversal, executing the specified operation
* on the data in each node it visits.
*
* #param visitOperation An operation to apply to the data of each visited node.
*/
protected void postOrderTraversal(ProcessData<E> visitOperation) {
postOrderTraversal(root, visitOperation);
}
private void postOrderTraversal(Node<E> node, ProcessData<E> visitOperation) {
if (node==null) return;
postOrderTraversal(node.left, visitOperation);
postOrderTraversal(node.right, visitOperation);
visitOperation.process(node.data);
}
/**
* Performs a inorder traversal, executing the specified operation
* on the data in each node it visits.
*
* #param visitOperation An operation to apply to the data of each visited node.
*/
protected void inOrderTraversal(ProcessData<E> visitOperation) {
inOrderTraversal(root, visitOperation);
}
private void inOrderTraversal(Node<E> node, ProcessData<E> visitOperation) {
if (node==null) return;
if (node.left != null && visitOperation instanceof PrePostProcess){
((PrePostProcess<E>)visitOperation).pre();
}
inOrderTraversal(node.left, visitOperation);
visitOperation.process(node.data);
inOrderTraversal(node.right, visitOperation);
if (node.right != null && visitOperation instanceof PrePostProcess){
((PrePostProcess<E>)visitOperation).post();
}
}
protected interface ProcessData<E> {
void process(E data);
}
protected interface PrePostProcess<E> extends ProcessData<E> {
void pre();
void post();
}
protected static class Node<E> {
protected E data;
protected Node<E> left;
protected Node<E> right;
/**
* Constructs a Node containing the given data.
* #param data Data to store in node
*/
public Node(E data) {
this.data = data;
}
#Override
public String toString() {
return data.toString();
}
}
}
import java.util.Iterator;
import java.util.Stack;
/**
* Binary Search Tree
*/
public class DDBinarySearchTree<E extends Comparable<E>> extends DDBinaryTree implements Iterable<E> {
static final int COUNT = 5;
/**
* Searches tree for target.
*
* #param target The element to look for.
* #return true if in tree, and false otherwise
*/
public boolean contains(E target) {
return contains(root, target);
}
/**
* Adds target to tree if it doesn't already exist.
*
* #param target The element to add.
* #return true if target added and false otherwise.
*/
public boolean add(E target) {
if (root == null) {
root = new Node<E>(target);
return true;
}
return add(root, target);
}
/**
* Output contents in order.
*/
public void printOrderedData() {
inOrderTraversal(new ProcessData<E>() {
#Override
public void process(E data) {
System.out.print(data + " ");
}
});
}
private boolean contains(Node<E> subtreeRoot, E target) {
if (subtreeRoot == null) return false;
if (target.compareTo(subtreeRoot.data) == 0) return true;
else if (target.compareTo(subtreeRoot.data) < 0)
return contains(subtreeRoot.left, target);
else
return contains(subtreeRoot.right, target);
}
private boolean add(Node<E> subtreeRoot, E target) {
if (target.compareTo(subtreeRoot.data) == 0) return false;
else if (target.compareTo(subtreeRoot.data) < 0) {
if (subtreeRoot.left == null) {
subtreeRoot.left = new Node<E>(target);
return true;
}
return add(subtreeRoot.left, target);
} else {
if (subtreeRoot.right == null) {
subtreeRoot.right = new Node<E>(target);
return true;
}
return add(subtreeRoot.right, target);
}
}
}
public class Tester {
public static void main(String[] args) {
DDBinarySearchTree<Integer> integerSearchTree = new DDBinarySearchTree<>();
DDBinarySearchTree<String> stringSearchTree = new DDBinarySearchTree<>();
String stringToSplit = "1 + 3 - 6 ^ 7 * 5";
//Splits up string and adds to stringSearchTree
for (String str : stringToSplit.split(" ")) {
stringSearchTree.add(str);
}
stringSearchTree.printOrderedData();
}
}
In the printOrderedData method, you can change the traversal type from inorder to pre/postorder by typing in their methods

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

Java Deque Implementation

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

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

Implementing Binary Search Tree Insert operation in Java

I have a TreeNode class that represents node of the binary tree.
public class TreeNode {
private static Object key=null;
private static Object value=null;
private TreeNode parent;
private TreeNode left=null;
private TreeNode right=null;
/**
* #return the value
*/
public static Object getValue() {
return value;
}
/**
* #param aValue the value to set
*/
public static void setValue(Object aValue) {
value = aValue;
}
public TreeNode()
{
this(key,value);
}
public TreeNode(Object key,Object value)
{
this.key = key;
this.value = value;
}
/**
* #return the key
*/
public Object getKey() {
return key;
}
/**
* #param key the key to set
*/
public void setKey(Object key) {
this.key = key;
}
/**
* #return the parent
*/
public TreeNode getParent() {
return parent;
}
/**
* #param parent the parent to set
*/
public void setParent(TreeNode parent) {
this.parent = parent;
}
/**
* #return the left
*/
public TreeNode getLeftChild() {
return left;
}
/**
* #param left the left to set
*/
public void setLeftChild(TreeNode left) {
this.left = left;
}
/**
* #return the right
*/
public TreeNode getRightChild() {
return right;
}
/**
* #param right the right to set
*/
public void setRightChild(TreeNode right) {
this.right = right;
}
}
I have a BinarySearchTree class
public class BinarySearchTree implements DataStructures.interfaces.BinarySearchTree {
private int size=0;
private TreeNode root = new TreeNode();
#Override
public void insert(Object key, Object value)
{
insertOperation(key,value,root);
}
private void insertOperation(Object element, Object value, TreeNode node)
{
if(node.getKey() == null) {
node.setKey(element);
node.setValue(value);
}
else
{
if((int) node.getKey() > (int) element)
{
if(node.getLeftChild() != null)
insertOperation(element,value,node.getLeftChild());
else
{
TreeNode child = new TreeNode(element, value);
child.setKey(element);
child.setValue(value);
child.setParent(node);
node.setLeftChild(child);
size++;
}
}
else if((int) node.getKey() <= (int) element)
{
if(node.getRightChild() != null)
insertOperation(element,value,node.getRightChild());
else
{
TreeNode child = new TreeNode(element, value);
child.setKey(element);
child.setValue(value);
child.setParent(node);
node.setRightChild(child);
size++;
}
}
}
}
///more methods
}
The problem is that when I create a child node and set the parent child link. The value of parent node (the node object that I passed) also gets updated and refers to child object.
That is not my intention.
I want to create a chain of treenode objects that can be accessed through the "root" treenode object.
But this is not happening and I do not understand what I am doing wrong.
I know that the problem lies in the logic of this code snippet (not just for inserting on left side but both for inserting left child and right), but I do not understand what exactly.
if(node.getLeftChild() != null)
insertOperation(element,value,node.getLeftChild());
else
{
TreeNode child = new TreeNode(element, value);
child.setKey(element);
child.setValue(value);
child.setParent(node);
node.setLeftChild(child);
size++;
}
All I am telling java to do is if the node in question does not have a left child then create a left child node and set the current node's left side object to the child object.
if the node in question does have a left child then inspect that child and see if the new node should be inserted in left or right by calling the same function for the child of the node in question ... I don't understand why node's (the TreeNode object passed) key gets updated, when i set child's key value.
Why are your key and value static Objects? This means all TreeNodes would share the same key/value. Remove the static keyword and it should work fine.
I don't quite get what you mean by
The problem is that when I create a child node and set the parent child link. The value of parent node (the node object that I passed) also gets updated and refers to child object.
but I did notice one thing that will result an error:
else if((int) node.getKey() <= (int) element)
When node.getKey() == element, it means the bst already has a node with "element" as the key, which should be another special case. Instead you're still traversing through its right child.
Also, it would be nice if you can elaborate your error more clearly...

Categories