本來遍歷用遞歸是一個非常簡單的事情,但是偏偏某書喜歡用非遞歸寫,真傷腦筋。剛開始的時候,覺得不就是把函數換成棧麼,簡單吶。結果,換了一天硬是沒有寫出來。抄書上的代碼,居然沒看懂。真是服了。後來從簡書上找到一篇文章,得到了一個非常簡單的非遞歸寫法,當然,簡單是有代價的。
原代碼用C++寫的,這裏換成Java。
使用一個輔助的Pair
相當巧妙的簡化了代碼
幾種遍歷的代碼
public static void preOrderNonRecursive_v3(BinaryTreeNode root) {
if (root == null) return;
Stack<Pair<BinaryTreeNode, Boolean>> stack = new Stack<>();
stack.push(new Pair<>(root, false));
boolean visited;
while(!stack.isEmpty()){
root = stack.peek().first;
visited = stack.peek().second;
stack.pop();
if(root==null) continue;
if(visited) System.out.print(root.data+" ");
else{
stack.push(new Pair<>(root.right,false));
stack.push(new Pair<>(root.left,false));
stack.push(new Pair<>(root, true));
}
}
}
public static void inOrderNonRecursive_v3(BinaryTreeNode root) {
if (root == null) return;
Stack<Pair<BinaryTreeNode, Boolean>> stack = new Stack<>();
stack.push(new Pair<>(root, false));
boolean visited;
while(!stack.isEmpty()){
root = stack.peek().first;
visited = stack.peek().second;
stack.pop();
if(root==null) continue;
if(visited) System.out.print(root.data+" ");
else{
stack.push(new Pair<>(root.right,false));
stack.push(new Pair<>(root, true));
stack.push(new Pair<>(root.left,false));
}
}
}
public static void postOrderNonRecursive_v3(BinaryTreeNode root) {
if (root == null) return;
Stack<Pair<BinaryTreeNode, Boolean>> stack = new Stack<>();
stack.push(new Pair<>(root, false));
boolean visited;
while(!stack.isEmpty()){
root = stack.peek().first;
visited = stack.peek().second;
stack.pop();
if(root==null) continue;
if(visited) System.out.print(root.data+" ");
else{
stack.push(new Pair<>(root, true));
stack.push(new Pair<>(root.right,false));
stack.push(new Pair<>(root.left,false));
}
}
}
Pair
的結構
private static class Pair<T,U>{
T first;
U second;
public Pair(T first, U second) {
this.first = first;
this.second = second;
}
}
簡單的TreeNode
public class BinaryTreeNode {
private int data;
private BinaryTreeNode left;
private BinaryTreeNode right;
public BinaryTreeNode(int data) {
this.data = data;
}
public BinaryTreeNode(int data, BinaryTreeNode left, BinaryTreeNode right) {
this.data = data;
this.left = left;
this.right = right;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(data)
.append("(")
.append(left == null ? null : left.data)
.append(",")
.append(right == null ? null : right.data)
.append(")");
return builder.toString();
}