非递归遍历的实现需要借助“栈”后进先出的特性来保存节点的顺序,前序、中序、后序是相对于根节点而言,根据根节点输出的位置,根、左、右为前序遍历;左、根、右为中序遍历;左、右、根为后序遍历。
1) 前序遍历(PreOrder):
1.先根节点设为当前节点进行访问
2.将当前节点入栈,并将其写入list,循环将左节点入栈,直到左节点为空,
3.访问栈顶元素,如果栈顶元素存在右孩子,将右孩子设为当前节点,继续第二步,
4.重复第2,3步,直到栈和当前节点都为空
对每个结点,都是先遍历其本身,再遍历左子树,所以当从栈中取出该结点的时候,可以确保其本身和左子树已经被访问过了,只需要访其右结点即可。
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode node = root;
while(node != null || !stack.isEmpty()) {
if(node != null) {
stack.push(node);
list.add(node.val);
node = node.left;
}else {
node = stack.pop();