leetcode103. 蛇形打印二叉树/锯齿形层次遍历

BFS

层级遍历+蛇形输出

思路:
1、使用广度优先遍历,将二叉树所有节点存放于一个双端队列中。
2、使用分隔符(空节点)将层级分离。
3、使用bool控制每一行的输出顺序即可。
leetcode103. 蛇形打印二叉树/锯齿形层次遍历_第1张图片
执行用时:8 ms
内存消耗:11.5 MB

/**
 * 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:
    void BFS(deque<TreeNode*>& deq, int& index)
    {
     
        while (index < deq.size())
        {
     
            TreeNode* cur = deq[index];
            if (cur == nullptr && index == deq.size()-1)
                return;
            else if(cur == nullptr)
                deq.push_back(nullptr);
            else
            {
     
                if (cur->left) 
                    deq.push_back(cur->left);
                if (cur->right) 
                    deq.push_back(cur->right);
            }
            index++;
        }
    }
    void toVector(deque<TreeNode*>& deq,vector<vector<int>>& ret)
    {
     
        if(deq.size() <= 0) return;
        bool forwardPrintf = true;

        int index1 = 0;
        int index2 = 0;
        vector<int> vLayer;
        while (index1 < deq.size()|| index2 < deq.size())
        {
     
            auto cur =  deq[index2];
            if (cur == nullptr)//翻转打印方向
            {
     
                if(forwardPrintf)
                    ret.push_back(vLayer);
                else
                {
     
                    int temp = index2 - 1;
                    while (index1 - 1 < temp)
                    {
     
                        vLayer.push_back(deq[temp]->val);
                        temp--; 
                    }
                    ret.push_back(vLayer);
                }
                
                vLayer.clear();
                index1 = index2;
                index1++;
                index2++;
                forwardPrintf = !forwardPrintf;
            }
            else if (forwardPrintf)//直接打印
            {
     
                vLayer.push_back( cur->val);
                index1++;
                index2++;
            }
            else//index2先行
            {
     
                index2++;
            }
        }
    }
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
     
        vector<vector<int>> ret;
        if (root == nullptr) 
            return ret;

        deque<TreeNode*> deq;
        deq.push_back(root);
        deq.push_back(nullptr);

        int index = 0;
        BFS(deq, index);

        
        toVector(deq,ret);
        return ret;
    }
};

BFS遍历时输出

思路:
既然使用双端队列,那就可以直接在队首或者队尾进行增删。
正向打印时,遍历deque中从front开始的所有节点,将其左右子树按序放入队尾push_back;
当正向打印到达deque的第一个nullptr时,保存这之前遍历的元素,改变当前节点至队尾元素,改变遍历方向。
当反向打印时,遍历deque中end()–的元素,将其左右子树反序放入deque的首部push_front;
当反向打印到达deque的第一个nullptr时,保存这之前遍历的元素,pop当前nullptr,使当前节点成为deque的队首元素。

执行用时:4 ms
内存消耗:11.3 MB

/**
 * 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:
    void BfsPro(deque<TreeNode*>& deq,bool bForword,vector<vector<int>>& ret)
    {
     
        vector<int> layer;
        auto cur = deq.front();
        while (deq.size())
        {
     
            if (bForword && cur == nullptr)
            {
     
                ret.push_back(layer);
                layer.clear();

                auto tmp = deq.end();
                tmp--;
                cur = *tmp;
                if (deq.size() == 1 && cur == nullptr)
                    break;

                
                bForword = !bForword;
            }
            else if (!bForword && cur == nullptr)
            {
     
                ret.push_back(layer);
                layer.clear();

                cur = deq.front();
                if (deq.size() == 1 && cur == nullptr)
                    break;

                bForword = !bForword;
            }
            else if (bForword && cur != nullptr)
            {
     
                layer.push_back(cur->val);
                if (cur->left) deq.push_back(cur->left);
                if (cur->right) deq.push_back(cur->right);
                deq.pop_front();
                cur = deq.front();
            }
            else if (!bForword && cur != nullptr)
            {
     
                layer.push_back(cur->val);
                if (cur->right) deq.push_front(cur->right);
                if (cur->left) deq.push_front(cur->left);
                
                deq.pop_back();
                auto tmp = deq.end();
                tmp--;
                cur = *(tmp);
            }
        }
    }
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
     
        vector<vector<int>> ret;
        if(root== nullptr)
            return ret;

        deque<TreeNode*> deq;
        deq.push_back(root);
        deq.push_back(nullptr);
        bool bForword = true;

        BfsPro(deq, bForword,ret);
        return ret;
    }
};

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:
   void Dfs(TreeNode* root, deque<deque<int>>& deq,int layer)
    {
     

        if (root == nullptr)
            return;

        if (layer < deq.size())
        {
     
            deq[layer].push_back(root->val);
        }
        else
        {
     
            deque<int> tmp;
            tmp.push_back(root->val);
            deq.push_back(tmp);
        }

        Dfs(root->left,deq, layer+1);
        Dfs(root->right, deq,  layer+1);

    }
    void dePrint(deque<deque<int>>& deq,vector<vector<int>>& ret)
    {
     
        vector<int> layer;
        for (int i = 0; i < deq.size(); ++i)
        {
     
            if (i % 2 == 0)
            {
     
                while (deq[i].size())
                {
     
                    layer.push_back(deq[i][0]);
                    deq[i].pop_front();
                }
            }
            else
            {
     
                while (deq[i].size())
                {
     
                    auto tmp = deq[i].end();
                    tmp--;
                    layer.push_back(*(tmp));
                    deq[i].pop_back();
                }
            }
            ret.push_back(layer);
            layer.clear();
        }
    }
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
     
        vector<vector<int>> ret;
        if(root== nullptr)
            return ret;

        deque<deque<int>> deq;
        Dfs( root,  deq, 0);
        
        dePrint( deq,ret);
        return ret;
    }
};

由于深度优先遍历时,无法输出结果,所以相比较而言,还是广度优先遍历的方法更优。

你可能感兴趣的:(C++,题库总结)