二叉树的层序遍历

二叉树的层序遍历要求从上到下,从左到右遍历整颗树;

 

这里提供两种解法,都是使用单队列。

二叉树的定义如下:

// C++
//Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

解法一:

        使用 nullptr 分割不同层的节点。具体做法是先入队一个空指针,再入队头节点,每次检测到 nullptr 就意味着到了新的一层,这时抛出这个 nullptr, 然后在队尾入队一个 nullptr;否则就访问队列头元素并将队列头元素的所有孩子入队。代码如下:

// C++
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> vecOfAns;
        if (!root)  return vecOfAns;            // 树为空,返回空容器

        queue<TreeNode*> queueOfNode;
        TreeNode* p = nullptr;
        int level = -1;                         // 层号

        queueOfNode.push(nullptr);              // 入队一个空指针
        queueOfNode.push(root);                 // 入队头节点
        
        while (queueOfNode.size() != 1) {       // 遍历完树后队列中最后会有一个空指针 nullptr
            p = queueOfNode.front();
            if (p == nullptr) {
                queueOfNode.push(nullptr);      // 使用空指针分割不同的层
                ++level;                        // 层号加1
                vecOfAns.push_back({});         // 新建一个空vector容器
            }
            else {
                vecOfAns[level].push_back(p->val);  // 访问节点
                if (p->left)                       // 入队左右孩子
                    queueOfNode.push(p->left);
                if (p->right)
                    queueOfNode.push(p->right);
            }
            queueOfNode.pop();
        }
        return vecOfAns;
    }
};

时间复杂度:O(n) : 每个节点访问一遍

解法二:

        解法二是每次统计队列中的元素个数,这个元素个数也是本层或者说下层节点的数量,然后在一个 for 循环中访问这些节点,每次 for 循环访问本层所有节点。代码如下:

// C++
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> queueOfNode;
        vector<vector<int>> vecOfAns;  

        if(root == nullptr) return vecOfAns;

        queueOfNode.push(root);
        while( !queueOfNode.empty() ) {                     // 队列非空
            int size = queueOfNode.size();                  // 树本层的节点数
            vector<int> tmp;                                // 存储本层的遍历序列
            for(int i =0; i < size; ++i) {                  // 访问本层的所有节点
                TreeNode* ptrTmp = queueOfNode.front();     // 取出队列头元素
                queueOfNode.pop();                          // 抛出队列头元素
                tmp.push_back(ptrTmp->val);                 // 访问节点
                if(ptrTmp->left != nullptr)                 // 入队左右孩子
                    queueOfNode.push(ptrTmp->left);
                if(ptrTmp->right != nullptr) 
                    queueOfNode.push(ptrTmp->right);
            }
            vecOfAns.push_back(tmp);                        // 本层遍历序列入 vector
        }
        return vecOfAns;
    }
};

时间复杂度:O(n) : 不得不说,在力扣上算法二比算法一快,同时说明,算法二参考自力扣

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值