102. Binary Tree Level Order Traversal

来源:互联网 发布:ubuntu 界面时钟 编辑:程序博客网 时间:2024/05/16 08:54
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,null,null,15,7],    3   / \  9  20    /  \   15   7return its level order traversal as:[  [3],  [9,20],  [15,7]]

二叉树基本操作,如果只是单纯的输出层序数列,那么一个queue就可以了,每次dequeue一个元素出来接着就把他的左右子树inqueue进去就行。这里要求层与层之间分开保存,所以需要增加些操作,这里提供两种方法,楼主也在之前的一篇博客里介绍过。栈和队列在二叉树遍历里的应用。

方法一:一个queue的实现

一个queue实现的时候,需要对每层的节点计数,从而完成分层的任务。计数的时候不用去按照理论上每层应该有的个数来判断,可以从根节点开始,弹出一个,本层数目减一,同时放进两个左右孩子,下一层数目加2。具体代码如下:
(1) 针对每层计数

vector<vector<int>> levelOrder(TreeNode* root) {    vector<vector<int>> res;    vector<int> temp;    queue<TreeNode*> queuenode;    queuenode.push(root);    int nodesincurlevel = 1;    int nodesinnextlevel = 0;    while (!queuenode.empty()) {        TreeNode* curnode = queuenode.front();        queuenode.pop();        nodesincurlevel--;        if (curnode) {            temp.push_back(curnode->val);            queuenode.push(curnode->left);            queuenode.push(curnode->right);            nodesinnextlevel += 2;        }        if (nodesincurlevel == 0) {        //因为最后一层的时候temp会push进几个NULL,所以这里增加一下判断,否则res最后会有一项空的数组            if (temp.size() > 0) res.push_back(temp);            temp.clear();            nodesincurlevel = nodesinnextlevel;            nodesinnextlevel = 0;        }    }    return res;}

(2)加间隔符
上一种方法里我们通过对每层计数的方法来实现,计数的时候同时计算NULL和实际node,为了保证在下一次检索的时候pop的都是上一层添加的孩子。这里也可以换一种思路,不添加NULL进队列,只添加确实存在的孩子,然后用NULL作为层与层之间的判断。

vector<vector<int>> levelOrder(TreeNode* root) {    vector<vector<int>> res;    vector<int> part;    queue<TreeNode*> queueNode;    queueNode.push(root);    queueNode.push(NULL);    while (!queueNode.empty()) {        TreeNode* temp = queueNode.front();        queueNode.pop();        if (temp) {            part.push_back(temp->val);            if (temp->left) queueNode.push(temp->left);            if (temp->right) queueNode.push(temp->right);        }        else {        //一旦等于NULL意味着一层结束了,开始下一层            if (part.size() > 0) {                res.push_back(part);                part.clear();                queueNode.push(NULL);            }        }    }    return res;}

方法二:两个queue实现

两个queue的话可以把当前的层与下一层分开push,等到当前层存储完成后与下一层交换即可。这里单独写了一个交换的函数,仅供参考。

vector<vector<int>> levelOrder(TreeNode* root) {    vector<vector<int>> res;    vector<int> temp;    queue<TreeNode*> curlevel, nextlevel;    curlevel.push(root);    while (!curlevel.empty()) {        TreeNode* curNode = curlevel.front();        curlevel.pop();        if (curNode) {            temp.push_back(curNode->val);            nextlevel.push(curNode->left);            nextlevel.push(curNode->right);        }        if (curlevel.empty()) {            if (temp.size() > 0) res.push_back(temp);            temp.clear();            swap(curlevel, nextlevel);        }    }    return res;}void swap(queue<TreeNode*>& curlevel, queue<TreeNode*>& nextlevel) {    while (!nextlevel.empty()) {        TreeNode* temp = nextlevel.front();        nextlevel.pop();        curlevel.push(temp);    }}

方法三:递归实现

在递归的时候纳入层的概念,不同层在res里的不同子序列中讨论。

vector<vector<int>> levelOrder(TreeNode* root) {    vector<vector<int>> res;    helper(root, res, 0);    return res;}void helper(TreeNode* root, vector<vector<int>>& res, int level) {    if (root == NULL) return;    //如果是讨论的层数还没在res中开辟内存,则新建一个数组作为这一层的存储    if (res.empty() || level > res.size() - 1) {        res.push_back(vector<int>());    }    res[level].push_back(root->val);    levelOrder(root->left, res, level+1);    levelOrder(root->right, res, level+1);}
1 0
原创粉丝点击