代码随想录算法训练营第42期 第十三天| 144、145、94前后中序递归遍历 及迭代遍历,102层序遍历

进入到二叉树章节了,今天学习了前中后序的递归遍历及迭代遍历。先了解三种遍历的规则

前序遍历:中左右

中序遍历:左中右

后序遍历:左右中

一、递归遍历

大家递归应该很了解了。写一个递归要遵循三步走战略,第一确定参数和返回值,第二确定终止条件,第三确定单层递归的逻辑。递归感悟:递归最喜欢处理的就是问题能处理成无数个子问题的题型(这句话,很重要,大家写题感悟一下)

// 前序遍历·递归·LC144_二叉树的前序遍历
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        preorder(root, result);
        return result;
    }

    public void preorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        result.add(root.val);
        preorder(root.left, result);
        preorder(root.right, result);
    }
}
// 中序遍历·递归·LC94_二叉树的中序遍历
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        inorder(root, res);
        return res;
    }

    void inorder(TreeNode root, List<Integer> list) {
        if (root == null) {
            return;
        }
        inorder(root.left, list);
        list.add(root.val);             // 注意这一句
        inorder(root.right, list);
    }
}
// 后序遍历·递归·LC145_二叉树的后序遍历
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        postorder(root, res);
        return res;
    }

    void postorder(TreeNode root, List<Integer> list) {
        if (root == null) {
            return;
        }
        postorder(root.left, list);
        postorder(root.right, list);
        list.add(root.val);             // 注意这一句
    }
}

二、迭代遍历 

递归是栈底层实现的,基本上递归的问题都可以用栈来解决。这次就放前序和中序,后序和前序思路差不多,只不过要进行代码调整位置和反转

前序遍历:

思路:先放入根节点,由于栈的先进后出的特性,弹出这个节点加入结果集,先放右节点再放左节点,然后循环往复就行了,大家模拟一下就知道思路了。

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {

		List<Integer> result=new ArrayList<>();
		if (root == null){
			return result;
		}
		Deque<TreeNode> record=new LinkedList<>();
		record.push(root);
		while(!record.isEmpty()){
			TreeNode temp=record.pop();
				result.add(temp.val);

			if(temp.right!=null)record.push(temp.right);
			if(temp.left!=null)record.push(temp.left);
		}
		return result;


	}

}

中序遍历 :

思路:这道题由于遍历二叉树的顺序不是要处理的顺序,最好用cur另外存储遍历顺序,然后栈记录节点,方便cur进行操作

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
           List<Integer> result=new ArrayList<>();
		   if(root==null)return result;
		   TreeNode cur=root;
		   Deque<TreeNode> stack=new LinkedList<>();
		   while(cur!=null||!stack.isEmpty()){
			   if(cur!=null){
				   stack.push(cur);
				   cur=cur.left;
			   }else{
				   cur=stack.pop();
				   result.add(cur.val);
				   cur=cur.right;
			   }
		   }
		   return 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.add(node.val);
			if (node.left != null){
				stack.push(node.left);
			}
			if (node.right != null){
				stack.push(node.right);
			}
		}
		Collections.reverse(result);
		return result;
	}
}

三、层序遍历

层序遍历就是一层一层遍历,一层的遍历规则是从左往右。

思路:这道题要用队列解,先放入根节点,记录当前层的size,然后poll出头元素放入结果中,然后左右节点不为空的话就入队列,这样持续到size<=0,然后进行下一层遍历,持续这样,直到队列为空。这道题要注意的是temp一定要在while新创建,而不能在一层遍历结束后清空,因为链表添加的是地址,当temp改变的时候,链表存的元素也会改变,造成结果错误

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
			if(root==null)return new ArrayList<>();
			List<List<Integer>> result=new ArrayList<>();
			Deque<TreeNode> record=new LinkedList<>();

			int size=1;
			record.offer(root);
			while(!record.isEmpty()){
				List<Integer> temp=new ArrayList<>();
				while(size-->0){
					TreeNode cur=record.poll();
					if(cur.left!=null) {
						record.offer(cur.left);
					}
					if(cur.right!=null){
						record.offer(cur.right);
					}
					temp.add(cur.val);
				}
				result.add(temp);
				size=record.size();
			}
			return result;
    }
}

 

  • 17
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值