剑指offer 32 从上到下打印二叉树(二叉树的层序遍历)、从下到上,之字形遍历

层序遍历(宽度优先遍历BFS)(从上到下):使用双端队列deque

思路:

层序遍历二叉树是典型的广度优先搜索BFS的应用,但是这里稍微复杂一点的是,我们要把各个层的数分开,存到一个二维向量里面,大体思路还是基本相同的,建立一个queue,然后先把根节点放进去,这时候找根节点的左右两个子节点,这时候去掉根节点,此时queue里的元素就是下一层的所有节点,用一个for循环遍历它们,然后存到一个一维向量里,遍历完之后再把这个一维向量存到二维向量里,以此类推,可以完成层序遍历。代码如下:

[cpp]  view plain  copy
  1. /** 
  2.  * Definition of TreeNode: 
  3.  * class TreeNode { 
  4.  * public: 
  5.  *     int val; 
  6.  *     TreeNode *left, *right; 
  7.  *     TreeNode(int val) { 
  8.  *         this->val = val; 
  9.  *         this->left = this->right = NULL; 
  10.  *     } 
  11.  * } 
  12.  */  
  13.   
  14. class Solution {  
  15. public:  
  16.     /** 
  17.      * @param root: A Tree 
  18.      * @return: Level order a list of lists of integer 
  19.      */  
  20.     vector<vector<int>> levelOrder(TreeNode * root) {  
  21.         // write your code here  
  22.         vector<vector<int> >st;  
  23.         deque<TreeNode*>node;//双端队列  
  24.       if (root == NULL)  
  25.             return st;  
  26.           
  27.         node.push_back(root);  
  28.         int len;  
  29.         while(!node.empty())  
  30.         {       
  31.              vector<int>temp;  
  32.              len=node.size();//很重要这一步,不能用empty()测试node是否为空  
  33.             while(len--)  
  34.             {  
  35.               TreeNode*pt=node.front();  
  36.               temp.push_back(pt->val);  
  37.                
  38.               node.pop_front();  
  39.               if(pt->left)  
  40.               node.push_back(pt->left);  
  41.               if(pt->right)  
  42.               node.push_back(pt->right);  
  43.             }  
  44.              st.push_back(temp);  
  45.         }  
  46.         return st;  
  47.     }  
  48.       
  49. };  
层序遍历(宽度优先遍历)(从下到上):使用双端队列deque
从底部层序遍历其实还是从顶部开始遍历,只不过最后存储的方式有所改变

[cpp]  view plain  copy
  1.  /** 
  2.  * Definition of TreeNode: 
  3.  * class TreeNode { 
  4.  * public: 
  5.  *     int val; 
  6.  *     TreeNode *left, *right; 
  7.  *     TreeNode(int val) { 
  8.  *         this->val = val; 
  9.  *         this->left = this->right = NULL; 
  10.  *     } 
  11.  * } 
  12.  */  
  13.   
  14. class Solution {  
  15. public:  
  16.     /** 
  17.      * @param root: A tree 
  18.      * @return: buttom-up level order a list of lists of integer 
  19.      */  
  20.     vector<vector<int>> levelOrderBottom(TreeNode * root) {  
  21.         // write your code here  
  22.         vector<vector<int> >st;  
  23.         deque<TreeNode*>node;//双端队列  
  24.       if (root == NULL)  
  25.             return st;  
  26.         node.push_back(root);  
  27.         int len;  
  28.         while(!node.empty())  
  29.         {       
  30.              vector<int>temp;  
  31.              len=node.size();//很重要这一步,不能用empty()测试node是否为空  
  32.              while(len--)  
  33.             {  
  34.               TreeNode*pt=node.front();  
  35.               temp.push_back(pt->val);  
  36.               node.pop_front();  
  37.               if(pt->left)  
  38.               node.push_back(pt->left);  
  39.               if(pt->right)  
  40.               node.push_back(pt->right);  
  41.             }  
  42.              st.insert(st.begin(),temp);  
  43.         }  
  44.         return st;  
  45.     }  
  46. };  
锯齿形遍历(宽度优先遍历)(使用两个栈)
分析:第一层从左到右遍历、第二层从右到左遍历,第三层从左到右遍历.......

根据其特点我们用到栈的后进先出的特点,这道题我们维护两个栈,相邻两行分别存到两个栈中,进栈的顺序也不相同,一个栈是先进左子结点然后右子节点,另一个栈是先进右子节点然后左子结点,这样出栈的顺序就是我们想要的之字形了,代码如下:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int> > zigzagLevelOrder(TreeNode *root) {
        vector<vector<int> >res;
        if (!root) return res;
        stack<TreeNode*> s1;
        stack<TreeNode*> s2;
        s1.push(root);
        vector<int> out;
        while (!s1.empty() || !s2.empty()) {
            while (!s1.empty()) {
                TreeNode *cur = s1.top();
                s1.pop();
                out.push_back(cur->val);
                if (cur->left) s2.push(cur->left);
                if (cur->right) s2.push(cur->right);
            } 
            if (!out.empty()) res.push_back(out);
            out.clear();
            while (!s2.empty()) {
                TreeNode *cur = s2.top();
                s2.pop();
                out.push_back(cur->val);
                if (cur->right) s1.push(cur->right);
                if (cur->left) s1.push(cur->left);
            }
            if (!out.empty()) res.push_back(out);
            out.clear();
        }
        return res;
    }
};
迭代法(使用队列实现)
层序遍历的思路,但是对偶数层的temp使用reverse函数
[cpp]  view plain  copy
  1. /** 
  2.  * Definition of TreeNode: 
  3.  * class TreeNode { 
  4.  * public: 
  5.  *     int val; 
  6.  *     TreeNode *left, *right; 
  7.  *     TreeNode(int val) { 
  8.  *         this->val = val; 
  9.  *         this->left = this->right = NULL; 
  10.  *     } 
  11.  * } 
  12.  */  
  13.   
  14. class Solution {  
  15. public:  
  16.     /** 
  17.      * @param root: A Tree 
  18.      * @return: A list of lists of integer include the zigzag level order traversal of its nodes' values. 
  19.      */  
  20.     vector<vector<int>> zigzagLevelOrder(TreeNode * root) {  
  21.         // write your code here  
  22.         vector<vector<int> >st;  
  23.        deque<TreeNode*>node;  
  24.       
  25.       if (root == NULL)  
  26.             return st;  
  27.         node.push_back(root);  
  28.        bool count=true;  
  29.          vector<int>temp;  
  30.          int len;  
  31.         while(!node.empty())  
  32.         {       
  33.             len=node.size();  
  34.             while(len--)  
  35.             {  
  36.                 TreeNode*pt=node.front();  
  37.                 temp.push_back(pt->val);  
  38.                 node.pop_front();  
  39.                 if(pt->left)  
  40.                 node.push_back(pt->left);  
  41.                 if(pt->right)  
  42.                 node.push_back(pt->right);  
  43.            }  
  44.              if(!count)    
  45.              reverse(temp.begin(),temp.end());  
  46.              //对temp使用reverse函数,一种比较简便的方法  
  47.              count=!count;  
  48.            st.push_back(temp);  
  49.            temp.clear();  
  50.          }  
  51.         return st;  
  52.     }  
  53. };  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值