層次遍歷遞歸和非遞歸方法


層次遍歷遞歸和非遞歸方法

如何遍歷一棵樹

有兩種通用的遍歷樹的策略:

  • 深度優先搜索(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 個節點的值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM