剑指offer 从上往下打印二叉树 | 把二叉树打印成多行 | 按之字形顺序打印二叉树

博客围绕剑指offer中三种二叉树打印方式展开。包括从上往下打印,借助队列实现按层打印;把二叉树打印成多行,用两层while循环和临时队列分层处理;按之字形顺序打印,用布尔值判断方向,借助栈实现反置打印,并给出分析思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从上往下打印二叉树

在这里插入图片描述

分析

题目很简短,需要我们自上而下,自左至右打印数据,这个“打印”我们可以理解为在列表中按照这个顺序添加参数。原本想到的是递归的方法,但是它不能做到这种按层的打印,必定会沿着子树不断递归。按层打印的效果的实现可以通过队列,先入队当前节点的左右节点,然后把当前节点的值打印,再出队左子节点,对左子节点的子节点进行入队,然后再出队右子节点,它的子节点入队。这样这一层已经按照顺序打印,下一层也已经按照顺序排队等待出队了,这样就实现了按层打印。
特殊情况处理

      if (root == null) {
          return list;
      }

代码

public class Solution {
        public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
              ArrayList<Integer> list  = new ArrayList<>();
              if (root == null) {
                  return list;
              }

              Queue<TreeNode> q = new LinkedList<TreeNode>();
              q.add(root);

              while (q.isEmpty() == false) {
                  TreeNode node = q.poll();
                  if (node.left != null) {
                      q.add(node.left);
                  }
                  if (node.right != null) {
                      q.add(node.right);
                  }
                  list.add(node.val);
              }
              return list;

        }
}

把二叉树打印成多行

在这里插入图片描述

分析

直接点出这题和上一题的区别,上一题只要按照从上到下,从左到右的顺序打印就可以了,而这题需要实现“分层”,嵌套ArrayList。
解决思路是分清层与层之间的区别,逐层处理数据,判断采用while非空判断。
队列:队列可以实现从上到下,从左到右的遍历顺序,这里不赘述。
如何分层?代码中用到了两层while(!que.isEmpty()),第一层是用来判断下一层有没有节点的,第二层是用来判断当前遍历层是否还有节点剩余。采用temp临时队列来保存下一层的节点,当前层“取”完后就把其中的节点移到que,开始下一层的读取。

代码

public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> listAll = new ArrayList();
        Queue<TreeNode> que = new LinkedList<TreeNode>();
        if(pRoot == null) {
            return listAll;
        }
        que.offer(pRoot);
        while(!que.isEmpty()){
            ArrayList<TreeNode> temp = new ArrayList();
            ArrayList<Integer> list = new ArrayList();
            while(!que.isEmpty()){
                TreeNode node = que.poll();
                list.add(node.val);
                if(node.left != null) {
                    temp.add(node.left);
                }
                if(node.right != null) {
                    temp.add(node.right);
                }
            }
            listAll.add(list);
            for(int i = 0; i < temp.size(); i++) {
                que.offer(temp.get(i));
            }
        }
        return listAll;
    }
    

}    

按之字形顺序打印二叉树

在这里插入图片描述

分析

和上一题的区别是它在打印的时候多了一个方向性,那么需要解决两个问题:一个问题是怎么实现来回的方向判断,另一个问题是怎么实现反置打印。
方向判断:
采用一个boolean值来实现方向的判断,每次判断后都取反。
反置打印:
借助栈,把数据存入和取出,这时就可以实现反转了。

代码

public class Solution {
    boolean flag = true;
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> listAll = new ArrayList();
        Queue<TreeNode> que = new LinkedList<TreeNode>();
        if(pRoot == null) {
            return listAll;
        }
        que.offer(pRoot);
        while(!que.isEmpty()){
            ArrayList<TreeNode> temp = new ArrayList();
            ArrayList<Integer> list = new ArrayList();
            while(!que.isEmpty()){
                TreeNode node = que.poll();
                list.add(node.val);
                if(node.left != null) {
                    temp.add(node.left);
                }
                if(node.right != null) {
                    temp.add(node.right);
                }
            }
            if(flag == false) {
                Stack<Integer> stack = new Stack();
                for(Integer val : list) {
                    stack.push(val);
                }
                ArrayList<Integer> nums = new ArrayList();
                while(stack.isEmpty() == false) {
                    nums.add(stack.pop());
                }
                list = nums;
                flag = true;
            }else {
                flag = false;
            }
            listAll.add(list);
          
            for(int i = 0; i < temp.size(); i++) {
                que.offer(temp.get(i));
            }


        }
        return listAll;
    }

}
内容概要:本文档详细介绍了基于MATLAB实现的多头长短期记忆网络(MH-LSTM)结合Transformer编码器进行多变量时间序列预测的项目实例。项目旨在通过融合MH-LSTM对时序动态的细致学习Transformer对全局依赖的捕捉,显著提升多变量时间序列预测的精度稳定性。文档涵盖了从项目背景、目标意义、挑战与解决方案、模型架构及代码示例,到具体的应用领域、部署与应用、未来改进方向等方面的全面内容。项目不仅展示了技术实现细节,还提供了从数据预处理、模型构建与训练到性能评估的全流程指导。 适合人群:具备一定编程基础,特别是熟悉MATLAB深度学习基础知识的研发人员、数据科学家以及从事时间序列预测研究的专业人士。 使用场景及目标:①深入理解MH-LSTM与Transformer结合的多变量时间序列预测模型原理;②掌握MATLAB环境下复杂神经网络的搭建、训练及优化技巧;③应用于金融风险管理、智能电网负荷预测、气象预报、交通流量预测、工业设备健康监测、医疗数据分析、供应链需求预测等多个实际场景,以提高预测精度决策质量。 阅读建议:此资源不仅适用于希望深入了解多变量时间序列预测技术的读者,也适合希望通过MATLAB实现复杂深度学习模型的开发者。建议读者在学习过程中结合提供的代码示例进行实践操作,并关注模型训练中的关键步骤超参数调优策略,以便更好地应用于实际项目中。
### C语言实现从上到下打印二叉树 要实现从上到下的顺序打印二叉树节点,可以采用层次遍历的方法。这种方法通常借助队列来完,因为队列具有先进先出的特点,能够按照加入的顺序依次处理每个节点。 以下是完整的代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树节点结构体 typedef struct TreeNode { int data; struct TreeNode* lchild; struct TreeNode* rchild; } TreeNode; // 创建新节点 TreeNode* create_node(int value) { TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->data = value; node->lchild = NULL; node->rchild = NULL; return node; } // 层次遍历并打印二叉树 void level_order_traversal(TreeNode* root) { if (!root) return; // 如果根为空,则直接返回 // 初始化队列 TreeNode** queue = (TreeNode**)malloc(100 * sizeof(TreeNode*)); // 假设最多有100个节点 int front = 0, rear = 0; // 将根节点入队 queue[rear++] = root; while (front != rear) { // 当队列不为空时继续循环 TreeNode* current = queue[front++]; // 取出队首元素 printf("%d ", current->data); // 输出当前节点的数据 // 左子节点存在则将其入队 if (current->lchild) { queue[rear++] = current->lchild; } // 右子节点存在则将其入队 if (current->rchild) { queue[rear++] = current->rchild; } } free(queue); // 释放队列内存 } int main() { // 构建一个简单的二叉树作为测试数据 TreeNode* root = create_node(1); root->lchild = create_node(2); root->rchild = create_node(3); root->lchild->lchild = create_node(4); root->lchild->rchild = create_node(5); // 调用层次遍历函数 printf("Level order traversal of binary tree is:\n"); level_order_traversal(root); return 0; } ``` 上述代码实现了通过队列进行层次遍历的功能[^1]。具体来说,程序会逐层访问二叉树中的每一个节点,并按从左至右的顺序输出其值。如果某个节点还有子节点,则这些子节点会被添加到队列中等待后续处理。 #### 关键点说明: - **队列的作用**:用于存储待访问的节点,确保每次总是优先访问较早进入队列的节点。 - **边界条件**:当输入的二叉树为空时,应立即退出而不执行任何操作。 - **动态分配与释放资源**:为了支持不同大小的二叉树,在实际应用中可能需要更灵活地管理队列的空间大小以及及时释放不再使用的内存区域。 此方法的时间复杂度为O(n),其中n表示二叉树中总的节点数;空间复杂度同样也是O(n),因为在最坏情况下整个二叉树的所有节点都可能会被暂时存放在队列里[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值