Insert node into binary search tree - java

I have been plugging away at a Binary Search Tree implementation for a few days now and I am to the point where I know that my root is being populated through the use of my 'insert()' (I can see this when I debug, using Eclipse). Why won't my other nodes get added to the tree?
Here is my BST Class:
package binarySearchTree;
public class BinarySearchTree<T extends Comparable<T>> {
#SuppressWarnings("hiding")
private class BinarySearchTreeNode<T>{
public BinarySearchTreeNode left, right;
private T data; //LINE 8
private BinarySearchTreeNode (T data,BinarySearchTreeNode left, BinarySearchTreeNode right ) {
this.left = left;
this.right = right;
this.data = data;
}
}
private BinarySearchTreeNode<T> root;
#SuppressWarnings("unused")
private T search(T target, BinarySearchTreeNode<T> ptr) {
//find target in subtree A ptr
if (root == null || ptr == null) {
return root; //target is not in tree
}
int compare = target.compareTo(ptr.data); //compareTo(ptr.data);
if (compare == 0) {
return ptr.data; //target is found
}
if (compare < 0) {
return search(target, ptr.left);
}
if (compare > 0) {
return search(target, ptr.right);
}
return target;
}
public T search(T target) {
return search(target);
}
public boolean isEmpty() {
return root == null;
}
/* To insert a data into a BST, 1st search for the data,
* if the data is found = duplicate data error
* if the data is NOT found = a null pointer
* Make this null pointer point to a NewNode holding data
* new values go into the BST as leaves
* Using public boolean insert (T node) &
* private boolean insert (T Node, BSTNode<T> ptr) as a recursive method
*/
#SuppressWarnings("unchecked")
private boolean insert(T value, BinarySearchTreeNode<T> ptr) {
//T data = null;
//insert data in a child of ptr, return false if duplicate is found
//Precondition: ptr must not be null
int compare = value.compareTo(ptr.data); //LINE 55
if (compare == 0) {
return false;
}
if (compare < 0) {
if (ptr.left == null) {
//found insertion point
BinarySearchTreeNode<T> node = new BinarySearchTreeNode<>(value, null, null);
ptr.left.data = node; //insert data in new node
return true;
}
} else {
return insert(value, ptr.left); //LINE 67
}
if (compare > 0) {
if (ptr.right == null) {
BinarySearchTreeNode<T> node = new BinarySearchTreeNode<>(value, null, null);
ptr.right.data = node;
return true;
} else {
return insert(value, ptr.right);
}
}
return false;
}
public boolean insert(T value) {
if (isEmpty()) {
root = new BinarySearchTreeNode<T>(value, null, null);
return true;
}
return insert(value, root); // LINE 85
}
}
And here is my Main(), eventually I would like to print the values of my BST in the console but first I know they need to be added to the tree:
package binarySearchTree;
public class Main {
public static void main(String[] args) {
BinarySearchTree<String> bstStrings = new BinarySearchTree<String>();
String s = "Hello";
String s1 = "World";
//String s2 = "This Morning";
bstStrings.insert(s);
bstStrings.insert(s1); //LINE 15
//bstStrings.insert(s2);
while (true){
if (!bstStrings.isEmpty()){
System.out.println(bstStrings + " ");
}
System.out.println();
System.out.println("You should have values above this line!");break;
}
}
}

Your root should be of BinarySearchTree<T> and not T
As a result you are not storing the values in the subtrees of the root.
Replace this:
return insert((T) value, node);
with
return insert((T) value, root);
in your code replace as follows:
public boolean insert(T value) {
if (isEmpty()) {
root = new BinarySearchTreeNode((T) value, null, null);
return true;
}
return insert((T) value, root); // start recursion
}
Otherwise you don't have a tree and the nodes are not linked to each other
UPDATE:
You get the NPE because you pass in insert the left child of root in the first comparison which is null.
You should not return boolean but BinarySearchTreeNode.
Your method should be:
#SuppressWarnings("unchecked")
private BinarySearchTreeNode<T> insert(T value, BinarySearchTreeNode<T> ptr) {
if(ptr == null){
ptr = new BinarySearchTreeNode<T>(value,null,null);
return ptr;
}
//your code next but return the `ptr`
}
Then in insert you should do:
public void insert(T value) {
root = insert(value, root);
}

After the first insertion, you create new nodes, but don't do anything with them.

Related

Rebalancing a Binary Tree Using Array Recursively (Java)

I am trying to balance a binary tree recursively by adding the tree data into an array in order, balance that data/ nodes (to minimize height) then insert the now balanced data back into the tree in the correct order. I am stuck on how to correctly do this all recursively. Here is the code if you scroll down you will see rebalance along with the methods I made to attempt to balance this tree:
package adts;
import java.util.Stack;
import interfaces.*;
import nodes.BSTNode;
public class BinarySearchTree<T extends Comparable<T>>
implements BSTInterface<T>
{
protected BSTNode<T> root; // reference to the root of this BST
boolean found; // used by remove
// for traversals
protected ArrayQueue<T> inOrderQ;
protected ArrayQueue<T> preOrderQ;
protected ArrayQueue<T> postOrderQ;
protected BinarySearchTree left = null;
protected BinarySearchTree right = null;
protected T[] rebalanceArray;
public BinarySearchTree() {
root = null;
}
public void add (T element) {
root = recAdd(element, root);
}
private BSTNode<T> recAdd(T element, BSTNode<T> tree) {
if (tree == null) {
tree = new BSTNode<T>(element);
}
else {
if (element.compareTo(tree.getData()) <= 0) {
tree.setLeft(recAdd(element, tree.getLeft())); // add to left subtree
}
else {
tree.setRight(recAdd(element, tree.getRight())); // add to right subtree
}
}
return tree;
}
public boolean remove (T element) {
root = recRemove(element, root);
return found;
}
private BSTNode<T> recRemove(T element, BSTNode<T> tree) {
if (tree == null) {
found = false;
}
else {
if (element.compareTo(tree.getData()) < 0) {
tree.setLeft(recRemove(element, tree.getLeft()));
}
else {
if (element.compareTo(tree.getData()) > 0) {
tree.setRight(recRemove(element, tree.getRight()));
}
else {
tree = removeNode(tree);
found = true;
}
}
}
return tree;
}
private BSTNode<T> removeNode(BSTNode<T> tree) {
T payload;
if (tree.getLeft() == null) {
return tree.getRight();
}
else {
if (tree.getRight() == null) {
return tree.getLeft();
}
else {
payload = getPredecessor(tree.getLeft());
tree.setData(payload);
tree.setLeft(recRemove(payload, tree.getLeft()));
return tree;
}
}
}
private T getPredecessor(BSTNode<T> tree) {
while (tree.getRight() != null) {
tree = tree.getRight();
}
return tree.getData();
}
public int size() {
return recSize(root);
}
private int recSize(BSTNode<T> tree) {
if (tree == null) {
return 0;
}
else {
return recSize(tree.getLeft()) + recSize(tree.getRight()) + 1;
}
}
// this implementation of a size operation demonstrates that
// it is possible to visit all the nodes of the tree without recursion
public int size2() {
int count = 0;
if (root != null) {
LLStack<BSTNode<T>> hold = new LLStack<BSTNode<T>>();
BSTNode<T> currNode;
hold.push(root);
while (!hold.isEmpty()) {
currNode = hold.peek();
hold.pop();
count++;
if (currNode.getLeft() != null) {
hold.push(currNode.getLeft());
}
if (currNode.getRight() != null) {
hold.push(currNode.getRight());
}
}
}
return count;
}
public boolean isEmpty() {
return (root == null);
}
public boolean contains (T element) {
return recContains(element, root);
}
private boolean recContains(T element, BSTNode<T> tree) {
if (tree == null) return false;
else
if (element.compareTo(tree.getData()) < 0)
return recContains(element, tree.getLeft()); // search left subtree
else
if (element.compareTo(tree.getData()) > 0)
return recContains(element, tree.getRight()); // search right subtree
else
return true; // element is found!
}
public T get(T element) {
return recGet(element, root);
}
private T recGet(T element, BSTNode<T> tree) {
if (tree == null)
return null;
else
if (element.compareTo(tree.getData()) < 0)
return recGet(element, tree.getLeft()); // get from left subtree
else
if (element.compareTo(tree.getData()) > 0)
return recGet(element, tree.getRight()); // get from right subtree
else
return tree.getData(); // element is found!
}
public void rebalance() {
T[] rebalanceArray = (T[]) new Comparable[size()];
// I want to return the newly constructed/ balanced tree here
}
private BinarySearchTree constructBST(T[] rebalanceArray , int high, int low) {
if (low > high)
return null;
int mid = (low+high)/2;
BinarySearchTree node = new BinarySearchTree();
node.left = constructBST(rebalanceArray, low, mid - 1);
node.right = constructBST(rebalanceArray, mid + 1, high);
return node;
}
private void storeNodes(BSTNode<T> root, BinarySearchTree nodes) {
if(root == null)
return;
storeNodes(root.getLeft(), nodes);
nodes.add(root); //add function not working
storeNodes(root.getRight(), nodes);
}
// populate inOrderQ with tree elements based on in-order traversal
private void inOrder(BSTNode<T> tree) {
if (tree != null) {
inOrder(tree.getLeft());
inOrderQ.enqueue(tree.getData());
inOrder(tree.getRight());
}
}
// populate preOrderQ with tree elements based on pre-order traversal
private void preOrder(BSTNode<T> tree) {
if (tree != null) {
preOrderQ.enqueue(tree.getData());
preOrder(tree.getLeft());
preOrder(tree.getRight());
}
}
// populate postOrderQ with tree elements based on post-order traversal
private void postOrder(BSTNode<T> tree) {
if (tree != null) {
postOrder(tree.getLeft());
postOrder(tree.getRight());
postOrderQ.enqueue(tree.getData());
}
}
public int reset(TraversalType orderType) {
// returns current number of nodes in the tree
int numNodes = size();
switch (orderType) {
case INORDER :
inOrderQ = new ArrayQueue<T>(numNodes);
inOrder(root);
break;
case PREORDER :
preOrderQ = new ArrayQueue<T>(numNodes);
preOrder(root);
break;
case POSTORDER :
postOrderQ = new ArrayQueue<T>(numNodes);
postOrder(root);
break;
}
return numNodes;
}
public T getNext (TraversalType orderType) {
switch (orderType) {
case INORDER : return inOrderQ.dequeue();
case PREORDER : return preOrderQ.dequeue();
case POSTORDER: return postOrderQ.dequeue();
default: return null;
}
}
}
Here is the rebalance specific code:
public void rebalance() {
T[] rebalanceArray = (T[]) new Comparable[size()];
// I want to return the newly constructed/ balanced tree here
}
private BinarySearchTree constructBST(T[] rebalanceArray , int high, int low) {
if (low > high)
return null;
int mid = (low+high)/2;
BinarySearchTree node = new BinarySearchTree();
node.left = constructBST(rebalanceArray, low, mid - 1);
node.right = constructBST(rebalanceArray, mid + 1, high);
return node;
}
private void storeNodes(BSTNode<T> root, BinarySearchTree nodes) {
if(root == null)
return;
storeNodes(root.getLeft(), nodes);
nodes.add(root); //add function not working
storeNodes(root.getRight(), nodes);
}
input/ test tree:
package apps;
import adts.BinarySearchTree;
public class TestRUn800 {
public static void main(String[] args) {
BinarySearchTree<Integer> testTree1 = new BinarySearchTree<>();
testTree1.add(1);
testTree1.add(2);
testTree1.add(3);
testTree1.add(4);
testTree1.add(5);
testTree1.add(6);
testTree1.add(7);
System.out.println(testTree1.treeHeight() + " tree height");
System.out.println(testTree1.reckonUnbalanced() + " reckonUnbalanced Value");
System.out.print(testTree1.rebalance()); // rebalance statement
}
}
I did a lot of searching around on the web and saw some solutions that had a method that built the tree and stored it's data before then returning it in the original (rebalance()) method. That is what I have here in storeNodes and buildBST but cannot get it running correctly without errors. The error I am running into for add is "The method add(Comparable) in the type BinarySearchTree is not applicable for the arguments (BSTNode)" (I also commented next to add in the code so one can see where it is). Also as seen in the tree I find tree height, the unbalanced height (reckonUnbalanced) then I want to rebalance it and get it's new height (I have not written that code in this example though just what I plan to do once I get the actual code working for rebalance).

Comparing two valus of Nodes in Binary search trees in java

hey I am new in the binary trees world and I am trying to compare to values to know which direction should I place the newly added node next.
for now, I tried to do CompareTo method but didn't succeed very much I am now trying to make a private method that will give me the value of the Nodes i would love some help
this is my code now I need to add to the if statement the comparing of nodes so I can proceed :
public void add(E data) {
if(root == null) {
return ;
}
if(root.getLeftSon() == null) {
root.setLeftSon((Node<E>) data);
}
else if(root.getRightSon() == null) {
root.setRightSon((Node<E>) data);
}
}
you have to use generics correctly. Parameter has to extend comparable so you can determinate how to sort it.
class BinaryTree<T extends Comparable<T>> {
Node<T> root;
public Node<T> addRecursive(Node<T> current, T value) {
if (current == null) {
return new Node<T>(value);
}
int ord = value.compareTo(current.value);
if (ord > 0) {
current.left = addRecursive(current.left, value);
} else if (ord < 0) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
return current;
}
static class Node<T extends Comparable<T>> {
T value;
Node<T> left;
Node<T> right;
Node(T value) {
this.value = value;
right = null;
left = null;
}
}
}

How to recursively removing an item from linkedList?

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

calculate how much internal leafs in subtree WAVL in O(1) in java

I am implementing WAVL tree and WAVL node classes. In the WAVL node class I should create a method that counts how much internal nodes exist in the subtree of the node. I should do that in time complexity of O(1). Any suggestions?
The class I wrote is:
package coding_ex1;
public class WAVLNode
{
WAVLNode left;
WAVLNode right;
WAVLNode parent;
int rank;
int key;
String value;
public WAVLNode() //*constructor
{
this.left=null;
this.right=null;
this.parent=null;
this.rank=0;
this.key=0;
this.value=null;
}
public int getKey() //*gets WAVLNode. if external leaf, return -1. else, return key
{
if (this.rank==-1)
{
return -1;
}
return key;
}
public String getValue()//*gets WAVLNode. if external leaf, returns null. else, returns value
{
if (this.rank==-1)
{
return null;
}
return value;
}
public WAVLNode getLeft()//* get WAVLNode. returns left (if there is no left, the value of left is null)
{
return left;
}
public WAVLNode getReft()//* get WAVLNode. returns right (if there is no right, the value of right is null)
{
return right;
}
public boolean isInnerNode()//*gets WAVLNode. returns true for internal leaf. else, returns false
{
if(this.right!=null || this.left!=null)
{
return true;
}
return false;
}
}
You should add a filed and methods.
private int internalNodeCount = 0; // initially count as leaf
public int internalNodeCount() {
return internalNodeCount;
}
public void setLeft(WAVLNode node) {
this.left = node;
setInternalNodeCount();
}
public void setRight(WAVLNode node) {
this.right = node;
setInternalNodeCount();
}
void setInternalNodeCount() {
if (isInnerNode()) {
internalNodeCount = 1; // count for self
if (left != null)
internalNodeCount += left.internalNodeCount;
if (right != null)
internalNodeCount += right.internalNodeCount;
} else
internalNodeCount = 0;
}

Post-order iterator in trees

I am trying to create an Iterator implementation for post-order and I am in a slump. I was able to get in-order and pre-order implementations but I can't seem to get a post-order. If you guys can point me in the right direction and give me some tips, that would be amazing.
Here's my in-order class:
public class InOrderIterator<T> implements Iterator<T> {
private final Deque<BinaryTreeNode<T>> stack;
private BinaryTreeNode<T> current;
public InOrderIterator(BinaryTreeNode<T> root){
stack = new LinkedList<BinaryTreeNode<T>>();
this.current = root;
}
#Override
public boolean hasNext() {
return (!stack.isEmpty() || current != null);
}
#Override
public T next() {
while (current != null) {
stack.push(current);
if (current.hasLeftChild())
current = current.getLeftChild();
else
current = null;
}
current = stack.pop();
BinaryTreeNode<T> node = current;
if (current.hasRightChild())
current = current.getRightChild();
else
current = null;
return node.getData();
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Here's a description of pre-, in-, and post-order:
Pre-order
Visit the root.
Traverse the left subtree.
Traverse the right subtree.
In-order
Traverse the left subtree.
Visit root.
Traverse the right subtree.
Post-order
Traverse the left subtree.
Traverse the right subtree.
Visit the root.
http://en.wikipedia.org/wiki/Tree_traversal#Types
I googled for a binary tree postorder iterator implementation but could not find a good one. So I implemented mine using two stacks.
public class BinaryTreePostorderIterator implements Iterator<Integer> {
private TreeNode root;
private Stack<TreeNode> nodes;
private Stack<Boolean> expanded;
public BinaryTreePostorderIterator(TreeNode root) {
this.root = root;
nodes = new Stack<>();
expanded = new Stack<>();
if (root != null) {
nodes.push(root);
expanded.push(false);
}
}
#Override
public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException("End reached");
}
expanded.pop();
return nodes.pop().val;
}
#Override
public boolean hasNext() {
if (nodes.isEmpty()) {
return false;
}
while (!expanded.peek()) {
expanded.pop();
expanded.push(true);
TreeNode node = nodes.peek();
if (node.right != null) {
nodes.push(node.right);
expanded.push(false);
}
if (node.left != null) {
nodes.push(node.left);
expanded.push(false);
}
}
return true;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.left.right = new TreeNode(4);
root.left.left = new TreeNode(2);
root.right = new TreeNode(7);
root.right.right = new TreeNode(8);
root.right.left = new TreeNode(6);
BinaryTreePostorderIterator pi = new BinaryTreePostorderIterator(root);
while (pi.hasNext()) {
System.out.println(pi.next());
}
}
}
One fairly general way to achieve this is by starting from the recursive algorithm, and turning it into an iterative algorithm with an explicit stack. Then, you find points in the recursive algorithm where it would output data, and you pause your computation there (in this example, by returning from the advance() method, and making sure the stack is left in a good state for the next call to advance()).
My recursive algorithm (I'm using Java 8 and a different Node class, but it's along the same lines) was:
private void postorder(Node<V> node, Consumer<V> c) {
// step 0
if (node == null) {
return; // pop
}
postorder(node.left, onTraverse); // push
// step 1
postorder(node.right, onTraverse); // push
// step 2
c.accept(node.data);
// pop
}
which turns into the following iterator:
class PostorderIterator<V> implements Iterator<V> {
class Frame {
int step;
Node<V> node;
public Frame(Node<V> node) {
this.node = node;
step = 0;
}
}
Stack<Frame> st = new Stack<>();
boolean ready;
V result;
public PostorderIterator(Node<V> node) {
st.push(new Frame(node));
}
private V advance() {
while (!st.isEmpty()) {
Frame f = st.peek();
switch (f.step) {
case 0:
if (f.node == null) {
st.pop(); // return
} else {
f.step = 1;
st.push(new Frame(f.node.left)); // ~postorder(node.left, ...)
}
break;
case 1:
f.step = 2;
st.push(new Frame(f.node.right)); // ~postorder(node.right, ...)
break;
case 2:
st.pop(); // ~return
return f.node.data;
default:
throw new RuntimeException();
}
}
return null;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
#Override
public boolean hasNext() {
if (!ready) {
result = advance();
ready = true;
}
return result != null;
}
#Override
public V next() {
if (!ready) {
result = advance();
ready = true;
}
if (result == null) {
throw new NoSuchElementException();
}
ready = false;
return result;
}
}
This approach might be a bit clunkier than necessary, but having an explicit Frame holding your local variables, arguments, and where you are in the code, should be a decent starting point to a cleaner algorithm.
I just played a bit with post order iterator..
This is what I've come up with:
class PostOrderIterator
implements Iterator<T> {
private Stack<Node<T>> stack;
private Node<T> prev;
public PostOrderIterator() {
this.stack = new Stack<>();
recurse(root);
this.prev = this.stack.peek();
}
private void recurse(Node<T> node) {
if(node == null) {
return;
}
while(node != null) {
stack.push(node);
node = node.left;
}
recurse(stack.peek().right);
}
#Override
public boolean hasNext() {
return !stack.isEmpty();
}
#Override
public T next() {
if(stack.peek().right != this.prev) {
recurse(stack.peek().right);
}
Node<T> next = stack.pop();
this.prev = next;
return next.value;
}
}
Basically, the main idea is that you should think how the initialization process puts the first item to print on the top of the stack, while the rest of the stack follow the nodes that would have been touched by the recursion. The rest would just then become a lot easier to nail.
Also, from design perspective, PostOrderIterator is an internal class exposed via some factory method of the tree class as an Iterator<T>.

Categories