递归形式的遍历都会有一个递归栈,因此对于非递归形式也可以使用一个栈来模拟递归栈来保存过程中的变量。
前序遍历
public List<Integer> preOrderTraverse(TreeNode root) {
// 保存前序遍历结果
List<Integer> result = new ArrayList<>();
if(root == null) return result;
// 模拟递归栈
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
result.add(node.val);
// 这里先判断右孩子,然后判断左孩子
if(node.right != null) stack.push(node.right);
if(node.left != null) stack.push(node.left);
}
return result;
}
中序遍历
public List<Integer> inOrderTraverse(TreeNode root) {
// 保存遍历结果
List<Integer> result = new ArrayList<>();
if(root == null) return result;
// 模拟栈
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
while(node != null || !stack.isEmpty()) {
while(node != null) {
stack.push(node);
node = node.left;
}
if(!stack.isEmpty()) {
node = stack.pop();
result.add(node.val);
node = node.right;
}
}
return result;
}
后序遍历
public List<Integer> postOrderTraverse(TreeNode root) {
// 后序遍历的结果
List<Integer> result = new ArrayList<>();
if(root == null) return result;
// 模拟栈
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
// 这里其实是逆序的后序遍历结果,也就是先->右->左,遍历完成之后反转一下就是最终的结果
result.add(node.val);
// 先放 左 后放 右 ,后面取的时候就是 先取右 再取左
if(node.left != null) stack.push(node.left);
if(node.right != null) stack.push(node.right);
}
Collections.reverse(result);
return result;
}