如果您不打算进行递归,则必须将调用完成位置或递归解决方案中的局部变量所暗示的数据类型显式存储在堆栈中。在这种情况下,我使用了几个布尔值来指示左子树是否已完成以及右子树是否已完成。
我不能完全让自己用一种方法来做这一切。我确实使用单独的方法从堆栈中提取节点标签列表。此外,为了节省携带单独的标签列表,我并没有将其严格视为堆栈。我认为使其成为严格堆栈的更改相当明显。我只评论了核心代码。随意询问是否还有其他不清楚的地方。
我确实想强调这不是我推荐的设计。我会使用递归,我认为这会导致更简单的代码。我也没有花很多时间打磨它。
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;
}
}