• 剑指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

  • 相关阅读:
    在windows系统下,配置vue项目一键启动文件
    CSS中设置元素的圆角矩形
    CSS中使用文本阴影与元素阴影
    如何使用CSS3中的结构伪类选择器和伪元素选择器
    CSS中的z-index属性如何使用
    深入学习CSS中如何使用定位
    css中如何使用border属性与display属性
    深入了解CSS中盒子模型
    CSS中如果实现元素浮动和清除浮动,看这篇文章就足够了
    CSS标准文档流
  • 原文地址:https://www.cnblogs.com/codeapes666/p/12290483.html
Copyright © 2020-2023  润新知