代码随想录二叉树——二叉树的迭代遍历

题目

使用迭代法来实现二叉树的前中后遍历。

递归的实现:每一次递归调用都会把函数的局部变量、参数值、和返回地址等压入调用栈中

注:二叉树的迭代(非递归)需要用(人工)栈实现,即递归需要系统栈实现,迭代(非递归)需要我们自己申请一个栈,只是没让系统帮我们压栈了,也就是说,遍历二叉树,树的高度这个空间(栈的大小)省不掉的,除了Morris遍历(冷门,空间复杂度O(1))。

  1. 前序遍历:中左右

处理顺序:先将根节点入栈,然后将右孩子入栈,再加入左孩子(先右后左出栈才是中左右的顺序)

前序遍历顺序:中-左-右 入栈顺序:中-右-左(因为栈是先进后出)

class Solution {
	public List<Integer> preorderTraversal(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);//添加具体数值用add
			if(node.right != null){//将右孩子入栈
				stack.push(node.right);//添加节点用push	
			}
			if(node.left != null){
				stack.push(node.left);//add()方法返回布尔值,push()方法返回元素值
			}
		}
		return result;
	}
}
  1. 中序遍历:左-中-右 入栈顺序:左-右
//迭代法中序遍历,需要指针的遍历帮助访问节点,栈来处理节点上的元素
class Solution {
	public List<Integer> inorderTraversal(TreeNode root){
		List<Integer> result = new ArrayList<>();
        if(root == null){
			return result;
		}
		Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;//让cur指针指向root,用指针进行遍历访问节点
		while(cur != null || !stack.isEmpty()){
			if(cur != null){//如果cur不为空
				stack.push(cur);//入栈并继续指向左孩子
				cur = cur.left;
			}else {
				cur = stack.pop();//如果没有左孩子,出栈加入遍历数组中
				result.add(cur.val);
				cur = cur.right;//再指向右孩子
			}
		}
		return result;
	}
}
  1. 后序遍历:左-右-中 ,从前序遍历推导得到后序遍历

前序遍历:中左右 → 中右左(把前序遍历代码左右顺序换一下)→左右中(反转,即可得到后序遍历结果)

所以相当于就是改了先序遍历的左右子树的代码顺序,最后多一步反转一下result数组即可。

class Solution {
	public List<Integer> postorderTraversal(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数组
			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;
	}
}

一定要掌握前中后序一种迭代的写法!!
并不因为某种场景的题目一定要用迭代,而是现场面试的时候,面试官看你顺畅的写出了递归,一般会进一步考察能不能写出相应的迭代

你可能感兴趣的:(代码随想录,数据结构,算法,java)