层次遍历递归和非递归方法

层次遍历递归和非递归方法

如何遍历一棵树

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

  • 深度优先搜索(DFS)

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

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

  • 宽度优先搜索(BFS)

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

下图中的顶点按照访问的顺序编号,按照 1-2-3-4-5 的顺序来比较不同的策略。

层次遍历可以采用两种方法递归和迭代:

方法1:递归

算法

最简单的解法就是递归,首先确认树非空,然后调用递归函数 helper(node, level),参数是当前节点和节点的层次。程序过程如下:

输出列表称为 levels,当前最高层数就是列表的长度 len(levels)。比较访问节点所在的层次 level 和当前最高层次 len(levels) 的大小,如果前者更大就向 levels 添加一个空列表。

将当前节点插入到对应层的列表 levels[level] 中。

递归非空的孩子节点:helper(node.left / node.right, level + 1)

class Solution {
    List<List<Integer>> levels = new ArrayList<List<Integer>>();

    public void helper(TreeNode node, int level) {
        // start the current level
        if (levels.size() == level)
            levels.add(new ArrayList<Integer>());

         // fulfil the current level
         levels.get(level).add(node.val);

         // process child nodes for the next level
         if (node.left != null)
            helper(node.left, level + 1);
         if (node.right != null)
            helper(node.right, level + 1);
    }

    public List<List<Integer>> levelOrder(TreeNode root) {
        if (root == null) return levels;
        helper(root, 0);
        return levels;
    }
}

复杂度分析

时间复杂度:O(N)O(N)O(N),因为每个节点恰好会被运算一次。

空间复杂度:O(N)O(N)O(N),保存输出结果的数组包含 N 个节点的值。

方法2:迭代

算法

上面的递归方法也可以写成迭代的形式。

我们将树上顶点按照层次依次放入队列结构中,队列中元素满足 FIFO(先进先出)的原则。在 Java 中可以使用 Queue 接口中的 LinkedList实现。

第 0 层只包含根节点 root ,算法实现如下:

  • 初始化队列只包含一个节点 root 和层次编号 0 : level = 0。
  • 当队列非空的时候:

在输出结果 levels 中插入一个空列表,开始当前层的算法。

计算当前层有多少个元素:等于队列的长度。

将这些元素从队列中弹出,并加入 levels 当前层的空列表中。

将他们的孩子节点作为下一层压入队列中。

进入下一层 level++。

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

    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.add(root);
    int level = 0;
    while ( !queue.isEmpty() ) {
      // start the current level
      levels.add(new ArrayList<Integer>());

      // number of elements in the current level
      int level_length = queue.size();
      for(int i = 0; i < level_length; ++i) {
        TreeNode node = queue.remove();

        // fulfill the current level
        levels.get(level).add(node.val);

        // add child nodes of the current level
        // in the queue for the next level
        if (node.left != null) queue.add(node.left);
        if (node.right != null) queue.add(node.right);
      }
      // go to next level
      level++;
    }
    return levels;
  }
}

复杂度分析

时间复杂度:O(N)O(N)O(N),因为每个节点恰好会被运算一次。

空间复杂度:O(N)O(N)O(N),保存输出结果的数组包含 N 个节点的值。

原文地址:https://www.cnblogs.com/kexinxin/p/11745764.html

时间: 2024-10-12 12:47:38

层次遍历递归和非递归方法的相关文章

二叉树遍历递归与非递归实现

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 二叉树遍历是二叉树中非常基础的部分,也是学习二叉树必须熟练掌握的部分,下面我们先给出二叉树三种遍历方式的定义,并通过举例来说明二叉树遍历的过程. 二叉树的遍历分为:前序遍历(也叫先序遍历).中序遍历.后序遍历.所谓前.中.后都是根据当前子树根结点相对左右孩子的位置而言,也就是说: 前序遍历:根结点在前,即:根 ----->左------->右: 中序遍历:根结点在中间,即:左------>根------>右: 后序遍历:根结点在最

中序遍历 递归与非递归

1 /** 2 * Definition for binary tree 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Solution { 11 12 public List<Integer> inorderTraversal(TreeNode root) {

图的深度优先搜索(DFS)简介与实现(递归与非递归方法)

上一篇刚刚学习了C++图的实现,今天对深度优先搜索(DFS)进行了一定学习,并作出一定实现.在本文中图的实现,以及相应的函数调用(如获得第一个邻接顶点.获得下一个邻接顶点等)均是基于上文中的实现,故如果想参考测试代码,还需导入上文中相应的类定义.关于C++图的实现可参考此处,这里实现了对图的邻接表以及邻接矩阵两种实现,而本文的深度优先搜索对于上面两种实现均是可行的. 当然,对于图的深度优先搜索的相关定义,本文也不再过多赘述,维基的解释应该就足够,下面将探讨其实现. 1.深度优先搜索的非递归实现:

二叉树三种遍历递归及非递归实现(Java)

import java.util.Stack; //二叉树三种遍历递归及非递归实现(Java) public class Traverse { /******************定义二叉树**************************/ private final int MAX_SIZE = 10; //链式存储 public static class BinaryTreeNode { int mValue; BinaryTreeNode mLeft; BinaryTreeNode

二叉树的遍历(递归、非递归)

理论: 1.先(根)序遍历的递归定义: 若二叉树非空,则依次执行如下操作: ⑴ 访问根结点: ⑵ 遍历左子树: ⑶ 遍历右子树. 2.中(根)序遍历的递归算法定义: 若二叉树非空,则依次执行如下操作: ⑴遍历左子树: ⑵访问根结点: ⑶遍历右子树. 3.后(根)序遍历得递归算法定义: 若二叉树非空,则依次执行如下操作: ⑴遍历左子树: ⑵遍历右子树: ⑶访问根结点 java实现 package 二叉树; import java.util.ArrayList; import java.util.L

采用先序遍历 和层次遍历递归建立二叉树--进行封装

1 package com.offer; 2 3 public class TreeNode { 4 5 int val = 0; 6 TreeNode left = null; 7 TreeNode right = null; 8 9 public TreeNode(int val) 10 { 11 this.val=val; 12 } 13 14 public TreeNode() 15 { 16 CreateBinaryTree();// 采用默认的 17 //preShow(this.r

java 树的遍历(递归与非递归)

package wangChaoPA实习工作练习.com.leetcode;import java.util.ArrayList;import java.util.Stack;class TreeNode{    TreeNode left;    TreeNode right;    int val; TreeNode(int x)    {        val = x;    }}public class TreeTrivel{    // 测试    public static void

递归和非递归方法得到某文件夹中的全部文件和文件夹

/*******************************************************递归实现***************************************************/ /** * 获取某文件夹的所有文件 * @param filePath 获取文件的文件夹路径 * @param myFiles 保存文件的文件集合 * @return  所有的文件及文件夹 * @throws IOException */ public static Arr

【分治】快速幂运算-递归与非递归方法

问题 Q: [分治]快速幂运算 时间限制: 1 Sec  内存限制: 128 MB提交: 14  解决: 9[提交][状态][讨论版] 题目描述 邪狼:“老大,好像还是不够油钱啊?”修罗王:“看来只好用我的独门绝技----能力增持术了.”邪狼:“听说能量增持数很霸道的?”修罗王:“没错,假设初始燃油能提供的能量为X,当我对它进行能量增持n秒后,该然后的能量将达到Xn”邪狼:“这么强大的技能啊,简直逆天了,不过怎么之前不见老大用过?”修罗王:“偶尔偷偷用几次没关系,经常用,燃油公司会找我麻烦的.”