从上往下打印二叉树

题目描述

从上往下打印出二叉树的每个节点,同层节点从左至右打印。


思路分析

        这道题实际上考察的就是二叉树的层次遍历。以下图(来自《剑指offer》)为例进行分析:


        因为按层打印的顺序决定应该先打印根结点,所以我们从树的根结点开始分析。为了接下来能够打印值为9的结点的两个子结点,我们应该在遍历到该结点的时候把值为6和10的两个结点保存到一个容器里,现在容器内就有两个结点了。按照从左到右打印的要求,我们先取出值为6的结点。打印出6之后把它的值分别为5和7的两个子结点放入数据容器,此时容器中有3个结点,值分别是10、5、7。接下来从容器中取出10的结点,注意到值为10的结点比值为5、7的结点先放入容器,此时又比这两个结点先取出,这就是“先进先出”典型的队列。由于值为5、7、9、11的结点都没有子结点,因此只要依次打印即可。

        通过上面例子分析,我们可找到从上到下打印二叉树的规律:每一次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到队列的末尾。接下来到队列的头部取出最早进入队列的结点,重复前面的操作,直至队列为空。


Java实现

import java.util.ArrayList;
import java.util.LinkedList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {      
        ArrayList<Integer> list=new ArrayList<Integer>();
        //判断特殊值
        if(root==null)
            return list;
               
        //队列保存二叉树层次遍历的结点
        LinkedList<TreeNode> queue=new LinkedList<TreeNode>();
        queue.addLast(root);
        while(queue.size()>0){
            TreeNode p=queue.removeFirst();
            list.add(p.val);
            
            if(p.left!=null)
                queue.addLast(p.left);
            if(p.right!=null)
                queue.addLast(p.right);
        }
        return list;
    }
}
启发:
        不管是广度优先遍历一个有向图还是一棵树,都要用到队列。第一步我们把起始结点(对树而言是根结点)放入队列中。接下来每一次从队列的头部取出一个结点,遍历这个结点之后把它能到达的结点(对树而言是子结点)都一次放入队列中,重复这个遍历过程,直到队列为空为止。
### 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]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值