Inexplicable Issue with Add Method of a Simple Binary Tree - java

My binary tree looks pretty close to my class materials, but when I print to the console or check for contains(), any adds I'm doing aren't registered.
I don't have a great understanding of static and the debugger is giving me a hint about making a static reference to non-static variable overallRoot, but everything compiles without error or warning in eclipse.
public class BSTSimpleSet<E extends Comparable<E>> implements SimpleSet<E> {
private GTNode<E> overallRoot;
private int size;
public static void main(String[] args) {
BSTSimpleSet<Integer> main = new BSTSimpleSet<Integer>(2);
main.toString();
main.add(3);
main.toString();
main.add(4);
main.toString();
main.add(5);
main.toString();
System.out.print(main.contains(3));
}
public BSTSimpleSet() {
size = 0;
}
public BSTSimpleSet(E input) {
overallRoot = new GTNode<E>(input);
size = 1;
}
public boolean add(E e) {
return add(e, overallRoot);
}
private boolean add(E e, GTNode<E> root) {
if (root == null) {
root = new GTNode<E>(e);
size++;
return true;
} else {
int compare = e.compareTo(root.data);
if (compare == 0) {
return false;
} else if (compare < 0) {
return add(e, root.left);
} else {
return add(e, root.right);
}
}
}
public void clear() {
overallRoot = null;
}
public boolean contains(E e) {
return contains(e, overallRoot);
}
private boolean contains(E e, GTNode<E> root) {
if (root == null) {
return false;
} else {
int compare = e.compareTo(root.data);
if (compare == 0) {
return true;
} else if (compare < 0) {
return contains(e, root.left);
} else {
return contains(e, root.right);
}
}
}
public boolean isEmpty() {
if (overallRoot == null) {
return false;
} else {
return true;
}
}
public int size() {
return size;
}
public String toString() {
this.toString(overallRoot, 0);
return null;
}
private void toString(GTNode<E> root, int level) {
if (root != null) {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println(root.data);
toString(root.left, level + 1);
toString(root.right, level + 1);
} else {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println("_");
}
}
private static class GTNode<E extends Comparable<E>> {
public E data;
public GTNode<E> left;
public GTNode<E> right;
public GTNode(E input) {
this(input, null, null);
}
public GTNode(E input, GTNode<E> lNode, GTNode<E> rNode) {
data = input;
left = lNode;
right = rNode;
}
}
}

This code does absolutely nothing.
private boolean add(E e, GTNode<E> root) {
if (root == null) {
root = new GTNode<E>(e);
size++;
return true;
}
...
Java passes in the Object Reference to a method. If you change the Reference, that will not
be propagated back to the calling method. If you change what the Reference refers to
that will be propagated back.
eg
// arrays behave the same way so using them to illustrate.
public void callMethods(){
int[] array = new int[1];
array[0] = 0;
doesNotChange(array);
System.out.println(array[0]);// will print 0
doesAChange(array);
System.out.println(array[0]);// will print 1
}
public void doesNotChange(int[] myArray){
myArray = new int[1];
myArray[0] = 1;
}
public void doesAChange(int[] myArray){
myArray[0] = 1;
}
To avoid these sorts of things I recommend always setting method parameters final.

The GTNode class shouldn't be static. Static classes are classes with only static methods, which means they don't have to be instantiated. The prototypical example of this is the java.lang.Math class: You don't need to call something like Math m = new Math(); m.cos(); to get the cosine, you just call Math.cos(). Since you're creating multiple instances of the GTNode class, make it non-static and you should be good.

Related

Custom treeSet class, how to write iterator

I am trying to create my own binary search tree. But I can't think of any way to implement a working iterator that has hasNext(), next().
I got the idea the only way to traverse a Binary search tree was through recursion. But how could I possibly save a recursion call if I am trying to use next, so it resumes when next gets called again and returns the value?
Is there any other way
import java.util.Iterator;
public class TreeWordSet implements WordSetInterface {
private BST root = null;
private class BST {
Word value;
BST left = null;
BST right = null;
BST(Word word) {
value = word;
}
void add(Word newWord) {
if (newWord.compareTo(value) < 0) {
if(left == null) {
left = new BST(newWord);
} else {
left.add(newWord);
}
} else if (newWord.compareTo(value) > 0) {
if (right == null) {
right = new BST(newWord);
} else {
right.add(newWord);
}
}
}
}
#Override
public void add(Word word) {
if (root == null) {
root = new BST(word);
} else {
root.add(word);
}
}
#Override
public boolean contains(Word word) {
return false;
}
#Override
public int size() {
return 0;
}
private class TreeWordSetIterator implements Iterator<Word> {
#Override
public boolean hasNext() {
return false;
}
#Override
public Word next() {
return null;
}
}
#Override
public Iterator<Word> iterator() {
return new TreeWordSetIterator();
}
}
If this is an exercise for the purpose of learning, maybe the best way is to just go look how TreeSet does it. If this is an exercise for production use, stop it right here right now and extend TreeSet if you really need to.
I solved it this way, it's not glamourous. Until someone can provide a better solution
private class TreeWordSetIterator implements Iterator<Word> {
Word arr[] = new Word[size()];
int i = 0;
TreeWordSetIterator(){
traverse(root);
i = 0;
}
private void traverse(BST currentNode) {
if (currentNode == null) {
return;
}
traverse(currentNode.left);
arr[i] = currentNode.value;
i++;
traverse(currentNode.right);
}
#Override
public boolean hasNext() {
if (i < size()) {
return true;
} else {
return false;
}
}
#Override
public Word next() {
Word current = arr[i];
i++;
return current;
}
}

What is wrong with this code? It won't run

public class StackSimple{
private long capacity=1000;//maximum size of array
private int idx_top;
private Object data[];
public StackSimple(int capacity)
{
idx_top=-1;
this.capacity=capacity;
data = new Object[capacity];
}
public boolean isEmpty(){
return(idx_top<0);
}
public boolean isFull(){
return(idx_top>=capacity-1);
}
public int size()
{
return idx_top+1;
}
public boolean push(Object x){
if (isFull()){
throw new IllegalArgumentException("ERROR:Stack Overflow.Full Stack");
}
else
{`enter code here`data[++idx_top]=x;
return true;
}
}
public Object pop(){
if(isEmpty())
throw new IllegalArgumentException("ERROR:Stack Underflow.Empty Stack.");
else{
return data[idx_top--];
}
}
public Object top(){
if (isEmpty())
throw new IllegalArgumentException("ERROR:Stack Underflow.Empty Stack.");
else{
return data[idx_top];
}
}
public void print()
{`
for (int i=size()-1;i>=0;i--)
System.out.println(data[i]);
}
}
public class Stack_Exercise {
public static void main(String[] args) {
StackSimple s = new StackSimple(capacity:3);//error shows here
s.push(x:"books");`enter code here`
s.push(x:"something");
s.push(x:"200");
s.print();
System.out.println("Size=" +s.size());
}
}
Why doesn't this work?
Why does it say invalid statement while creating the StackSimple object? The problem is in the main class while running it. There are errors while pushing the elements.
Error while compiling
When passing parameters to a function you just pass the values.
In your case not StackSimple(capacity:3) but just StackSimple(3)
First question, which version of Java are you using.
Second, in Java you should be passing as a variable instead of StackSimple(capacity:3). Change your main method to below, here is my recommendation:
StackSimple s = new StackSimple(3);
s.push("books");
s.push("something");
s.push("200");
s.print();
System.out.println("Size=" +s.size());
You are not at all pushing the value in the stack, your pusch function is not working as it is expected to work.
Here is the correct program.
class StackSimple {
private long capacity = 1000;// maximum size of array
private int idx_top;
private Object data[];
public StackSimple(int capacity) {
idx_top = -1;
this.capacity = capacity;
data = new Object[capacity];
}
public boolean isEmpty() {
return (idx_top < 0);
}
public boolean isFull() {
return (idx_top >= capacity - 1);
}
public int size() {
return idx_top + 1;
}
public boolean push(Object x) {
if (isFull()) {
throw new IllegalArgumentException("ERROR:Stack Overflow.Full Stack");
} else {
data[++idx_top] = x;
return true;
}
}
public Object pop() {
if (isEmpty())
throw new IllegalArgumentException("ERROR:Stack Underflow.Empty Stack.");
else {
return data[idx_top--];
}
}
public Object top() {
if (isEmpty())
throw new IllegalArgumentException("ERROR:Stack Underflow.Empty Stack.");
else {
return data[idx_top];
}
}
public void print() {
for (int i = size() - 1; i >= 0; i--)
System.out.println(data[i]);
}
}
public class test {
public static void main(String[] args) {
StackSimple s = new StackSimple(3);// error shows here
s.push("books");
s.push("something");
s.push("200");
s.print();
System.out.println("Size=" + s.size());
}
}

Java double LinkedList remove node

So the idea is to make a Double Ended Priority Queue so far I have got a tree like structure using 2 Linked Lists, I have and interface I have to stick with with no alterations to it. The problem I have got is I have to make 2 methods called getMost and getLeast which gets the most or least node and then makes that node null. But these 2 methods are proving quite difficult to make. How would you go about doing it?
I have tried using recursion but this is proving difficult as I have to select the tree by going tree.root but passing in tree.root into a recursive method always starts it from tree.root
Also I have tried what i have written in inspectLeast() and inspectMost() but Java passes by value not by reference. Any tips?
P.S Not allowed to use anything from java collections or java util.
public class PAS43DPQ implements DPQ
{
//this is the tree
TreeNode tree = new TreeNode();
//this is for the size of the array
int size = 0;
#Override
public Comparable inspectLeast() {
return tree.inspectLeast(tree.root);
}
#Override
public Comparable inspectMost() {
return tree.inspectMost(tree.root);
}
#Override
public void add(Comparable c)
{
tree.add(c);
size++;
}
#Override
public Comparable getLeast() {
if (tree.root != null){
}
return getLeast();
}
#Override
public Comparable getMost(){
Comparable most = getMost();
return most;
}
#Override
public boolean isEmpty() {
return (size > 0)?true:false;
}
#Override
public int size() {
return this.size;
}
class TreeNode{
private Comparable value;
private TreeNode left, right, root;
//constructors
public TreeNode() {}
public TreeNode(TreeNode t) {
this.value = t.value;
this.left = t.left;
this.right = t.right;
this.root = t.root;
}
public TreeNode(Comparable c) {
this.value = (int) c;
}
public void add(Comparable input){
if(root == null){
root = new TreeNode(input);
return;
} else {
insert(root, input);
}
}
public Comparable inspectLeast(TreeNode n){
if (n == null)
return null;
if (n.left == null){
TreeNode least = n;
return least.value;
}
return inspectLeast(n.left);
}
public Comparable inspectMost(TreeNode n){
if (n == null)
return null;
if (n.right == null){
TreeNode most = n;
return most.value;
}
return inspectMost(n.right);
}
public Comparable getMost(TreeNode n){
if(n.right == null)
return n.value;
return tree.getMost(right);
}
public void insert(TreeNode n, Comparable input){
if(input.compareTo(n.value) >= 0){
if (n.right == null) {
n.right = new TreeNode(input);
return;
}
else
insert(n.right, input);
}
if(input.compareTo(n.value) < 0){
if(n.left == null) {
n.left = new TreeNode(input);
return;
}
else
insert(n.left, input);
}
}
}
}
You should be able to modify your TreeNode.getMost(TreeNode n) and TreeNode.getLeast(TreeNode n) similar to the following:
public class TreeNode{
// Also, your parameter here seems to be superfluous.
public TreeNode getMost(TreeNode n) {
if (n.right == null) {
n.root.right = null;
return n;
}
return n.getMost(n);
}
}
Get least should be able to be modified in a similar fashion, but using left rather than right obviously.

OutOfBoundsException into stack

I have a problem with ArrayIndexOutOfBoundsException it is always appears in my program. How I can go into try{}?
#Override
public Object pop() {
if (stackIsEmpty()) {
System.err.println("underflow");
return null;
} else {
try {
Object temp = stack[top];
stack[top--] = null;
System.out.println("top is " + top);
return temp;
} catch (ArrayIndexOutOfBoundsException e) {
return "exception";
}
}
}
added code of the rest class( I have the comparison with -1 into stackisEmpty()):
public class ArrayStackImpl implements ArrayStack {
private int top = -1;
private int maxLength;
public Object stack[] = new Object[maxLength];
public ArrayStackImpl(int maxLength) {
this.maxLength = maxLength;
}
#Override
public boolean stackIsEmpty() {
return (top < 0);
}
#Override
public void push(Object o) {
if ((top >= maxLength - 1))
System.err.println("overflow");
else
try {
stack[++top] = o;
} catch (ArrayIndexOutOfBoundsException e) {
}
}
On popping of a non-empty stack top might become -1 (for "empty stack"). So
private int top = -1;
public boolean stackIsEmpty() {
return top < 0; // != -1
}
Do the field initialisation in your constructor. Before that maxlength is not initialized, and 0.
Furthermore you do not need maxlength as field. stack.length == maxlength.
public Object[] stack;
public ArrayStackImpl(int maxLength) {
stack = new Object[maxLength];
(I used the more conventional notation Object[].)
Check top is initialized to -1. Don't catch ArrayIndexOutOfBoundsException, find out why. Also, your stackIsEmpty should check if top equals -1.

Why is `root` keep staying null?

I have a very basic binary tree
import java.util.Scanner;
public class ExprTree {
// Data member
private ExprTreeNode root; // reference to root node
private String input;
private Scanner s = new Scanner(System.in);
// Constructor
public ExprTree() {
// root = new ExprTreeNode(key, leftPtr, rightPtr)
}
// Expression tree manipulation methods
public void build() {
System.out.println("Please enter a prefix sequence. avoid using spaces!");
input = s.nextLine();
for(int i = 0; i < input.length(); ++i) {
addToTree(root, input.charAt(i));
}
}
public void expression() {
}
public float evaluate() {
return 0;
}
public void clear() {
}
public void showStructure(ExprTreeNode t) {
if(t == null) // no more
return;
System.out.println(t.getKey() + "-> ");
showStructure(t.getLeft());
showStructure(t.getRight());
}
private void showSubTrees(ExprTreeNode p, int leven) {
}
private void addToTree(ExprTreeNode t, char key) {
if(t == null) { // no more
t = new ExprTreeNode(key, null, null);
return;
}
addToTree(t.getLeft(), key);
addToTree(t.getRight(), key);
}
public ExprTreeNode getRoot() {
return root;
}
public static void main(String[] args) {
ExprTree t = new ExprTree();
t.build();
t.showStructure(t.getRoot());
}
}
And the tree node class:
public class ExprTreeNode {
// Data memebers
private char key;
private ExprTreeNode left,
right;
// Constructor
public ExprTreeNode(char key, ExprTreeNode leftPtr, ExprTreeNode rightPtr) {
this.key = key;
left = leftPtr;
right = rightPtr;
}
public char getKey() {
return key;
}
public void setKey(char key) {
this.key = key;
}
public ExprTreeNode getLeft() {
return left;
}
public void setLeft(ExprTreeNode left) {
this.left = left;
}
public ExprTreeNode getRight() {
return right;
}
public void setRight(ExprTreeNode right) {
this.right = right;
}
}
In this line:
for(int i = 0; i < input.length(); ++i) {
addToTree(root, input.charAt(i));
}
Every time I call addToTree with root, the debugegr shows that root is null,
even though the first time I called addToTree has alloced root, and the debugger shows so.
Why is it keep staying null?
You commented out the line in
public ExprTree() {
// root = new ExprTreeNode(key, leftPtr, rightPtr);
// just use null for both left and right ptr
}
so root is null.
Remember that java is pass by value, so
private void addToTree(ExprTreeNode t, char key) {
if(t == null) { // no more
t = new ExprTreeNode(key, null, null);
return;
}
addToTree(t.getLeft(), key);
addToTree(t.getRight(), key);
}
called with
addToTree(root, input.charAt(i));
t has the same reference as root, ie. null, but isn't a reference to the variable root. So all you are doing is re-assigning a local variable.

Categories