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;
}
}
Related
Implementing LinkedList in a recursive approach was a bit challenging to me, which I get stuck in implementing of its remove method and wonder how to keep reference to previous item in recursive?
MyLinkedList class
package linkedlist;
public class MyLinkedList {
private Integer value;
private MyLinkedList next;
public MyLinkedList() {
}
public MyLinkedList(Integer value) {
this.value = value;
}
public void add(Integer value) {
if (this.value == null) {
this.value = value;
} else if (this.next == null) {
this.next = new MyLinkedList(value);
} else {
this.next.add(value);
}
}
public MyLinkedList remove(Integer index) {
//
// if (index < 0) {
// return this;
// }
// if (index == 0) {
// return this.next;
// }
// this.next = remove(index - 1);
return this;
}
public Integer indexOf(Integer value) {
if (this.value.equals(value)) {
return 0;
} else if (this.next == null) {
return null;
} else {
return 1 + this.next.indexOf(value);
}
}
}
MyLinkedListTester class
package linkedlist;
public class MyLinkedListTester {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.add(1);
myLinkedList.add(2);
myLinkedList.add(3);
myLinkedList.add(4);
System.out.println("Index Of Array: " + myLinkedList.indexOf(3));
MyLinkedList linkedList = myLinkedList.remove(3);
}
}
As mentioned in the comments the iterative approach is easier and more efficient most of the time. Anyway I think you do this as an exercise because in Java you already have a LinkedList.
So first you have a kind of error in your thinking (as far as I'm aware of it). It's also a kind of bad design choice. You create your MyLinkedList and save the data right into it and the next is also of the class MyLinkedList but it's not a list, it's a Node. There should only be one List, and 0 - many nodes.
For example I can't figure out how to do a remove function that will return the removed Node (in your case MyLinkedList) and as well let you keep the list in case you remove the first element in your list.
If you are looking in the implementation that's why they use Nodes and it's also more logical (a list doesn't contain "List elements") and so on...
Some other remark: your indexOf funtion will return an error if you try to get a element that does not exist (1 + null => error).
So anyway. What you have to do is to create a Node. (btw if you really want a real LinkedList you can use generic instead of int/Integer).
Below I post my solution how to do it (may be better out there but that is how I would do it). I also wrote a toString method to see how the List looks like (and it works as far as I can say). In case you want to still use your code without the Node it should give you an idea how to solve your problem with remove. You can also put some of the logic into the Node class but for me Node is only a container and doesn't really contain any logic.
public class MyLinkedList {
private Node head;
public MyLinkedList() {
}
public class Node{
private int value;
private Node next = null;
public Node(int value){
this.value = value;
}
public int getValue(){
return value;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
public void add(int value) {
Node next = new Node(value);
if(head == null){
head = next;
} else {
addRecursive(head,next);
}
}
private void addRecursive(Node node, Node next) {
if(node.next == null){
node.setNext(next);
} else {
addRecursive(node.getNext(),next);
}
}
public Node remove(int index){
Node removeNode = head;
if(index == 0){
head = head.getNext();
} else {
removeNode = removeRecursive(head,index-1);
}
return removeNode;
}
private Node removeRecursive(Node node, int index){
Node removeNode = node.getNext();
if(index == 0){
node.setNext(removeNode.getNext());
} else {
removeNode = removeRecursive(node.getNext(),index-1);
}
return removeNode;
}
public int indexOf(int value) {
if (head == null){
return -1;
} else if (head.getValue() == value){
return 0;
} else {
return indexOfRecursive(head,value,0);
}
}
private int indexOfRecursive(Node node, int value, int index) {
if(node.getNext() == null){
return -1;
} else if(node.getNext().getValue() == value){
return index + 1;
} else {
return indexOfRecursive(node.getNext(),value,index+1);
}
}
#Override
public String toString(){
if(head == null){
return "";
} else {
return toStringRecursive(head,"["+head.getValue());
}
}
private String toStringRecursive(Node node, String output){
if(node.getNext() == null){
return output + "]";
} else {
return toStringRecursive(node.getNext(),output + ", " + node.getNext().getValue());
}
}
}
I'm creating methods that will be used for buttons one that will return the next Photo object in my array and when it gets to the end will start over moving through the list. The other that will get the previous Photo Object and will start at the end when it reaches the beginning
My issue is that the loop always returns true and if I use listIterator.next I get an error, my class also implements collection if that helps any
public Photo next() {
ListIterator<Photo> listIterator = PhotoAlbum.photo.listIterator();
if (this.size() == 0) {
return null;
}
if (listIterator.hasNext()) {
Photo output = listIterator.next();
return output;
}
return PhotoAlbum.photo.get(0);
}
public Photo previous() {
ListIterator<Photo> listIterator = PhotoAlbum.photo.listIterator();
if (this.size() == 0) {
return null;
}
if (listIterator.hasPrevious()) {
return listIterator.previous();
}
return PhotoAlbum.photo.get(this.size()-1);
}
You should store the current index of the photo inside a variable.
private int currentPhotoIndex = 0;
Then your functions will increment/decrement it depending on the operation
private int currentPhotoIndex = 0;
public Photo next() {
if (this.size() == 0) {
return null;
}
if (this.currentPhotoIndex < this.size()) {
this.currentPhotoIndex++;
} else {
this.currentPhotoIndex = 0;
}
//I think here it should be: return this.get(currentPhotoIndex), but I sticked to your code
return PhotoAlbum.photo.get(currentPhotoIndex);
}
public Photo previous() {
if (this.size() == 0) {
return null;
}
if (this.currentPhotoIndex > 0) {
this.currentPhotoIndex--;
} else {
this.currentPhotoIndex = this.size() - 1;
}
//I think here it should be: return this.get(currentPhotoIndex), but I sticked to your code
return PhotoAlbum.photo.get(currentPhotoIndex);
}
You can do it simple using ListIterator, here is an example of that.
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Thomas");
names.add("Andrew");
names.add("Ivan");
ListIterator li = names.listIterator();
while(li.hasNext()) {
System.out.println(li.next());
}
while(li.hasPrevious()) {
System.out.println(li.previous());
}
}
}
Of course that is only a simple example, but you can adapt it to your needs.
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.
I'm trying to write code in a way that it is object oriented. In this particular case I want to keep track of the minimum value of my stack in O(1) time. I know how to do it, the idea of it, well my idea of it, which is to have another stack that keeps track of the minimum value for every push and pop.
I've nested every class inside of the program class which is called minStack, which doesn't seem like the right thing to do however when I create a instance of minStack and call its variables it works out fine for a regular stack. I created a class that extends a Stack called StackWithMin but I don't know how to call its values. Should I create a new instance of a StackWithMin? If so how would i do it? I did it at the end of the code above the main function, but peek() always returns null
class minStack {
public class Stack {
Node top;
Object min = null;
Object pop() {
if(top != null) {
Object item = top.getData();
top = top.getNext();
return item;
}
return null;
}
void push(Object item) {
if(min == null) {
min = item;
}
if((int)item < (int)min) {
min = item;
}
Node pushed = new Node(item, top);
top = pushed;
}
Object peek() {
if(top == null) {
//System.out.println("Its null or stack is empty");
return null;
}
return top.getData();
}
Object minimumValue() {
if(min == null) {
return null;
}
return (int)min;
}
}
public class Node {
Object data;
Node next;
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public void setNext(Node n) {
next = n;
}
public Node getNext() {
return next;
}
public void setData(Object d) {
data = d;
}
public Object getData() {
return data;
}
}
public class StackWithMin extends Stack {
Stack s2;
public StackWithMin() {
s2 = new Stack();
}
public void push(Object value) {
if((int)value <= (int)min()) {
s2.push(value);
}
super.push(value);
}
public Object pop() {
Object value = super.pop();
if((int)value == (int)min()) {
s2.pop();
}
return value;
}
public Object min() {
if(s2.top == null) {
return null;
}
else {
return s2.peek();
}
}
}
Stack testStack = new Stack();
StackWithMin stackMin = new StackWithMin();
public static void main(String[] args) {
minStack mStack = new minStack();
//StackWithMin stackMin = new StackWithMin();
mStack.testStack.push(3);
mStack.testStack.push(5);
mStack.testStack.push(2);
mStack.stackMin.push(2);
mStack.stackMin.push(4);
mStack.stackMin.push(1);
System.out.println(mStack.testStack.peek());
System.out.println(mStack.stackMin.peek());
mStack.testStack.pop();
}
}
I would suggest to create generic interface Stack like this one
interface Stack<T> {
void push(T item);
T pop();
T peek();
}
Generics add stability to your code by making more of your bugs
detectable at compile time.
See more about generics here.
Then implement this interface in a common way. All implementation details will be hidden inside of this class (your Node class for example). Here is the code (it is just to show the idea, if you want to use it you need to improve it with exception handling for example). Note that class Node is now also generic.
class SimpleStack<T> implements Stack<T> {
private class Node<T> { ... }
private Node<T> root = null;
public void push(T item) {
if (root == null) {
root = new Node<T>(item);
} else {
Node<T> node = new Node<T>(item, root);
root = node;
}
}
public T pop() {
if (root != null) {
T data = root.getData();
root = root.getNext();
return data;
} else {
return null;
}
}
public T peek() {
if (root != null) {
return root.getData();
} else {
return null;
}
}
}
Now we get to the part with stored minimum value. We can extend our SimpleStack class and add field with another SimpleStack. However I think this is better to make another implementation of the Stack and store two stacks for values and for minimums. The example is below. I have generalize the class that now uses Comparator to compare object, so you can use any other object types.
class StackWithComparator<T> implements Stack<T> {
private Comparator<T> comparator;
private SimpleStack<T> mins = new SimpleStack<>();
private SimpleStack<T> data = new SimpleStack<>();
public StackWithComparator(Comparator<T> comparator) {
this.comparator = comparator;
}
public void push(T item) {
data.push(item);
if (mins.peek() == null || comparator.compare(mins.peek(), item) >= 0) {
mins.push(item);
} else {
mins.push(mins.peek());
}
}
public T pop() {
mins.pop();
return data.pop();
}
public T peek() {
return data.peek();
}
public T min() {
return mins.peek();
}
}
Now you can use both implementations like so
SimpleStack<Integer> s1 = new SimpleStack<>();
s1.push(1);
s1.push(2);
s1.push(3);
System.out.println(s1.pop()); // print 3
System.out.println(s1.pop()); // print 2
System.out.println(s1.pop()); // print 1
StackWithComparator<Integer> s2 = new StackWithComparator<>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
s2.push(1);
s2.push(2);
s2.push(3);
s2.push(0);
s2.push(4);
System.out.println(s2.min() + " " + s2.pop()); // print 0 4
System.out.println(s2.min() + " " + s2.pop()); // print 0 0
System.out.println(s2.min() + " " + s2.pop()); // print 1 3
System.out.println(s2.min() + " " + s2.pop()); // print 1 2
System.out.println(s2.min() + " " + s2.pop()); // print 1 1
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.