【二叉树2】逐层遍历一棵二叉树

来源:互联网 发布:程序员穿衣 编辑:程序博客网 时间:2024/05/05 13:40

【问题描述】

对【二叉树1】中建立的二叉树逐层打印,也就是说第一行打印第0层根节点,第二行打印第一层……如此类推。

【举例】

一棵二叉树如下:

打印结果为:


【代码】

编程之美介绍了两种实现,一种是递归,该方法需要一个层数作为参数。

另一种就是如下方法,用两个游标记录树的每一层。

代码仅为该函数的实现,和所需头文件。并且不包含二叉树节点的定义以及main函数的调用

#include <iostream>#include <vector>using namespace std;void PrintBTreeByLevel(BTreeNode *root){if(root==NULL)return;vector<BTreeNode*> vec;vec.push_back(root);int current=0,last=1;while(current<vec.size()){while(current<last){cout<<vec[current]->value<<" ";if(vec[current]->leftchild)//Avec.push_back(vec[current]->leftchild);if(vec[current]->rightchild)//Bvec.push_back(vec[current]->rightchild);++current;}last=vec.size();cout<<endl;}}

做leetcode的时候发现上述代码超出内存限制,主要原因在vector中存放了所有的节点,最好选取queue来存放节点,每次只存放一层。还有leetcode函数输出为一个二维的vector,不是单纯打印,所以稍稍复杂。

有三种思路:

【思路一】用一个NULL做分隔

vector<vector<int> > levelOrder(TreeNode *root) {    // Start typing your C/C++ solution below    // DO NOT write int main() function    vector<vector<int>> levels;    queue<TreeNode *> que;    if (!root)        return levels;    que.push(root);    que.push(NULL);        while(que.front() != NULL) {        vector<int> line;        TreeNode *temp = que.front();        que.pop();        while (temp != NULL) {            line.push_back(temp->val);            if (temp->left)                que.push(temp->left);            if (temp->right)                que.push(temp->right);            temp = que.front();            que.pop();        }                levels.push_back(line);        que.push(NULL);            }    return levels;}

【思路二】申请一个附加容器,存储当前层的下一层,然后将下一层再拷贝回queue

vector<vector<int> > levelOrder(TreeNode *root) {    // Start typing your C/C++ solution below    // DO NOT write int main() function    vector<vector<int>> levels;    queue<TreeNode *> q;    if (!root)        return levels;    q.push(root);    while(!q.empty()) {        vector<int> l;        vector<TreeNode *> temp;        while(!q.empty()) {            TreeNode *p = q.front();            q.pop();            l.push_back(p->val);            if (p->left) temp.push_back(p->left);            if (p->right) temp.push_back(p->right);        }        levels.push_back(l);        for (int i=0; i<temp.size(); i++)            q.push(temp[i]);    }    return levels;}


【思路三】递归的方法,函数travers是一个top-buttom的方法,算法很简单很奇妙,是leetcode上的大牛写的。简单理解一下:

if (level > result.size())

判断result中是否出现过这一层的元素。root='a'时,level=1,result.size()=0,说明遍历到第一层时,result还是空的,所以需要需要push进去一个vector<int>;root=’b'时,level=2,result.size()=1,继续push;root='c'时,level=2,result.size()=2,直接执行后面的语句。

result[level-1].push_back(root->val)

因为result是从0开始的,level是从1开始的,所以需要result[level-1]进行push

vector<vector<int> > levelOrderBottom(TreeNode *root) {    // Start typing your C/C++ solution below    // DO NOT write int main() function    vector<vector<int>> result;    traverse(root, 1, result);    std::reverse(result.begin(), result.end());    return result;}void traverse(TreeNode *root, int level, vector<vector<int>> &result) {    if (!root)        return;    if (level > result.size()) {        vector<int> temp;        result.push_back(temp);    }    result[level-1].push_back(root->val);    traverse(root->left, level+1, result);    traverse(root->right, level+1, result);}



【扩展一】打印一棵二叉树的镜像

只需要交换上述代码中A和B的两段if,也就是先让一个节点的右孩子入栈,再让左孩子入栈,结果如下:

【扩展二】从下到上逐层打印二叉树

可以在正向遍历的结果后加上一句std::reverse(result.begin(),result.end())做反转

原创粉丝点击