二叉树遍历系列总结+递归/迭代的统一写法

本文详细介绍了二叉树的前中后序遍历的递归和迭代统一实现,包括深度优先搜索(DFS)和广度优先搜索(BFS)策略。递归解法简洁但易受栈溢出限制,而迭代解法通过显式栈模拟递归,适用于深度较大的树。文章强调了迭代统一版本的重要性,并提供了复杂度分析。
摘要由CSDN通过智能技术生成

本文提供二叉树 前中序 三种遍历方式的 递归和迭代 统一写法。递归写法很简单
在面试中不足以获得面试官的青睐,应该重点掌握迭代写法

一、题目

144. 二叉树的前序遍历
94 . 二叉树的中序遍历
145. 二叉树的后序遍历
在这里插入图片描述

二、分析:DFS/BFS 与树的遍历

  • 有两种通用的遍历树的策略:

    • 深度优先搜索(DFS)

      在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,
      然后再返回根到达另一个分支。

      深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序
      被细分为前序遍历,中序遍历和后序遍历

    • 宽度优先搜索(BFS)

      我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。
      对应数的层次(层序遍历)

  • *****五星重点

    • 前中后序遍历的递归和迭代写法 本质上对应DFS的递归写法和显示调用栈的写法
    • 递归解决方案的优点是它更容易实现。 但是,存在一个很大的缺点:如果递归的深度太高,你将遭受堆栈溢出。 在这种情况下,推荐使用显式栈实现 DFS(有时也可以用BFS)。
    • 显式栈实现 DFS逻辑与递归解决方案完全相同。 但我们使用 while 循环和栈来模拟递归期间的系统调用栈
    • DFS的两种方式的解题模板参考:深度优先搜索DFS_图文详解_Java代码_leetcode刷题模板
    • DFS模板I—递归写法
      /*
      * Return true if there is a path from cur to target.
      */
      boolean DFS(Node cur, Node target, Set<Node> visited) {
             
         return true if cur is target;
         for (next : each neighbor of cur) {
             
             if (next is not in visited) {
             
                 add next to visted;
                 return true if DFS(next, target, visited) == true;
             }
         }
         return false;
      }
      
    • DFS模板II—显示调用栈写法
       /*
       * Return true if there is a path from cur to target.
       */
       boolean DFS(int root, int target) {
             
          Set<Node> visited;
          Stack<Node> s; //额外注意:BFS 这里使用的是queue队列。
          add root to s;
          while (s is not empty) {
             
              Node cur = the top element in s;
              return true if cur is target;
              for (Node next : the neighbors of cur) {
             
                  if (next is not in visited) {
             
                      add next to s;
                      add next to visited;
                  }
              }
              remove cur from s;
          }
          return false;
      }
      

在这里插入图片描述

链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/er-cha-shu-de-qian-xu-

三、递归的写法

递归写法只需要调整list添加节点值 和 左右子树递归的顺序即可
前序: 根 左 右 :list.add(root.val) -> dfs(左子树) -> dfs(右子树)
中序: 左 根 右 :dfs(左子树) -> list.add(root.val) -> dfs(右子树)
后序: 左 右 根 :dfs(左子树) -> dfs(右子树) -> list.add(root.val)

  • 1.前序遍历
    class Solution {
         
        public List<Integer> preorderTraversal(TreeNode root) {
         
            //创建list
            List<Integer> res = new ArrayList();
            
            //递归调用
            dfs(root,res);
            
    		//返回结果
            return res;
        }
        
        private void dfs(TreeNode root, List<Integer> list){
         
            
            if(root != null ){
         
            	//1.先添加root值
                list.add(root.val);
               
                //2.递归左子树
                dfs(root.left,list);
    
      			//3.递归右子树
                dfs(root.right,list);
            }
    		
    		/* 【另一种写法】
            
            //递归终止条件, base case
            if(root == null) return;
    
            //先遍历根节点,  直接添加节点值
            list.add(root.val);//前序遍历 根 左  右
    
            //递归左子树
            //if(root.left != null)
            recur(root.left,list);
    
            //递归右子树
            //if(root.right != null) 
            recur(root.right,list);
    
    		*/
        }
    }
    
  • 2.中序遍历
    class Solution {
         
        public List<Integer> inorderTraversal(TreeNode root) {
         
            //创建list
            List<Integer> res = new ArrayList();
            
            //递归调用
            dfs
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值