If you are not going to do recursion, you have to store explicitly in a stack the sort of data that would be implied by where a call was done or in local variables in a recursive solution. In this case, I used a couple of booleans to indicate whether the left subtree has been done and whether the right subtree has been done.
I could not quite bring myself to do it all in one method. I do use a separate method to extract the list of node labels from the stack. Also, to save carrying around a separate label list, I'm not treating it strictly as a stack. I think the changes to make it a strict stack are fairly obvious. I've only commented the core code. Feel free to ask if anything else is unclear.
I do want to emphasize that this is not a design I recommend. I would use recursion, which I think would result in simpler code. I have also not spent a lot of time polishing it.
import java.util.Stack;
public class Bad {
public static void main(String[] args) {
TreeNode root;
boolean firstLeaf = true;
root = makeTree();
Stack<StackNode> stack = new Stack<StackNode>();
stack.push(new StackNode(root));
System.out.print("[");
while (stack.size() > 0) {
// Decide what to do next with the top element
StackNode top = stack.lastElement();
if (top.tn == null) {
// Nothing to do for a null subtree
stack.pop();
} else {
if (top.tn.left == null && top.tn.right == null) {
// leaf element, print it out and pop it.
if(!firstLeaf) {
System.out.print(",");
}
firstLeaf = false;
System.out.print("[" + getLabelList(stack) + "]");
stack.pop();
} else {
if (top.leftDone) {
if (!top.rightDone) {
stack.push(new StackNode(top.tn.right));
top.rightDone = true;
} else {
// Done both subtrees
stack.pop();
}
} else {
stack.push(new StackNode(top.tn.left));
top.leftDone = true;
}
}
}
}
System.out.println("]");
}
private static class StackNode {
TreeNode tn;
boolean leftDone;
boolean rightDone;
public StackNode(TreeNode tn) {
this.tn = tn;
}
}
private static String getLabelList(Stack<StackNode> in) {
String result = "";
for (StackNode node : in) {
if (result.length() > 0) {
result += ", ";
}
result += node.tn.label;
}
//System.out.print("getLabelList: " + result);
return result;
}
private static TreeNode makeTree() {
TreeNode l;
TreeNode r;
l = new TreeNode(4, null, null);
r = new TreeNode(7, null, null);
r = new TreeNode(6, l, r);
l = new TreeNode(1, null, null);
l = new TreeNode(3, l, r);
r = new TreeNode(14, new TreeNode(13, null, null), null);
r = new TreeNode(10, null, r);
return (new TreeNode(8, l, r));
}
}
class StackNode {
TreeNode current;
boolean leftSubtreeDone;
}
class TreeNode {
int label;
TreeNode left;
TreeNode right;
public TreeNode(int label, TreeNode left, TreeNode right) {
this.label = label;
this.left = left;
this.right = right;
}
}