Depth First Search Algorithm to Find Leaves of a Binary Tree

  • 时间:2020-09-26 22:11:41
  • 分类:网络文摘
  • 阅读:93 次

Given a binary tree, collect a tree’s nodes as if you were doing this: Collect and remove all leaves, repeat until the tree is empty.

Example:
Input: [1,2,3,4,5]

 
          1
         / \
        2   3
       / \     
      4   5    

Output: [[4,5,3],[2],[1]]

complete-binary-tree-1 Depth First Search Algorithm to Find Leaves of a Binary Tree algorithms c / c++ java recursive

Example of a Complete Binary Tree

Explanation:
1. Removing the leaves [4,5,3] would result in this tree:

          1
         / 
        2          

2. Now removing the leaf [2] would result in this tree:

          1          

3. Now removing the leaf [1] would result in the empty tree:

          []         

Finding the leaves is easy, but it is not trivial to remove them and iteratively finding new leaves until the tree is empty. We may however simulate the process, which takes time and this requires somehow a complex piece of implementation.

Depth First Search Algorithm to Find the Binary Tree Leaves

We define a function that recursively computes the distances/depth between any nodes to the leaf nodes. Then we can associate the nodes with its depth. This will be implemented using recursion and the following Java code demonstrates the Depth First Search.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> findLeaves(TreeNode root) {
        List<List<Integer>> r = new ArrayList<List<Integer>>();
        dfs(root, r);
        return r;
    }
    
    private int dfs(TreeNode root, List<List<Integer>> r) {
        if (root == null) return 0; // leave nodes are depth 0.
        // the depth is the max between two branches + 1
        int h = Math.max(dfs(root.left, r), dfs(root.right, r)) + 1;
        if (r.size() < h) {
            r.add(new ArrayList<Integer>());
        }
        r.get(h - 1).add(root.val); // put the 'leave' to its level
        return h;
    }
}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> findLeaves(TreeNode root) {
        List<List<Integer>> r = new ArrayList<List<Integer>>();
        dfs(root, r);
        return r;
    }
    
    private int dfs(TreeNode root, List<List<Integer>> r) {
        if (root == null) return 0; // leave nodes are depth 0.
        // the depth is the max between two branches + 1
        int h = Math.max(dfs(root.left, r), dfs(root.right, r)) + 1;
        if (r.size() < h) {
            r.add(new ArrayList<Integer>());
        }
        r.get(h - 1).add(root.val); // put the 'leave' to its level
        return h;
    }
}

The DFS runs at O(N) time where N is the number of the nodes in the given binary tree. The space complexity is O(N) as well. The following is the C++ implementation of the same algorithm (so the time and space complexity is the same – O(N)).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> findLeaves(TreeNode* root) {
        vector<vector<int>> res;
        dfs(root, res);
        return res;
    }
    
    int dfs(TreeNode* root, vector<vector<int>> &r) {
        if (root == NULL) { // leave nodes are depth 0.
            return 0;
        }
        int lv = dfs(root->left, r);
        int rv = dfs(root->right, r);        
        int h = 1 + max(lv, rv);
        if (h > r.size()) {
            r.push_back({});  // allocate for the new level
        }
        r[h - 1].push_back(root->val);
        return h;        
    }
};
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> findLeaves(TreeNode* root) {
        vector<vector<int>> res;
        dfs(root, res);
        return res;
    }
    
    int dfs(TreeNode* root, vector<vector<int>> &r) {
        if (root == NULL) { // leave nodes are depth 0.
            return 0;
        }
        int lv = dfs(root->left, r);
        int rv = dfs(root->right, r);        
        int h = 1 + max(lv, rv);
        if (h > r.size()) {
            r.push_back({});  // allocate for the new level
        }
        r[h - 1].push_back(root->val);
        return h;        
    }
};

The Depth First Search Algorithm is usually implemented using Recursion where a stack will be generated and maintained by the compiler automatically. You could, however, convert the recursion into the iterative approach by manually operating the stack.

–EOF (The Ultimate Computing & Technology Blog) —

推荐阅读:
曹刿论战原文及翻译  数学题:组成只能被3整除不能被9整除的4位数  数学题:将某款服装按标价打8折出售,仍可盈利10%  数学题:把一根长30cm,底面半径是8cm的圆木平均锯成4段  数学题:甲乙两种皮鞋的原价相同,换季时  奥数题:1994年“世界杯”足球赛中  数学题:如何按照一定的比例把小长方形扩大成与大长方形完全重的图形  问答题:说明学生总数、每辆车载客数、客车数成什么比例  数学题:有一个礼品盒,用彩绳扎成如右图的形状  数学题:客车从甲地到乙地要6小时;货车从乙地到甲地要8小时 
评论列表
添加评论