本例使用Java語言來編寫無遞歸的二叉樹中序遍歷
實現方式:使用Stack保存父節點,使用一個HashSet來標記遍歷過的節點,防止在遍歷左子樹時重複遍歷。
樹的節點
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){ val = x; }
}
包含中序遍歷方法的類
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
public class RangeSumBST {
public static TreeNode tree;
public static void print(){
// 使用棧來保存父節點
Set<TreeNode> set = new HashSet<>();
Stack<TreeNode> stack = new Stack();
// 防止root被改變
TreeNode currNode = tree;
stack.push(currNode);
// 只要棧中還有節點就說明還有元素未被遍歷
while (!stack.isEmpty() && currNode != null){
// 先遍歷當前節點到最左的葉節點,遇到曾經遍歷過的節點時也終止遍歷
if (currNode.left != null){
while (currNode.left != null && !set.contains(currNode.left)){
stack.push(currNode.left);
currNode = currNode.left;
}
}
// 輸出當前節點的值,該節點的左葉節點已經遍歷完成了
currNode = stack.pop();
System.out.print(currNode.val + " ");
//已經被輸出(取值)過的節點添加進HashSet中,以便不被重複遍歷
set.add(currNode);
// 如果當前節點有右節點,當前節點跳到前節點的右節點上
if(currNode.right != null){
stack.push(currNode.right);
currNode = currNode.right;
}
}
}
}
測試類及輸出
import org.junit.Before;
import org.junit.Test;
public class RangeSumBSTTest {
@Before
public void init(){
RangeSumBST.tree = new TreeNode(10);
RangeSumBST.tree.left = new TreeNode(5);
RangeSumBST.tree.right = new TreeNode(15);
RangeSumBST.tree.left.left = new TreeNode(3);
RangeSumBST.tree.left.left.left = new TreeNode(1);
RangeSumBST.tree.left.left.left.left = new TreeNode(0);
RangeSumBST.tree.left.right = new TreeNode(7);
RangeSumBST.tree.left.right.right = new TreeNode(8);
RangeSumBST.tree.right.right = new TreeNode(18);
}
@Test
public void fun(){
RangeSumBST.print();
}
}
Output: 0 1 3 5 7 8 10 15 18