[LeetCode] Binary Tree Level Order Traversal 二叉树层次遍历(DFS | BFS)

目录:
1.Binary Tree Level Order Traversal - 二叉树层次遍历 BFS
2.Binary Tree Level Order Traversal II - 二叉树层次遍历从低往高输出 BFS
3.Maximum Depth of Binary Tree - 求二叉树的深度 DFS
4.Balanced Binary Tree - 判断平衡二叉树 DFS
5.Path Sum - 二叉树路径求和判断DFS


题目概述:
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
For example:
Given binary tree {3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

return its level order traversal as:

[
  [3],
  [9,20],
  [15,7]
]

Here's an example:

   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".


题目分析:
        本题考查的就是二叉树的层次遍历,需要注意的是二叉树用数组的表示方法,二叉树的每层是从左到右存入数组的。方法包括:
        1.层次遍历。二维数组存储数字和深度,输出二维数组即可,过于复杂。
        2.通过队列BFS广度优先搜索。
        3.通过DFS深度优先搜索实现。

我的代码:

/**
 * 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:
    //二叉树层次遍历 通过队列BFS广度优先搜索
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> result;
        queue<TreeNode*>q;            
        vector<int> level;       //每层结果
        int size,i;
        TreeNode* p;
        
        if(root==NULL) return result;
        q.push(root);            //入队
        while(!q.empty()) {
            //队列中有几个元素就依次遍历每个元素的左右结点
            level.clear();
            size=q.size();
            for(i=0; i<size; i++) {
                p=q.front();     //队首元素值赋给p
                q.pop();         //出队
                level.push_back(p->val);
                if(p->left) {    //依次压入左右结点元素
                    q.push(p->left);
                }
                if(p->right) {
                    q.push(p->right);
                }
            }
            result.push_back(level);   //添加每层数据
        }
        return result;
    }
};


代码详解:
        该题目你如果采用C语言二维数组过于复杂,故采用C++的容器vector实现。同时BFS广度优先搜索采用队列queue实现,常见方法如下(参考地址):
        1.栈操作

#include<stack>         头文件
stack<int> s            定义栈
s.empty()               如果栈为空返回true,否则返回false  
s.size()                返回栈中元素的个数  
s.pop()                 删除栈顶元素但不返回其值  
s.top()                 返回栈顶的元素,但不删除该元素  
s.push()                在栈顶压入新元素  
        2.队列操作
#include<queue>         头文件
queue<int> q            定义队列
q.empty()               如果队列为空返回true,否则返回false  
q.size()                返回队列中元素的个数  
q.pop()                 删除队列首元素但不返回其值  
q.front()               返回队首元素的值,但不删除该元素  
q.push()                在队尾压入新元素  
q.back()                返回队列尾元素的值,但不删除该元素  
        3.二叉树层次遍历如何使用队列
        由于二叉树是从左至右进行输入,故层次遍历通过队列存储每层的结点,它存储的顺序也是前一个结点的左孩子结点、右孩子结点,依次顺序进出队列。

        DFS代码参考地址:LeetCode Binary Tree Level Order Traversal


其他题目:
Binary Tree Level Order Traversal II
        层次遍历从低往root结点输出,如 
Given binary tree {3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

          return its level order traversal as:

[
  [15,7],
  [9,20],
  [3]
]
        最简单方法通过层次遍历BFS调用队列后逆序倒置vector容器即可。
/**
 * 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>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>> result;
        vector<int> level;
        queue<TreeNode*> q;
        
        if(root==NULL)
            return result;
        q.push(root);
        while(!q.empty()) {
            //层次遍历
            level.clear();
            int size=q.size();
            for(int i=0; i<size; i++) { //注意:不能i<q.size() 当入队时它会变换
                TreeNode* p=q.front();
                q.pop();
                level.push_back(p->val);
                if(p->left)
                    q.push(p->left);
                if(p->right)
                    q.push(p->right);
            }
            //每层结果存入容器
            result.push_back(level);
        }
        /*
         * 逆序输出 倒置容器调用函数
         * reverse(result.begin(),result.end());
         * return result;
         */
        vector<vector<int>>::iterator iter;  //迭代器
        vector<vector<int>> res;
        for(iter=result.end()-1; iter!=result.begin()-1; iter--)
        {
            level.clear();
            for(int i=0; i<(*iter).size(); i++) //复制每层内容
            {
                level.push_back((*iter)[i]);
            }
            res.push_back(level);
        }
        return res;
    }
};
        PS:如果是每层的也要逆序的话,就把left 和right 入队的顺序调换一下。另一种遍历方法参考:http://www.cnblogs.com/ganganloveu/p/3843470.html
        


Maximum Depth of Binary Tree - 求二叉树的深度
        常见方法通过BFS层次遍历计算二叉树层数及深度或通过DFS计算二叉树从root到leaf结点最长路径及深度,在采用BSF代码中可通过前面代码进行修改,但错误:
                        [0,2,4,1,null,3,-1,5,1,null,6,null,8] output=5 Excepted=4
        故采用DFS进行深度递归搜索。代码如下:
int maxDepth(struct TreeNode* root) {
    if(root == NULL) return 0;
    int left = maxDepth(root->left);
    int right = maxDepth(root->right);
    return (left >= right ? left : right) + 1;
}
        BFS代码参考:http://blog.csdn.net/sunbaigui/article/details/8980887



Balanced Binary Tree - 判断平衡二叉树
        平衡二叉树是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。参考前面的计算深度方法完成。

 int DFS(struct TreeNode* p) {
    if(p==NULL)
        return 0;
    int left=DFS(p->left);
    int right=DFS(p->right);
    return (left>=right?left:right)+1;
 }
//递归判断左右子树结点是否符合平衡二叉树
bool isBalancedNode(struct TreeNode* L,struct TreeNode* R) {
    if(!L&&!R) 
        return true;
    //自定义DFS函数计算结点的深度
    int left=DFS(L);
    int right=DFS(R);
    //平衡二叉树左右结点深度相差0或1
    if(abs(left-right)>1) 
        return false;
    else if(L&&R) //必须存在 否则会报错RE [1,2]时R->left不存在
        return isBalancedNode(L->left,L->right) && isBalancedNode(R->left,R->right);
}
bool isBalanced(struct TreeNode* root) {
    if(root==NULL)
        return true;
    if(root&&!root->left&&!root->right)
        return true;
    else 
        return isBalancedNode(root->left,root->right);
}
        另一种方法参考地址,也可通过后序遍历实现。
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool checkBalance(TreeNode *node, int &dep)
    {
        if (node == NULL)
        {
            dep = 0;
            return true;
        }
        
        int leftDep, rightDep;
        bool leftBalance = checkBalance(node->left, leftDep);
        bool rightBalance = checkBalance(node->right, rightDep);
        
        dep = max(leftDep, rightDep)+1;
        
        return leftBalance && rightBalance && (abs(rightDep - leftDep) <= 1);
    }
    
    bool isBalanced(TreeNode *root) {
        int dep;
        return checkBalance(root, dep);
    }
};



Path Sum - 二叉树路径求和判断

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.For example:
Given the below binary tree and sum = 22,

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \      \
        7    2      1

return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

        该题主要考察DFS或BFS计算root到leaf结点路径求和是否存在一条与sum相等的path。我采用DFS结合计算二叉树深度完成,最初打算自定义isNode(*root,num)函数判断,后来直接通过判断每个结点是否是leaf且值为sum-前面结点。代码如下:
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

//思路:通过DFS计算root-to-leaf的结果
bool hasPathSum(struct TreeNode* root, int sum) {
    if(root==NULL)
        return false;
    else if(root&&!root->left&&!root->right&&root->val==sum)  //仅root结点
        return true;
    else if(root&&!root->left&&!root->right&&root->val!=sum)
        return false;
    else  //包括子结点
        return hasPathSum(root->left,(sum - root->val)) ||
            hasPathSum(root->right,(sum - root->val));
}



(By:Eastmount 2015-9-11 凌晨3点半   http://blog.csdn.net/eastmount/)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于二叉树层次遍历,可以使用队列来实现。首先,将二叉树的根结点入队,然后循环执行以下操作:出队并访问出队结点,如果有左孩子结点,将左孩子结点入队;如果有右孩子结点,将右孩子结点入队。直到队列为空为止。 例如,给定二叉树 [3,9,20,null,null,15,7,按层次遍历的结果为: 3 9 20 15 7 其中,根结点3位于第一层,左孩子结点9和右孩子结点20位于第二层,左孩子结点15和右孩子结点7位于第三层。 这种自顶向下的层次遍历可以通过队列结构来实现,每次出队一个结点,访问该结点,并将其子结点入队,直到队列为空。这样可以保证从叶子节点所在层到根节点所在的层,逐层从左向右遍历。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [leetcode107. 二叉树层次遍历 II](https://download.csdn.net/download/weixin_38551059/13759244)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [二叉树层次遍历](https://blog.csdn.net/qq_44722109/article/details/126292665)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eastmount

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值