zoukankan      html  css  js  c++  java
  • 剑指Offer-从上到下打印二叉树

    题目 1

    不分行从上到下打印二叉树。从上到下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。

    示例

    输入:

         8
        / 
       6   10
      /   / 
     5   7 9  11
    
    

    输出:

    8 6 10 5 7 9 11
    

    解题思路

    这个其实就是层序遍历。每次打印一个结点的时候,若该结点有子结点,则让该结点的子结点放到一个队列的末尾。接下来到队列的首部取出最早进入队列的结点,不断重复前面的打印,直至队列中所有的结点都被打印出来。

    代码实现

    #include <iostream>
    #include <vector>
    #include <queue>
    
    struct BiTNode {
        int val;
        BiTNode* left;
        BiTNode* right;
        BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
    };
    
    class Solution {
    public:
        std::vector<int> PrintFromTopToBottom(BiTNode* root) {
            // 存储打印结果
            std::vector<int> result;
            
            // 边界条件
            if (root == nullptr) {
                return result;
            }
            
            // 辅助容器:队列
            std::queue<BiTNode*> qeueTreeNode;
            
            // 根结点入队
            qeueTreeNode.push(root);
            
            // 遍历队列
            while (!qeueTreeNode.empty()) {
                // 辅助指针:指向队头
                BiTNode* node = qeueTreeNode.front();
    
                // 打印结果存储到result中
                result.push_back(node->val);
                
                // 根结点的子结点入队
                if (node->left != nullptr) {
                    qeueTreeNode.push(node->left);
                }
                if (node->right != nullptr) {
                    qeueTreeNode.push(node->right);
                }
    
                // 根结点出队
                qeueTreeNode.pop();
            }
            
            return result;
        }
    };
    
    // 销毁二叉树
    void DestroyBiTree(BiTNode* root)
    {
        if (root == nullptr) {
            return;
        }
    
        DestroyBiTree(root->left);
        DestroyBiTree(root->right);
    
        // 从最左依次 delete 至根结点
        delete root;
        root = nullptr;        
    }
    
    int main(void)
    {
        Solution sol;
        std::vector<int> res;
        
        // 构造一个二叉树
        BiTNode* root = new BiTNode(8);
        root->left = new BiTNode(6);
        root->right = new BiTNode(10);
        root->left->left = new BiTNode(5);
        root->left->right = new BiTNode(7);
        root->right->left = new BiTNode(9);
        root->right->right = new BiTNode(11);
        
        res = sol.PrintFromTopToBottom(root);
        
        // 遍历vector,C++ 11 标准支持
        for (int i:res) {
             std::cout << i;
             
            if (i != res[res.size() - 1]) {
                std::cout << ' ';
            }
        }
        
        // 遍历vector,打印结果
        // for (unsigned int i = 0; i < res.size(); ++i) {
        //     std::cout << res[i];
        //     if (i != res.size() - 1) {
        //         std::cout << ' ';
        //     }
        // }
        std::cout << std::endl;
    
        DestroyBiTree(root);
        
        return 0;
    }
    

    题目 2

    分行从上到下打印二叉树。从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印到一行。

    示例

    输入:

         8
        / 
       6   10
      /   / 
     5   7 9  11
    
    

    输出:

    8
    6 10
    5 7 9 11
    

    解题思路

    为了把二叉树的每一行单独打印到一行里,我们需要两个变量:一个变量表示当前层中还未打印的结点数;另一个变量表示下一层结点的数目。

    代码实现

    #include <iostream>
    #include <queue>
    
    struct BiTNode {
        int val;
        BiTNode* left;
        BiTNode* right;
        BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
    };
    
    class Solution {
    public:
        int PrintTreesInLines(BiTNode* root) {
     
            // 边界条件
            if (root == nullptr) {
                return -1;
            }
    
            std::queue<BiTNode*> qeueTreeNode;
    
            qeueTreeNode.push(root);
    
            // 下一层的结点数
            int nextLevel = 0;
    
            // 当前层中未打印的结点数
            int toBePrinted = 1;
    
            while (!qeueTreeNode.empty()) {
                BiTNode* node = qeueTreeNode.front();
                
                // 打印结果
                std::cout << node->val;
    
                // 打印结果之间用空格隔开
                if (toBePrinted != 1) {
                    std::cout << ' ';
                }
    
                if (node->left != nullptr) {
                    qeueTreeNode.push(node->left);
                    ++nextLevel;
                }
                if (node->right != nullptr) {
                    qeueTreeNode.push(node->right);
                    ++nextLevel;
                }
    
                qeueTreeNode.pop();
                --toBePrinted;
                
                // 当前层的所有结点已打印完毕,可以继续打印下一层
                if (toBePrinted == 0) {
                    std::cout << std::endl;
                    toBePrinted = nextLevel;
                    nextLevel = 0;
                }
            }
            
            return 0;
        }
    };
    
    // 销毁二叉树
    void DestroyBiTree(BiTNode* root)
    {
        if (root == nullptr) {
            return;
        }
    
        DestroyBiTree(root->left);
        DestroyBiTree(root->right);
    
        // 从最左依次 delete 至根结点
        delete root;
        root = nullptr;        
    }
    
    int main(void)
    {
        Solution sol;
        
        // 构造一个二叉树
        BiTNode* root = new BiTNode(8);
        root->left = new BiTNode(6);
        root->right = new BiTNode(10);
        root->left->left = new BiTNode(5);
        root->left->right = new BiTNode(7);
        root->right->left = new BiTNode(9);
        root->right->right = new BiTNode(11);
        
        sol.PrintTreesInLines(root);
    
        std::cout << std::endl;
        
        DestroyBiTree(root);
        
        return 0;
    }
    

    题目 3

    之字形打印二叉树。请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二行按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其它行以此类推。

    示例

    输入:

              1
           /      
        2           3
       /         /   
      4    5     6     7
    /    /     /   / 
    8  9  10 11 12 13 14 15
    

    输出:

    1
    3 2
    4 5 6 7
    15 14 13 12 11 10 9 8
    

    解题思路

    按之字形顺序打印二叉树需要两个栈。在打印某一层的结点时,把下一层的子结点保存到相应的栈里。若当前打印的是奇数层(第 1 、3 层等),则先保存左子结点再保存右子结点到第一个栈里;若打印的是偶数层(第 2 、4层等),则先保存右子结点再保存左子结点到第二个栈里。

    代码实现

    #include <iostream>
    #include <stack>
    
    struct BiTNode {
        int val;
        BiTNode* left;
        BiTNode* right;
        BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
    };
    
    class Solution {
    public:
        int PrintTreesInZigzag(BiTNode* root) {
     
            // 边界条件
            if (root == nullptr) {
                return -1;
            }
    
            std::stack<BiTNode*> stackLevels[2];
    
            int current = 0;
            int next = 1;
    
            stackLevels[current].push(root);
    
            while (!stackLevels[0].empty() || !stackLevels[1].empty()) {
                BiTNode* node = stackLevels[current].top();
                stackLevels[current].pop();
    
                std::cout << node->val;
    
                if (!stackLevels[current].empty()) {
                    std::cout << ' ';
                }
    
                if (current == 0) {
                    if (node->left != nullptr) {
                        stackLevels[next].push(node->left);
                    }
                    if (node->right != nullptr) {
                        stackLevels[next].push(node->right);
                    }
                } else {
                    if (node->right != nullptr) {
                        stackLevels[next].push(node->right);
                    }
                    if (node->left != nullptr) {
                        stackLevels[next].push(node->left);
                    }
                }
    
                if (stackLevels[current].empty()) {
                    std::cout << std::endl;
                    current = 1 - current;
                    next = 1 - next;
                }
            }
            
            return 0;
        }
    };
    
    // 销毁二叉树
    void DestroyBiTree(BiTNode* root)
    {
        if (root == nullptr) {
            return;
        }
    
        DestroyBiTree(root->left);
        DestroyBiTree(root->right);
    
        // 从最左依次 delete 至根结点
        delete root;
        root = nullptr;        
    }
    
    int main(void)
    {
        Solution sol;
        
        // 构造一个二叉树
        BiTNode* root = new BiTNode(1);
        root->left = new BiTNode(2);
        root->right = new BiTNode(3);
        root->left->left = new BiTNode(4);
        root->left->right = new BiTNode(5);
        root->right->left = new BiTNode(6);
        root->right->right = new BiTNode(7);
        root->left->left->left = new BiTNode(8);
        root->left->left->right = new BiTNode(9);
        root->left->right->left = new BiTNode(10);
        root->left->right->right = new BiTNode(11);
        root->right->left->left = new BiTNode(12);
        root->right->left->right = new BiTNode(13);
        root->right->right->left = new BiTNode(14);
        root->right->right->right = new BiTNode(15);
        
        sol.PrintTreesInZigzag(root);
    
        std::cout << std::endl;
        
        DestroyBiTree(root);
        
        return 0;
    }
    

    个人主页:

    www.codeapes.cn

  • 相关阅读:
    入门菜鸟
    FZU 1202
    XMU 1246
    Codeforces 294E Shaass the Great 树形dp
    Codeforces 773D Perishable Roads 最短路 (看题解)
    Codeforces 814E An unavoidable detour for home dp
    Codeforces 567E President and Roads 最短路 + tarjan求桥
    Codeforces 567F Mausoleum dp
    Codeforces 908G New Year and Original Order 数位dp
    Codeforces 813D Two Melodies dp
  • 原文地址:https://www.cnblogs.com/codeapes666/p/12290483.html
Copyright © 2011-2022 走看看