再帰を実行しない場合は、呼び出しが行われた場所または再帰ソリューションのローカル変数によって暗示される種類のデータをスタックに明示的に格納する必要があります。この場合、いくつかのブール値を使用して、左側のサブツリーが実行されたかどうか、および右側のサブツリーが実行されたかどうかを示しました。
すべてを1つの方法で行うことはできませんでした。別の方法を使用して、スタックからノードラベルのリストを抽出します。また、別のラベルリストを持ち歩く手間を省くために、厳密にはスタックとして扱っていません。厳密なスタックにするための変更はかなり明白だと思います。コアコードにコメントしただけです。他に不明な点がないか、お気軽にお問い合わせください。
これは私がお勧めするデザインではないことを強調したいと思います。再帰を使用すると、コードが単純になると思います。私もそれを磨くのに多くの時間を費やしていません。
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;
}
}